/* ChangesPage.jsx — review & submit the pending change set */
const { useState: useStateCH } = React;

const IMPACT = {
  major: { label:'major', labelZh:'重大', color:'var(--danger)',  hint:'Breaking', hintZh:'破坏性' },
  minor: { label:'minor', labelZh:'次要', color:'var(--warning)', hint:'Additive', hintZh:'新增兼容' },
  patch: { label:'patch', labelZh:'修订', color:'var(--success)', hint:'Fix',      hintZh:'修复' },
};

function ActionTag({ action }) {
  const m = ACTION_META[action] || ACTION_META.modified;
  const zh = { added:'新增', modified:'修改', renamed:'重命名', removed:'移除', deprecated:'废弃' }[action];
  return <span className="inline-flex items-center justify-center w-[78px] h-[20px] rounded-[4px] text-[11px] font-medium"
    style={{ background:'color-mix(in srgb, '+m.color+' 13%, transparent)', color:m.color }}>{tr(m.label, zh)}</span>;
}

function ImpactSelect({ value, onChange }) {
  const [open, setOpen] = useStateCH(false);
  const [pos, setPos] = useStateCH(null);
  const btnRef = React.useRef(null);
  const m = IMPACT[value];
  // fixed-position the menu off the button rect so it's never clipped by the scrolling/overflow container
  const toggle = () => {
    if (!open && btnRef.current) { const r = btnRef.current.getBoundingClientRect(); setPos({ top: r.bottom + 4, left: Math.max(8, r.right - 160) }); }
    setOpen(o => !o);
  };
  return (
    <div className="relative">
      <button ref={btnRef} onClick={toggle}
        className="h-7 flex items-center gap-1.5 pl-2 pr-1.5 bg-panel border border-line rounded-[7px] text-[12px] hover:bg-hover transition focus-ring">
        <span className="w-1.5 h-1.5 rounded-full" style={{ background:m.color }} />
        <span className="text-ink whitespace-nowrap">{tr(m.label, m.labelZh)}</span>
        <Icon name="chevronD" size={12} className="text-ink3" />
      </button>
      {open && pos && (
        <>
          <div className="fixed inset-0 z-[60]" onClick={()=>setOpen(false)} />
          <div className="fixed z-[61] w-40 bg-panel border border-line rounded-[8px] py-1 shadow-[0_8px_24px_rgba(0,0,0,0.14)]" style={{ top:pos.top, left:pos.left, animation:'fadeIn 110ms ease' }}>
            {Object.entries(IMPACT).map(([k,im])=>(
              <button key={k} onClick={()=>{onChange(k);setOpen(false);}} className={cx('w-full flex items-center gap-2 px-2.5 h-8 text-left hover:bg-hover transition', k===value&&'bg-accentWeak')}>
                <span className="w-1.5 h-1.5 rounded-full" style={{ background:im.color }} />
                <span className="text-[12px] text-ink">{tr(im.label, im.labelZh)}</span>
                <span className="ml-auto text-[11px] text-ink3">{tr(im.hint, im.hintZh)}</span>
              </button>
            ))}
          </div>
        </>
      )}
    </div>
  );
}

/* diff visual per type */
function Diff({ c }) {
  const arrow = <Icon name="arrowR" size={13} className="text-ink3" />;
  if (c.diffType==='colorRef') return (
    <div className="flex items-center gap-2 flex-wrap text-[12px]">
      <span className="inline-flex items-center gap-1.5"><Swatch color={c.fromVal} size={16}/><span className="font-mono text-ink2">{'{'+c.from+'}'}</span></span>
      {arrow}
      <span className="inline-flex items-center gap-1.5"><Swatch color={c.toVal} size={16}/><span className="font-mono text-ink">{'{'+c.to+'}'}</span></span>
    </div>
  );
  if (c.diffType==='color') return (
    <div className="flex items-center gap-2 flex-wrap text-[12px] font-mono">
      {c.from && <span className="inline-flex items-center gap-1.5"><Swatch color={c.from} size={16}/><span className="text-ink2">{c.from}</span></span>}
      {c.from && arrow}
      <span className="inline-flex items-center gap-1.5"><Swatch color={c.to} size={16}/><span className="text-ink">{c.to}</span></span>
    </div>
  );
  if (c.diffType==='refChange') return (
    <div className="flex items-center gap-2 text-[12.5px] font-mono">
      {c.from && <span className="text-ink2">{c.from}</span>}{c.from && arrow}<span className="text-ink">{c.to}</span>
    </div>
  );
  if (c.diffType==='num') return (
    <div className="flex items-center gap-2 text-[12.5px] font-mono">
      <span className="text-ink2 line-through">{c.from}</span>{arrow}<span className="text-ink">{c.to}</span>
    </div>
  );
  if (c.diffType==='rename') return (
    <div className="flex items-center gap-2 text-[12.5px] font-mono">
      <span className="text-ink2 line-through">{c.from}</span>{arrow}<span className="text-ink">{c.to}</span>
    </div>
  );
  if (c.diffType==='new') return <span className="font-mono text-[12.5px] text-success inline-flex items-center gap-1.5"><Icon name="plus" size={12}/>{c.to}</span>;
  if (c.diffType==='copyEdit' || c.diffType==='copyNew') return (
    <div className="flex items-center gap-2 text-[12.5px] min-w-0">
      {c.from ? <><span className="text-ink2 line-through truncate max-w-[180px]">“{c.from}”</span>{arrow}</> : <Icon name="plus" size={12} className="text-success"/>}
      <span className="text-ink truncate max-w-[220px]">“{c.to}”</span>
    </div>
  );
  if (c.diffType==='contentDoc') return <span className="text-[12.5px] text-ink2 inline-flex items-center gap-1.5"><Icon name="edit" size={12} className="text-ink3"/>{c.summary}</span>;
  if (c.diffType==='deprecate') return <span className="font-mono text-[12.5px] text-ink3 line-through">{c.from}</span>;
  if (c.diffType==='newIcon') return (
    <div className="flex items-center gap-2"><span className="w-8 h-8 rounded-[8px] bg-sunken border border-line flex items-center justify-center text-ink"><Icon name={c.icon} size={18}/></span><span className="text-[12px] text-success inline-flex items-center gap-1"><Icon name="plus" size={11}/>New asset</span></div>
  );
  if (c.diffType==='imageSwap') return (
    <div className="flex items-center gap-2">
      <span className="w-12 h-8 rounded-[4px] checker border border-line opacity-60" />{arrow}<span className="w-12 h-8 rounded-[4px] bg-sunken border border-line flex items-center justify-center"><Icon name="image" size={13} className="text-ink3"/></span>
    </div>
  );
  if (c.diffType==='deprecateIcon') return (
    <div className="flex items-center gap-2 opacity-60"><span className="w-8 h-8 rounded-[8px] bg-sunken border border-line flex items-center justify-center text-ink2"><Icon name={c.icon} size={18}/></span><span className="text-[12px] text-ink3 line-through">Deprecated</span></div>
  );
  if (c.diffType==='compDocs') return (
    <span className="text-[12.5px] text-ink2 inline-flex items-center gap-1.5"><Icon name="edit" size={12} className="text-ink3"/>{c.summary}</span>
  );
  if (c.diffType==='compStatus') {
    const sb = (s)=>{ const m=(COMP_STATUS[s]||COMP_STATUS.stable); return <span className="inline-flex items-center gap-1 h-[18px] px-1.5 rounded-full text-[10.5px] font-medium" style={{ background:'color-mix(in srgb, '+m.color+' 13%, transparent)', color:m.color }}><span className="w-1 h-1 rounded-full" style={{ background:m.color }}/>{m.label}</span>; };
    return <div className="flex items-center gap-2 flex-wrap">{sb(c.from)}{arrow}{sb(c.to)}{c.note && <span className="text-[11.5px] text-ink3 truncate max-w-[240px]" title={c.note}>· {c.note}</span>}</div>;
  }
  if (c.diffType==='compCaution') return (
    <span className="text-[12.5px] inline-flex items-center gap-1.5 flex-wrap" style={{ color: c.on ? 'var(--warning)' : 'var(--text-2)' }}>
      <Icon name="warningTri" size={13}/>{c.on ? tr('Flagged caution','标记为谨慎') : tr('Caution cleared','取消谨慎标记')}
      {c.on && c.note && <span className="text-ink3 truncate max-w-[240px]" title={c.note}>· {c.note}</span>}
    </span>
  );
  if (c.diffType==='themeNew') return (
    <div className="flex items-center gap-2 text-[12px]"><span className="w-5 h-5 rounded-[4px] border border-line2" style={{ background:c.swatch }}/><span className="text-success inline-flex items-center gap-1"><Icon name="plus" size={11}/>{tr('New brand theme','新建品牌主题')}</span></div>
  );
  if (c.diffType==='themeEdit') return (
    <div className="flex items-center gap-2 text-[12px]"><span className="w-5 h-5 rounded-[4px] border border-line2" style={{ background:c.swatch }}/><span className="text-ink2">{tr('Accent / meta updated','强调色/信息已更新')}</span></div>
  );
  if (c.diffType==='themeRemove') return <span className="text-[12.5px] text-ink3 line-through">{tr('Removed theme','已删除主题')}</span>;
  if (c.diffType==='theme-divergence') { const sm = { intentional:['Intentional','合理','success'], review:['Needs review','待复核','warning'], fix:['To fix','需修复','danger'] }[c.status] || ['Logged','已记录','neutral'];
    return (
      <div className="flex items-center gap-2 flex-wrap text-[12px]">
        {typeof Pill!=='undefined' && <Pill color={(typeof deltaBand!=='undefined'?deltaBand(c.maxDE).color:'var(--accent)')}>ΔE {c.maxDE}</Pill>}
        <span className="text-ink2 truncate max-w-[260px]">“{c.reason}”</span>
        {typeof Pill!=='undefined' && <Pill tone={sm[2]}>{tr(sm[0], sm[1])}</Pill>}
      </div>
    );
  }
  return null;
}

function ChangeRow({ c, onImpact, onJump }) {
  const kindLabel = tr({ token:'Token', component:'Component', asset:'Asset', theme:'Theme', content:'Content', rationale:'Rationale' }[c.kind] || c.kind, { token:'Token', component:'组件', asset:'资源', theme:'主题', content:'文案', rationale:'差异说明' }[c.kind]);
  return (
    <div onClick={()=>onJump && onJump(c)} role="button" title={tr('Go to edit point','跳转到修改点')}
      className="group grid items-center gap-3 px-4 py-2.5 border-b border-[color:var(--border)] hover:bg-hover transition-colors cursor-pointer"
      style={{ gridTemplateColumns:'auto minmax(0,1.1fr) minmax(0,1.2fr) 150px 28px' }}>
      <ActionTag action={c.action} />
      <div className="min-w-0">
        <div className="flex items-center gap-2 min-w-0">
          <div className="font-mono text-[13px] text-ink truncate">{c.target}</div>
          {c.kind==='token' && c.scope && (
            c.scope==='all'
              ? <Pill tone="neutral">{tr('All themes','所有主题')}</Pill>
              : <Pill tone="accent" icon="link">{tr(c.scope+' only', c.scope+' 专属')}</Pill>
          )}
        </div>
        <div className="text-[11px] text-ink3 mt-0.5">{kindLabel}</div>
      </div>
      <div className="min-w-0"><Diff c={c} /></div>
      <div className="flex items-center gap-1.5" onClick={e=>e.stopPropagation()}>
        <span className="text-[11px] text-ink3">{tr('Impact','影响')}</span>
        <ImpactSelect value={c.impact} onChange={(v)=>onImpact(c.id,v)} />
      </div>
      <span className="flex items-center justify-center text-ink3 opacity-0 group-hover:opacity-100 transition"><Icon name="arrowR" size={15}/></span>
    </div>
  );
}

function ChangesPage({ changes, setChanges, onJump }) {
  const [msg, setMsg] = useStateCH('');
  const [submitting, setSubmitting] = useStateCH(false);
  const [pr, setPr] = useStateCH(null);
  const [view, setView] = useStateCH('pending'); // pending | history
  const [openPr, setOpenPr] = useStateCH(null);  // history entry shown in the side drawer

  const tokenChanges = changes.filter(c=>c.kind==='token');
  const themeChanges = changes.filter(c=>c.kind==='theme');
  const componentChanges = changes.filter(c=>c.kind==='component');
  const assetChanges = changes.filter(c=>c.kind==='asset');
  const contentChanges = changes.filter(c=>c.kind==='content');
  const rationaleChanges = changes.filter(c=>c.kind==='rationale');

  function setImpact(id, v){ setChanges(cs=>cs.map(c=>c.id===id?{...c,impact:v}:c)); }
  function submit(){
    setSubmitting(true);
    setTimeout(()=>{
      setSubmitting(false);
      setPr({ number: 482, url:'github.com/aperture/design-system/pull/482', status:'In review', when:'just now',
        rollup: rollupImpact(changes) });
    }, 1100);
  }

  if (pr) return <SubmittedView pr={pr} count={changes.length} msg={msg} branch={SESSION.branch} onBack={()=>{ setPr(null); }} />;

  return (
    <div className="h-full flex flex-col">
      <PageToolbar
        title={tr('Changes','变更')}
        subtitle={`${changes.length} ${tr('unpublished changes on this branch','项未发布变更')} · ${tr('targets','目标')} ${SESSION.cycle}.`}
        contextHint={<span className="inline-flex items-center gap-2 text-[12px] text-ink3"><Icon name="branch" size={14}/><span className="font-mono">{SESSION.branch}</span></span>}
      />
      <div className="shrink-0 border-b border-line px-6 py-3 bg-panel flex items-center gap-3">
        <Segmented value={view} onChange={setView} options={[
          { value:'pending', label: tr('Pending','待提交') },
          { value:'history', label: tr('History','历史') },
        ]} />
        {view==='pending' && changes.length>0 && (
          <>
            <div className="relative flex-1">
              <Icon name="edit" size={14} className="absolute left-3 top-1/2 -translate-y-1/2 text-ink3"/>
              <input value={msg} onChange={e=>setMsg(e.target.value)} placeholder={tr('Describe this change set (e.g. “Refresh Cortex accent + add chart gridlines”)','描述本次变更集(如「刷新 Cortex 强调色 + 新增图表网格线」)')}
                className="w-full h-8 bg-sunken border border-line rounded-[8px] pl-9 pr-3 text-[13px] text-ink focus-ring focus:border-line2" />
            </div>
            <Button variant="primary" icon={submitting?undefined:'branch'} disabled={changes.length===0||submitting||!canEdit()} onClick={submit} className="shrink-0">
              {submitting ? <span className="inline-flex items-center gap-2"><span className="w-3.5 h-3.5 rounded-full border-2 border-onAccent border-t-transparent animate-spin"/>{tr('Submitting…','提交中…')}</span> : tr('Submit for review','提交评审')}
            </Button>
          </>
        )}
      </div>

      <div className="flex-1 overflow-y-auto ds-scroll">
        {view==='history' ? (
          <div className="max-w-[1080px] mx-auto px-6 py-5 flex flex-col gap-3">
            {CHANGE_HISTORY.map(h=>(
              <div key={h.id} className="rounded-[12px] border border-line bg-panel p-4 flex items-center gap-4">
                <span className="w-10 h-10 rounded-full flex items-center justify-center shrink-0" style={{ background:'color-mix(in srgb, var(--success) 14%, transparent)', color:'var(--success)' }}><Icon name="check" size={18}/></span>
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 flex-wrap">
                    <span className="font-mono text-[13px] text-ink">PR #{h.number}</span>
                    <span className="inline-flex items-center gap-1 h-[18px] px-2 rounded-full text-[10.5px] font-medium" style={{ background:'color-mix(in srgb, var(--success) 13%, transparent)', color:'var(--success)' }}>{tr('Merged','已合并')}</span>
                    <span className="text-[11.5px] text-ink3">{h.date}</span>
                  </div>
                  <div className="text-[13.5px] text-ink mt-0.5 truncate">{tr(h.title, h.titleZh)}</div>
                  <div className="text-[11.5px] text-ink3 mt-0.5">{(h.items||[]).length} {tr('changes','项变更')} · {h.author} · {tr('roll-up','合并影响')} <span className="font-medium" style={{ color:IMPACT[h.rollup].color }}>{tr(IMPACT[h.rollup].label, IMPACT[h.rollup].labelZh)}</span></div>
                </div>
                <Button variant="secondary" size="sm" icon="external" className="shrink-0" onClick={()=>setOpenPr(h)}>{tr('Open','打开')}</Button>
              </div>
            ))}
          </div>
        ) : changes.length===0 ? (
          <EmptyState icon="check" title={tr('No unpublished changes','没有未发布的变更')} body={tr('Edits you save as drafts in Tokens and Assets will collect here, ready to submit for review.','在 Token 和资源库里保存为草稿的修改会汇集到这里,随时可提交评审。')} />
        ) : (
          <div className="max-w-[1080px] mx-auto px-6 py-5 flex flex-col gap-6">
            {[[tr('Token changes','Token 变更'), tokenChanges, 'layers'],[tr('Theme changes','主题变更'), themeChanges, 'sliders'],[tr('Component changes','组件变更'), componentChanges, 'component'],[tr('Content changes','文案变更'), contentChanges, 'edit'],[tr('Asset changes','资源变更'), assetChanges, 'image'],[tr('Theme rationale','差异说明'), rationaleChanges, 'eye']].map(([title, list, ic]) => list.length>0 && (
              <section key={title} className="rounded-[12px] border border-line bg-panel overflow-hidden">
                <div className="flex items-center gap-2 px-4 h-11 border-b border-line bg-sunken">
                  <Icon name={ic} size={15} className="text-ink2"/>
                  <span className="text-[13px] font-semibold text-ink">{title}</span>
                  <span className="text-[11px] text-ink3 font-mono">{list.length}</span>
                </div>
                {list.map(c => <ChangeRow key={c.id} c={c} onImpact={setImpact} onJump={onJump} />)}
              </section>
            ))}
            <div className="flex items-center justify-between text-[12px] text-ink3 px-1">
              <span>{tr('Roll-up impact','合并影响')}: <span className="font-semibold" style={{ color:IMPACT[rollupImpact(changes)].color }}>{tr(IMPACT[rollupImpact(changes)].label, IMPACT[rollupImpact(changes)].labelZh)}</span> · {tr('reviewers','评审人')}: {SESSION.reviewers.join(', ')}</span>
              <span>{SESSION.user.name} · @{SESSION.user.handle}</span>
            </div>
          </div>
        )}
      </div>

      {/* history change-set drawer — closes the loop on the submit flow */}
      <Drawer open={!!openPr} onClose={()=>setOpenPr(null)} width={680}>
        {openPr && (
          <div className="flex flex-col h-full">
            <div className="flex items-start justify-between px-5 pt-4 pb-3 border-b border-line">
              <div className="min-w-0">
                <div className="flex items-center gap-2 mb-1">
                  <span className="font-mono text-[14px] text-ink">PR #{openPr.number}</span>
                  <span className="inline-flex items-center gap-1 h-[18px] px-2 rounded-full text-[10.5px] font-medium" style={{ background:'color-mix(in srgb, var(--success) 13%, transparent)', color:'var(--success)' }}>{tr('Merged','已合并')}</span>
                </div>
                <div className="text-[13px] text-ink2 leading-snug">{tr(openPr.title, openPr.titleZh)}</div>
              </div>
              <IconButton name="close" title="Close" onClick={()=>setOpenPr(null)} />
            </div>
            <div className="px-5 py-3 border-b border-line flex items-center gap-4 text-[12px] text-ink3">
              <span>{openPr.date}</span><span>·</span><span>{openPr.author}</span><span>·</span>
              <span>{tr('roll-up','合并影响')} <span className="font-medium" style={{ color:IMPACT[openPr.rollup].color }}>{tr(IMPACT[openPr.rollup].label, IMPACT[openPr.rollup].labelZh)}</span></span>
            </div>
            <div className="flex-1 overflow-y-auto ds-scroll p-5">
              <div className="text-[10.5px] uppercase tracking-wide text-ink3 mb-2">{(openPr.items||[]).length} {tr('changes in this set','项变更')}</div>
              <div className="rounded-[12px] border border-line bg-panel overflow-hidden">
                {(openPr.items||[]).map((it)=>(
                  <div key={it.id} className="flex items-center gap-3 px-3.5 py-3 border-b border-[color:var(--border)] last:border-0">
                    <ActionTag action={it.action} />
                    <div className="w-[140px] shrink-0 min-w-0">
                      <div className="font-mono text-[12.5px] text-ink truncate">{it.target}</div>
                      <div className="text-[11px] text-ink3 mt-0.5">{tr({ token:'Token', component:'Component', asset:'Asset', theme:'Theme', content:'Content' }[it.kind] || it.kind, { token:'Token', component:'组件', asset:'资源', theme:'主题', content:'文案' }[it.kind])}</div>
                    </div>
                    <div className="min-w-0 flex-1"><Diff c={it} /></div>
                  </div>
                ))}
              </div>
            </div>
          </div>
        )}
      </Drawer>
    </div>
  );
}

function rollupImpact(changes){
  if (changes.some(c=>c.impact==='major')) return 'major';
  if (changes.some(c=>c.impact==='minor')) return 'minor';
  return 'patch';
}

function SubmittedView({ pr, count, msg, branch, onBack }) {
  return (
    <div className="h-full flex items-center justify-center p-8" style={{ animation:'fadeIn 220ms ease' }}>
      <div className="w-full max-w-[520px] rounded-[12px] border border-line bg-panel overflow-hidden shadow-[0_8px_40px_rgba(0,0,0,0.08)]">
        <div className="px-6 pt-7 pb-5 text-center border-b border-line">
          <div className="w-12 h-12 rounded-full mx-auto flex items-center justify-center mb-3" style={{ background:'color-mix(in srgb, var(--success) 14%, transparent)', color:'var(--success)' }}>
            <Icon name="check" size={24}/>
          </div>
          <h2 className="text-[17px] font-semibold text-ink">{tr('Submitted for review','已提交评审')}</h2>
          <p className="text-[13px] text-ink2 mt-1">{tr(`${count} ${count===1?'change':'changes'} packaged into a pull request.`, `${count} 项变更已打包为一个 Pull Request。`)}</p>
        </div>
        <div className="px-6 py-5 flex flex-col gap-3">
          <div className="flex items-center justify-between rounded-[12px] border border-line px-3.5 py-3">
            <div className="min-w-0">
              <div className="flex items-center gap-2 mb-1"><span className="font-mono text-[14px] text-ink">PR #{pr.number}</span>
                <span className="inline-flex items-center gap-1 h-[20px] px-2 rounded-full text-[11px] font-medium" style={{ background:'var(--accentWeak)', color:'var(--accent)' }}><span className="w-1.5 h-1.5 rounded-full bg-accent"/>{tr('In review','评审中')}</span></div>
              <div className="font-mono text-[11.5px] text-ink3 truncate">{pr.url}</div>
            </div>
            <a className="shrink-0"><Button variant="secondary" icon="external">{tr('Open','打开')}</Button></a>
          </div>
          {msg && <div className="text-[12.5px] text-ink2"><span className="text-ink3">{tr('Summary · ','摘要 · ')}</span>{msg}</div>}
          <div className="flex items-center justify-between text-[12px] text-ink3 pt-1">
            <span className="inline-flex items-center gap-1.5"><Icon name="branch" size={13}/><span className="font-mono">{branch}</span></span>
            <span>{tr('Roll-up','合并影响')} <span className="font-mono font-semibold" style={{ color:IMPACT[pr.rollup].color }}>{tr(IMPACT[pr.rollup].label, IMPACT[pr.rollup].labelZh)}</span></span>
          </div>
        </div>
        <div className="px-6 py-3.5 border-t border-line flex justify-center bg-sunken">
          <button onClick={onBack} className="text-[12.5px] text-ink2 hover:text-ink transition">{tr('← Back to changes','← 返回变更')}</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { ChangesPage });
