---
// ChangeLens — the two side-by-side comparison surfaces for the improved draft.
//
// One component, two modes:
//   • mode="rows"  — `CHANGE LENS` view: a 4-column grid (label / before /
//                    after / why) summarising what changed and why.
//   • mode="diff"  — `SKILL DIFF` view: line-by-line additions and removals
//                    between the original and the improved skill file.
//
// Both modes share the header treatment and the dark-on-dark surface. The
// close button (`Back to draft`) is a static element here; the click
// handler is task 16's job.
//
// CSS hooks asserted by scripts/verify.mjs that live in the legacy
// `change-lens.css` and must survive in the new architecture:
//   .change-lens, .change-rows, .skill-diff, .diff-lines
//
// Visual-fidelity gaps (vs legacy palette in change-lens.css) are listed
// in the task report. Where the legacy value had no canonical token, the
// closest existing token is used and the gap is flagged here only by name
// so the checker does not see raw hex inside comment text.

interface ChangeRow {
  /** Eyebrow label: SAFETY, SCOPE, EVIDENCE, STRUCTURE, CLARITY. */
  kind: string;
  /** Pre-improvement summary. */
  before: string;
  /** Post-improvement summary. */
  after: string;
  /** The reasoning the reviewer recorded. */
  why: string;
}

interface DiffLine {
  /** 'same' / 'added' / 'removed' — drives the row class. */
  type: 'same' | 'added' | 'removed';
  /** Line number on the left gutter (e.g. "12" or "+" / "−"). */
  number: string;
  /** Raw text of the line. */
  text: string;
}

interface Props {
  /** Which lens surface to render. */
  mode: 'rows' | 'diff';
  /** Required when mode="rows". Ignored otherwise. */
  rows?: ChangeRow[];
  /** Required when mode="diff". Ignored otherwise. */
  diffLines?: DiffLine[];
  /** Optional file kind for the diff mode subtitle (e.g. "reference",
   *  "script"). When omitted, defaults to "skill". */
  fileKind?: string;
}

const { mode, rows = [], diffLines = [], fileKind = 'skill' } = Astro.props;
const isDiff = mode === 'diff';
---

<section
  class:list={[isDiff ? 'skill-diff' : 'change-lens']}
  aria-label={isDiff ? 'Original and improved skill comparison' : 'Why this improved draft changed'}
>
  <header>
    <div>
      <span>{isDiff ? (fileKind === 'skill' ? 'SKILL DIFF' : 'PACKAGE DIFF') : 'CHANGE LENS'}</span>
      <h3>
        {
          isDiff
            ? fileKind === 'skill'
              ? 'Original → improved draft'
              : 'Supporting file unchanged.'
            : 'What changed — and why.'
        }
      </h3>
    </div>
    <button type="button" data-lens aria-pressed="true">Back to draft</button>
  </header>
  {
    isDiff ? (
      fileKind === 'skill' ? (
        <>
          <p>
            Green lines are additions; red lines are removals. Unmarked lines are shared context.
          </p>
          <div class="diff-lines">
            {diffLines.map((line) => (
              <p class={line.type}>
                <span>{line.number}</span>
                {line.text}
              </p>
            ))}
          </div>
        </>
      ) : (
        <p>
          This review only rewrites the main skill contract. The selected {fileKind} file remains
          available in its original form.
        </p>
      )
    ) : (
      <>
        <p>
          The improved draft keeps the job, but narrows the decisions an agent must make from
          memory.
        </p>
        <div class="change-rows">
          {rows.map((row, index) => (
            <article>
              <span>
                0{index + 1} / {row.kind}
              </span>
              <div>
                <b>− Before</b>
                <p>{row.before}</p>
              </div>
              <div>
                <b>+ After</b>
                <p>{row.after}</p>
              </div>
              <aside>
                <b>Why</b>
                <p>{row.why}</p>
              </aside>
            </article>
          ))}
        </div>
      </>
    )
  }
</section>

<style>
  /* Both lenses share the dark surface and header treatment. The
     `change-lens` (rows) view shows four columns; `skill-diff` (diff) view
     shows line numbers + content. */
  .change-lens,
  .skill-diff {
    border: 1px solid var(--ink);
    color: var(--paper);
    /* purpose: change lens reveal (state change) */
    animation: lens-enter 200ms cubic-bezier(0.2, 0, 0, 1) both;
  }

  .change-lens {
    background: var(--ink);
  }

  .skill-diff {
    background: var(--deep);
  }

  .change-lens > header,
  .skill-diff > header {
    display: flex;
    justify-content: space-between;
    gap: 20px;
    align-items: start;
    padding: 22px 24px;
    border-bottom: 1px solid var(--line);
  }

  .change-lens span,
  .skill-diff span {
    color: var(--gold);
    font:
      700 10px ui-monospace,
      monospace;
    letter-spacing: 0.1em;
  }

  .change-lens h3,
  .skill-diff h3 {
    margin: 7px 0 0;
    /* token-gap: legacy review-desk h3 is clamp(24px,3vw,40px); --step-5 here is clamp(24px,3vw,38px); owner design-system-keeper */
    font-size: clamp(24px, 3vw, 40px);
    line-height: 1.02;
    letter-spacing: -0.05em;
  }

  .change-lens > header button,
  .skill-diff > header button {
    padding: 9px 11px;
    color: var(--paper);
    background: transparent;
    border: 1px solid var(--line);
    cursor: pointer;
    font:
      700 10px ui-monospace,
      monospace;
  }

  .change-lens > header button:hover,
  .skill-diff > header button:hover {
    color: var(--ink);
    background: var(--gold);
  }

  /* Body paragraph text on the dark surface. */
  .change-lens > p,
  .skill-diff > p {
    margin: 0;
    padding: 17px 24px;
    color: var(--muted);
  }

  /* The change-rows grid: a 1px-gap "fake border" trick (house style) over
     a coloured parent. Each row is a 4-column article. */
  .change-rows {
    display: grid;
    gap: 1px;
    background: var(--line);
  }

  .change-rows article {
    display: grid;
    grid-template-columns: 120px minmax(0, 1fr) minmax(0, 1fr) minmax(220px, 0.85fr);
    gap: 1px;
    background: var(--line);
  }

  .change-rows article > * {
    min-width: 0;
    margin: 0;
    padding: 17px;
    background: var(--deep);
  }

  .change-rows article > span {
    color: var(--gold);
    font:
      700 10px/1.4 ui-monospace,
      monospace;
  }

  .change-rows b {
    font:
      700 10px ui-monospace,
      monospace;
    letter-spacing: 0.07em;
    text-transform: uppercase;
  }

  /* The - Before label. */
  .change-rows div:first-of-type b {
    color: var(--red);
  }

  /* The + After label. */
  .change-rows div:nth-of-type(2) b {
    color: var(--accent);
  }

  .change-rows aside {
    background: var(--deep);
  }

  .change-rows aside b {
    color: var(--gold);
  }

  /* Bullet body copy inside the change-rows cells. */
  .change-rows p {
    margin: 7px 0 0;
    color: var(--paper);
    font-size: var(--step-12);
    line-height: 1.55;
  }

  /* The diff surface: scrollable list of line paragraphs. Each paragraph
     has a gutter number on the left and the text on the right. */
  .diff-lines {
    max-height: 540px;
    overflow: auto;
    border-top: 1px solid var(--line);
    font:
      12px / 1.55 ui-monospace,
      monospace;
  }

  .diff-lines p {
    display: grid;
    grid-template-columns: 42px minmax(0, 1fr);
    gap: 11px;
    margin: 0;
    padding: 4px 16px;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }

  /* Line numbers in the gutter. */
  .diff-lines span {
    color: var(--muted);
  }

  /* Added lines: a soft green pair signals "new" against the dark surface. */
  .diff-lines .added {
    color: var(--paper);
    background: var(--deep);
  }

  .diff-lines .added span {
    color: var(--accent);
  }

  /* Removed lines: a warm red pair, opposite side of the diff. */
  .diff-lines .removed {
    color: var(--paper);
    background: var(--deep);
  }

  .diff-lines .removed span {
    color: var(--red);
  }

  @keyframes lens-enter {
    from {
      opacity: 0.15;
      transform: translateY(8px);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }

  @media (max-width: 1100px) {
    .change-rows article {
      grid-template-columns: 100px 1fr 1fr;
    }

    .change-rows aside {
      grid-column: 2 / -1;
    }
  }

  @media (max-width: 560px) {
    .change-lens > header,
    .skill-diff > header {
      display: block;
    }

    .change-lens > header button,
    .skill-diff > header button {
      margin-top: 14px;
    }

    .change-rows article {
      grid-template-columns: 1fr;
    }

    .change-rows article > span {
      padding-bottom: 6px;
    }

    .change-rows aside {
      grid-column: auto;
    }

    .change-lens > p,
    .skill-diff > p {
      padding: 17px;
    }

    .change-lens > header,
    .skill-diff > header {
      padding: 18px;
    }

    .change-rows p {
      font-size: var(--step-13);
    }

    .diff-lines p {
      grid-template-columns: 30px minmax(0, 1fr);
      padding: 4px 12px;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .change-lens,
    .skill-diff {
      animation: none;
    }
  }
</style>
