/* ThemesPage.jsx — brand theme manager (create / edit / delete) over THEMES.
   Edits mutate THEMES in memory and push a kind:'theme' change into Changes. */
const { useState: useStateTH, useRef: useRefTH } = React;

function ThemeSwatches({ accent, h = 28 }) {
  return (
    <span className="flex gap-0.5 shrink-0">
      {[400, 500, 600].map((s, i) => (
        <span key={s} className={cx('w-5', i === 0 && 'rounded-l-[5px]', i === 2 && 'rounded-r-[5px]')}
          style={{ height: h, background: accent[s] }} />
      ))}
    </span>
  );
}

function ThemeLogo({ th, size = 44 }) {
  if (th.logo) return <img src={th.logo} alt="" className="rounded-[12px] object-cover border border-line shrink-0" style={{ width: size, height: size }} />;
  return (
    <span className="rounded-[12px] flex items-center justify-center text-white font-semibold border border-line2 shrink-0"
      style={{ width: size, height: size, background: th.accent[500], fontSize: Math.round(size * 0.4) }}>
      {(th.name || '?').trim().charAt(0).toUpperCase()}
    </span>
  );
}

function LogoUpload({ draft, onPick, onRemove }) {
  const ref = useRefTH(null);
  function handle(e) { const f = e.target.files && e.target.files[0]; if (!f) return; const r = new FileReader(); r.onload = () => onPick(r.result); r.readAsDataURL(f); e.target.value = ''; }
  return (
    <div className="flex items-center gap-3">
      <ThemeLogo th={draft} size={64} />
      <div className="flex flex-col gap-1.5">
        <input ref={ref} type="file" accept="image/*" onChange={handle} className="hidden" />
        <Button size="sm" variant="secondary" icon="upload" onClick={() => ref.current && ref.current.click()}>{draft.logo ? tr('Replace logo', '替换 logo') : tr('Upload logo', '上传 logo')}</Button>
        {draft.logo
          ? <button onClick={onRemove} className="text-[11.5px] text-ink3 hover:text-danger text-left transition">{tr('Remove', '移除')}</button>
          : <span className="text-[11.5px] text-ink3">{tr('SVG / PNG · falls back to a monogram', 'SVG / PNG · 缺省用首字母')}</span>}
      </div>
    </div>
  );
}

function ThemeCard({ th, isActive, onEdit }) {
  return (
    <button onClick={onEdit}
      className="text-left rounded-[12px] border border-line bg-panel p-4 hover:border-line2 hover:bg-hover transition group flex flex-col gap-3">
      <div className="flex items-center gap-3">
        <ThemeLogo th={th} size={40} />
        <div className="min-w-0 flex-1">
          <div className="flex items-center gap-1.5">
            <span className="text-[14px] font-semibold text-ink truncate">{th.name}</span>
            {isActive && <span className="text-[10px] text-accent font-medium px-1.5 h-[16px] inline-flex items-center rounded-full bg-accentWeak shrink-0">{tr('Previewing', '预览中')}</span>}
          </div>
          <div className="text-[11.5px] text-ink3 truncate">{th.line}</div>
        </div>
        <Icon name="edit" size={15} className="text-ink3 opacity-0 group-hover:opacity-100 transition shrink-0" />
      </div>
      <div className="flex items-center gap-3 text-[11px] text-ink3 font-mono">
        {[400, 500, 600].map(s => <span key={s}>{th.accent[s]}</span>)}
      </div>
    </button>
  );
}

function ColorField({ label, value, onChange }) {
  return (
    <div className="flex flex-col gap-1.5 min-w-0">
      <label className="text-[12px] font-medium text-ink2">{label}</label>
      <div className="flex items-center gap-2 min-w-0">
        <label className="relative w-8 h-8 rounded-[8px] border border-line2 overflow-hidden shrink-0 cursor-pointer" style={{ background: value }}>
          <input type="color" value={value} onChange={e => onChange(e.target.value)} className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" />
        </label>
        <input value={value} onChange={e => onChange(e.target.value)}
          className="flex-1 min-w-0 h-8 bg-sunken border border-line rounded-[8px] px-2 text-[12px] font-mono text-ink focus-ring focus:border-line2" />
      </div>
    </div>
  );
}

/* per-theme PIN list: the tokens this brand overrides, with an unpin (delete key) action.
   A pin is stale when its stored `_basis` hash differs from the base token's current source. */
function ThemePinList({ theme, onUnpin }) {
  const ov = (theme && theme.overrides) || {};
  const ids = Object.keys(ov).filter(id => TOKEN_MAP[id]);
  if (ids.length === 0) {
    return (
      <div className="rounded-[10px] border border-dashed border-line2 bg-sunken px-3 py-3 text-[12px] text-ink3 leading-snug">
        {tr('No pinned tokens. This theme inherits every base token. Pin one from the token editor → “Applies to · This theme only”.',
            '没有固定的 token。该主题完全继承基座。可在 token 编辑器 → “作用范围 · 仅此主题” 中固定。')}
      </div>
    );
  }
  return (
    <div className="rounded-[10px] border border-line overflow-hidden divide-y divide-[color:var(--border)]">
      {ids.map(id => {
        const tk = TOKEN_MAP[id];
        const src = ov[id];
        const stale = typeof sourceHash === 'function' && src._basis != null && src._basis !== sourceHash(tk.source);
        const r = resolve(id, { theme, mode: 'light' });
        return (
          <div key={id} className="flex items-center gap-2.5 px-3 h-10">
            {tk.kind === 'color' ? <Swatch color={r.value} size={16} /> : <span className="w-4 h-4 rounded bg-sunken border border-line shrink-0" />}
            <div className="min-w-0 flex-1">
              <div className="font-mono text-[12px] text-ink truncate">{id}</div>
              <div className="text-[10.5px] text-ink3 truncate">
                {src.type === 'ref' ? '{' + src.ref + '}' : src.type === 'value' ? String(src.value) : src.type}
              </div>
            </div>
            {stale && <Pill tone="warning" icon="warningTri">{tr('base changed', '基座已变')}</Pill>}
            {canEdit() && onUnpin && (
              <button onClick={() => onUnpin(theme.id, id)} title={tr('Unpin', '取消固定')}
                className="text-ink3 hover:text-danger transition shrink-0"><Icon name="trash" size={14} /></button>
            )}
          </div>
        );
      })}
    </div>
  );
}

function ThemeEditor({ theme, isNew, onClose, onSave, onDelete, onUnpin }) {
  const [draft, setDraft] = useStateTH(() => theme
    ? { id: theme.id, name: theme.name, line: theme.line, logo: theme.logo || null, accent: { ...theme.accent } }
    : { id: '', name: '', line: '', logo: null, accent: { 400: '#4E84FB', 500: '#0A59F7', 600: '#0A47C9' } });
  const [confirmDel, setConfirmDel] = useStateTH(false);
  const set = (k, v) => setDraft(d => ({ ...d, [k]: v }));
  const setAccent = (s, v) => setDraft(d => ({ ...d, accent: { ...d.accent, [s]: v } }));
  const valid = draft.name.trim().length > 0;

  return (
    <Drawer open={true} onClose={onClose} width={440}>
      <div className="flex items-start justify-between px-5 pt-4 pb-3 border-b border-line">
        <div>
          <div className="text-[11px] text-ink3 uppercase tracking-wide mb-1">{tr('Brand theme', '品牌主题')}</div>
          <h2 className="text-[16px] font-semibold text-ink">{isNew ? tr('New theme', '新建主题') : draft.name}</h2>
        </div>
        <IconButton name="close" title="Close" onClick={onClose} />
      </div>

      <div className="flex-1 overflow-y-auto ds-scroll px-5 py-4 flex flex-col gap-4">
        <div>
          <label className="text-[12px] font-medium text-ink2 block mb-2">{tr('Brand logo', '品牌 logo')}</label>
          <LogoUpload draft={draft} onPick={d => set('logo', d)} onRemove={() => set('logo', null)} />
        </div>

        <Field label={tr('Name', '名称')}><TextInput value={draft.name} onChange={e => set('name', e.target.value)} placeholder={tr('e.g. Atlas Analytics', '如 Atlas Analytics')} /></Field>
        <Field label={tr('Product line', '产品线')}><TextInput value={draft.line} onChange={e => set('line', e.target.value)} placeholder={tr('e.g. Data dashboards', '如 数据看板')} /></Field>

        <div className="grid grid-cols-3 gap-2.5">
          <ColorField label={tr('Accent 400', '强调 400')} value={draft.accent[400]} onChange={v => setAccent(400, v)} />
          <ColorField label={tr('Accent 500', '强调 500')} value={draft.accent[500]} onChange={v => setAccent(500, v)} />
          <ColorField label={tr('Accent 600', '强调 600')} value={draft.accent[600]} onChange={v => setAccent(600, v)} />
        </div>
        <p className="text-[11.5px] text-ink3 leading-relaxed">{tr('500 is the base accent. 400 is the lighter (dark-mode) tint, 600 the pressed tone. Switching the preview theme re-resolves every accent-derived token.', '500 为基准强调色,400 为更亮(暗色模式)色调,600 为按下态。切换预览主题会重新解析所有由强调色派生的 token。')}</p>

        {!isNew && (
          <div className="flex flex-col gap-2 pt-1">
            <div className="flex items-center justify-between">
              <label className="text-[12px] font-medium text-ink2">{tr('Pinned tokens', '固定的 token')}</label>
              <span className="text-[11px] text-ink3">{Object.keys((theme && theme.overrides) || {}).length}</span>
            </div>
            <ThemePinList theme={theme} onUnpin={onUnpin} />
            <p className="text-[11.5px] text-ink3 leading-snug">{tr('Tokens this brand overrides. Every other token inherits the shared base.', '该品牌单独覆盖的 token。其余 token 继承共享基座。')}</p>
          </div>
        )}
      </div>

      <div className="border-t border-line px-5 py-3 flex items-center justify-between gap-2">
        <div>
          {!isNew && canEdit() && (confirmDel
            ? <ConfirmInline open={true} label={tr('Delete theme?', '删除主题?')} onConfirm={() => { onDelete(draft.id); onClose(); }} onCancel={() => setConfirmDel(false)} />
            : <Button variant="danger" icon="trash" onClick={() => setConfirmDel(true)}>{tr('Delete', '删除')}</Button>)}
        </div>
        <div className="flex items-center gap-2">
          <Button variant="ghost" onClick={onClose}>{tr('Cancel', '取消')}</Button>
          <Button variant="primary" icon="check" disabled={!valid || !canEdit()} onClick={() => { onSave(draft, isNew); onClose(); }}>{tr('Save draft', '保存草稿')}</Button>
        </div>
      </div>
    </Drawer>
  );
}

function ThemesPage({ theme, rev, onSaveTheme, onDeleteTheme, onUnpin, focusId, clearFocus, onCompare }) {
  const [editing, setEditing] = useStateTH(null); // { theme } | { isNew:true }
  void rev; // re-render on pin/unpin so the editor's pin list stays live

  React.useEffect(() => { if (focusId) { const th = THEMES.find(x => x.id === focusId); if (th) setEditing({ theme: th }); if (clearFocus) clearFocus(); } }, [focusId]);

  return (
    <div className="h-full flex flex-col">
      <PageToolbar
        title={tr('Themes', '主题')}
        count={THEMES.length}
        subtitle={tr('Manage the brand themes for each product line. Each carries an accent scale that re-resolves accent-derived tokens.', '管理各产品线的品牌主题。每个主题带一套强调色阶,会重新解析由强调色派生的 token。')}
        secondaryActions={onCompare && <Button variant="secondary" size="sm" icon="diff" onClick={onCompare}>{tr('Compare themes', '对比主题')}</Button>}
      />

      <div className="flex-1 overflow-y-auto ds-scroll p-6">
        <div className="grid gap-3" style={{ gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))' }}>
          {canEdit() && <button onClick={() => setEditing({ isNew: true })}
            className="rounded-[12px] border border-dashed border-line2 bg-sunken p-4 min-h-[108px] flex flex-col items-center justify-center gap-2 text-ink3 hover:text-accent hover:border-accent hover:bg-accentWeak transition">
            <Icon name="plus" size={20} /><span className="text-[12.5px] font-medium">{tr('New theme', '新建主题')}</span>
          </button>}
          {THEMES.map(th => <ThemeCard key={th.id} th={th} isActive={theme && theme.id === th.id} onEdit={() => setEditing({ theme: th })} />)}
        </div>
      </div>

      {editing && <ThemeEditor theme={editing.theme} isNew={!!editing.isNew} onClose={() => setEditing(null)} onSave={onSaveTheme} onDelete={onDeleteTheme} onUnpin={onUnpin} />}
    </div>
  );
}

Object.assign(window, { ThemesPage });
