/* global React */
// Data Editor: tree nav + team list + edit + Staging drawer.

function DataEditorPage({ toast, openStagingExt, onStagingClosed }) {
  const [selectedArea, setSelectedArea] = React.useState(null);
  const [selectedNpc, setSelectedNpc] = React.useState(null);
  const [expanded, setExpanded] = React.useState(new Set());
  const [stagingOpen, setStagingOpen] = React.useState(false);
  const [editingIdx, setEditingIdx] = React.useState(null);
  const [lineupData, setLineupData] = React.useState({});
  const [stagingCount, setStagingCount] = React.useState(0);

  React.useEffect(() => {
    if (openStagingExt) { setStagingOpen(true); onStagingClosed?.(); }
  }, [openStagingExt]);

  React.useEffect(() => {
    window.API.lineups().then((d) => {
      setLineupData(d || {});
      if (!selectedArea && d) {
        const firstCode = Object.keys(d)[0];
        if (firstCode) {
          setSelectedArea(firstCode);
          setExpanded(new Set([firstCode]));
          const first = d[firstCode]?.[0];
          if (first) setSelectedNpc(first.npcName);
        }
      }
    });
    window.API.staging().then((r) => setStagingCount(r?.items?.length || 0));
  }, []);

  const areaList = Object.keys(lineupData).length
    ? Object.entries(lineupData).map(([code, groups]) => ({
        code, name: window.MOCK.AREAS.find((a) => a.code === code)?.name || code,
        color: window.MOCK.AREAS.find((a) => a.code === code)?.color || '#6366F1',
        groups,
        count: groups.reduce((n, g) => n + g.lineupList.length, 0),
      }))
    : window.MOCK.AREAS.map((a) => ({ ...a, groups: [] }));

  const teams = (lineupData[selectedArea]?.find((g) => g.npcName === selectedNpc)?.lineupList || []).map((l) => ({
    idx: l.idx || `第${l.i || l.id}套`,
    speed: l.speed, drug: l.drug, weather: l.weather,
    ding: l.ding, lock: l.lock, chu: l.chu,
    team: (l.playerList || []).slice(0, 6).map((p) => ({
      name: p.name,
      color: window.MOCK.POKEMON.find((x) => x.name === p.name)?.color || '#999',
    })),
    note: '',
  }));
  const npc = { name: selectedNpc || '请选择天王', team_count: teams.length };

  return (
    <div>
      <div className="page-header">
        <div>
          <div className="breadcrumb"><span>日常</span><span className="sep">/</span><span>数据编辑</span>
            {selectedArea && <><span className="sep">/</span><span>{areaList.find((a)=>a.code===selectedArea)?.name || selectedArea}</span></>}
            {selectedNpc && <><span className="sep">/</span><span>{selectedNpc}</span></>}
          </div>
          <h1 className="page-title">数据编辑器</h1>
          <div className="page-subtitle">所有修改先入暂存,审计后由你统一发布到 manifest。</div>
        </div>
        <div className="hstack">
          <button onClick={() => setStagingOpen(true)} className="btn"
                  style={{ paddingRight: 8, borderColor: 'var(--warning)', color: 'var(--warning)' }}>
            <window.I.layers size={14}/>
            <span>暂存中</span>
            <span className="badge" style={{ background: 'var(--warning)' }}>{stagingCount}</span>
          </button>
          <window.Btn icon={<window.I.plus size={14}/>}>新增阵容</window.Btn>
        </div>
      </div>

      <div style={{ display:'grid', gridTemplateColumns: '260px 1fr', gap: 16, alignItems: 'flex-start' }}>
        {/* Tree */}
        <div className="card card-pad-sm" style={{ position:'sticky', top: 16 }}>
          <div style={{ position:'relative', marginBottom: 12 }}>
            <window.I.search size={13} style={{ position:'absolute', left: 10, top: 11, color: 'var(--text-3)' }}/>
            <input className="input" placeholder="搜索 NPC…" style={{ paddingLeft: 32, height: 32 }}/>
          </div>
          {areaList.map((area) => {
            const exp = expanded.has(area.code);
            return (
              <div key={area.code} style={{ marginBottom: 4 }}>
                <div className="tree-item group" onClick={() => {
                  const ns = new Set(expanded);
                  exp ? ns.delete(area.code) : ns.add(area.code);
                  setExpanded(ns);
                  if (!exp) setSelectedArea(area.code);
                }}>
                  <window.I.chevD size={12} style={{ transform: exp ? 'rotate(0)' : 'rotate(-90deg)', transition: 'transform .12s' }}/>
                  <span style={{ width: 8, height: 8, borderRadius: 2, background: area.color }}/>
                  {area.name}
                  <span className="count">{area.count}</span>
                </div>
                {exp && (area.groups || []).map((g) => (
                  <div key={g.npcName} className={`tree-item ${selectedNpc === g.npcName && selectedArea === area.code ? 'active' : ''}`}
                       onClick={() => { setSelectedArea(area.code); setSelectedNpc(g.npcName); }}
                       style={{ paddingLeft: 26 }}>
                    <window.I.user size={13}/>
                    {g.npcName}
                    <span className="count">{g.lineupList.length}</span>
                  </div>
                ))}
                {exp && (!area.groups || area.groups.length === 0) && (
                  <div style={{ padding: '8px 12px 8px 26px', color: 'var(--text-3)', fontSize: 12 }}>
                    暂无数据
                  </div>
                )}
              </div>
            );
          })}
        </div>

        {/* Right pane */}
        <div>
          {/* NPC header */}
          <div className="card card-pad" style={{ marginBottom: 16 }}>
            <div className="hstack" style={{ justifyContent:'space-between' }}>
              <div className="hstack" style={{ gap: 16 }}>
                <window.Sprite name={npc?.name} color="#A78BFA" size="lg"/>
                <div>
                  <div style={{ fontSize: 20, fontWeight: 600 }}>{npc?.name || '小茂'}</div>
                  <div className="muted" style={{ fontSize: 12, marginTop: 4 }}>
                    关都 · {npc?.team_count || 12} 套阵容 · 头像:
                    <button style={{ color: 'var(--indigo)', marginLeft: 4 }}>编辑</button>
                  </div>
                </div>
              </div>
              <div className="hstack">
                <window.Btn size="sm" icon={<window.I.list size={12}/>}>排序模式</window.Btn>
                <window.Btn size="sm">复制到另一 NPC</window.Btn>
                <window.Btn kind="primary" size="sm" icon={<window.I.plus size={12}/>}>新增阵容</window.Btn>
              </div>
            </div>
          </div>

          {/* Team list */}
          {teams.map((team, ti) => (
            <TeamCard key={ti} team={team} index={ti + 1}
                      editing={editingIdx === ti}
                      onEdit={() => setEditingIdx(ti)}
                      onCancel={() => setEditingIdx(null)}
                      onSave={() => { setEditingIdx(null); toast.push('已存入暂存'); }}/>
          ))}

          {/* Add new */}
          <button onClick={() => toast.push('已添加新阵容草稿')} className="card card-pad-sm"
                  style={{
                    width: '100%', cursor:'pointer',
                    border: '1px dashed var(--border-strong)',
                    background: 'var(--surface-2)',
                    color: 'var(--text-2)',
                    display:'flex', alignItems:'center', justifyContent:'center', gap: 8,
                    marginTop: 8
                  }}>
            <window.I.plus size={14}/> 新增第 {teams.length + 1} 套阵容
          </button>
        </div>
      </div>

      {/* Staging drawer */}
      {stagingOpen && (
        <>
          <div className="drawer-backdrop" onClick={() => setStagingOpen(false)}/>
          <div className="drawer">
            <StagingDrawer onClose={() => setStagingOpen(false)} toast={toast}/>
          </div>
        </>
      )}
    </div>
  );
}

function TeamCard({ team, index, editing, onEdit, onCancel, onSave }) {
  const [collapsed, setCollapsed] = React.useState(false);
  return (
    <div className="card" style={{
      marginBottom: 12,
      borderColor: editing ? 'var(--indigo)' : 'var(--border)',
      boxShadow: editing ? '0 0 0 1px var(--indigo)' : 'none',
    }}>
      <div className="card-header" style={{ background: editing ? 'var(--primary-50)' : 'transparent' }}>
        <div className="hstack">
          <button onClick={() => setCollapsed(!collapsed)} className="btn icon sm" style={{ background: 'transparent', border: 0 }}>
            <window.I.chevD size={14} style={{ transform: collapsed ? 'rotate(-90deg)' : 'none', transition: 'transform .12s' }}/>
          </button>
          <span style={{ fontWeight: 600 }}>{team.idx}</span>
          <span className="muted">·</span>
          <span style={{ display:'flex', gap: 4 }}>
            <Chip>速 {team.speed}</Chip>
            <Chip>{team.weather}</Chip>
            <Chip>{team.drug}</Chip>
            {team.ding && <Chip>定</Chip>}
            {team.lock && <Chip>锁</Chip>}
            {team.chu  && <Chip>初</Chip>}
          </span>
          {editing && <span className="pill new" style={{ marginLeft: 8 }}><span className="dot"/>编辑中</span>}
        </div>
        <div className="hstack">
          {!editing && (
            <>
              <window.Btn size="xs" icon={<window.I.edit size={11}/>} onClick={onEdit}>编辑</window.Btn>
              <window.Btn size="xs">复制</window.Btn>
              <window.Btn size="xs" kind="danger" icon={<window.I.trash size={11}/>}>删除</window.Btn>
            </>
          )}
          {editing && (
            <>
              <window.Btn size="xs" onClick={onCancel}>取消</window.Btn>
              <window.Btn size="xs" kind="primary" onClick={onSave}>保存到暂存</window.Btn>
            </>
          )}
        </div>
      </div>
      {!collapsed && (
        <div className="card-pad-sm">
          {/* Team grid */}
          <div className="team-row" style={{ gridTemplateColumns: 'repeat(6, 1fr)' }}>
            {team.team.map((p, i) => (
              <PokemonSlot key={i} p={p} editing={editing} highlighted={editing && i === 2}/>
            ))}
          </div>
          {team.note && !editing && (
            <>
              <div className="divider"/>
              <div className="muted" style={{ fontSize: 12 }}>备注:</div>
              <div style={{ fontSize: 13, marginTop: 4 }}>{team.note}</div>
            </>
          )}
        </div>
      )}
    </div>
  );
}

function PokemonSlot({ p, editing, highlighted }) {
  return (
    <div style={{
      padding: 12,
      border: `1px solid ${highlighted ? 'var(--warning)' : 'var(--border)'}`,
      borderRadius: 'var(--r-md)',
      background: highlighted ? 'var(--warning-bg)' : editing ? 'var(--surface-2)' : 'var(--surface)',
      position: 'relative',
    }}>
      {highlighted && (
        <span style={{
          position:'absolute', top: -8, right: 8,
          fontSize: 10, padding: '2px 6px',
          background: 'var(--warning)', color: 'white',
          borderRadius: 'var(--r-pill)', fontWeight: 600,
        }}>已修改</span>
      )}
      <div style={{ textAlign:'center', marginBottom: 8 }}>
        <window.Sprite name={p.name} color={p.color} size="lg"/>
      </div>
      <div style={{ textAlign:'center', fontWeight: 500, fontSize: 13 }}>{p.name}</div>
      <div style={{ display:'flex', justifyContent:'center', gap: 3, marginTop: 4 }}>
        {p.types.map((t) => <window.TypeChip key={t} type={t}/>)}
      </div>
      {editing ? (
        <div style={{ marginTop: 10 }}>
          <label className="field" style={{ marginBottom: 2 }}>性格</label>
          <input className="input" defaultValue="保守" style={{ height: 28 }}/>
          <label className="field" style={{ marginBottom: 2, marginTop: 6 }}>道具</label>
          <input className="input" defaultValue="讲究头巾" style={{ height: 28 }}/>
          <label className="field" style={{ marginBottom: 2, marginTop: 6 }}>技能</label>
          <div style={{ display:'grid', gridTemplateColumns: '1fr 1fr', gap: 4 }}>
            <input className="input" defaultValue="热风" style={{ height: 28 }}/>
            <input className="input" defaultValue="气合拳" style={{ height: 28 }}/>
            <input className="input" defaultValue="暗影爪" style={{ height: 28 }}/>
            <input className="input" defaultValue="龙之爪" style={{ height: 28 }}/>
          </div>
        </div>
      ) : (
        <div style={{ marginTop: 8, fontSize: 11, color: 'var(--text-3)', textAlign:'center', lineHeight: 1.6 }}>
          <div>讲究头巾 · 保守</div>
          <div className="mono">热风/气合拳</div>
          <div className="mono">暗影爪/龙之爪</div>
        </div>
      )}
    </div>
  );
}

// ────────────────────────────────────────────────────────────────────
// Staging drawer

function StagingDrawer({ onClose, toast }) {
  const [items, setItems] = React.useState(window.MOCK.STAGING);
  const [publishing, setPublishing] = React.useState(false);
  const [expanded, setExpanded] = React.useState(null);

  React.useEffect(() => {
    window.API.staging().then((r) => {
      if (r?.items) {
        setItems(r.items.map((x) => ({
          id: 's' + x.id, _id: x.id, kind: x.kind,
          area: x.area_code, npc: x.npc_name, target: x.target || '—',
          summary: x.summary || '', actor: x.actor,
          at: x.created_at ? new Date(x.created_at).toLocaleString('zh-CN', { hour12: false }) : '',
        })));
      }
    }).catch(() => {});
  }, []);
  const counts = {
    add: items.filter((i) => i.kind === 'add').length,
    edit: items.filter((i) => i.kind === 'edit').length,
    delete: items.filter((i) => i.kind === 'delete').length,
  };

  return (
    <>
      <div className="drawer-header">
        <div>
          <div style={{ fontWeight: 600, fontSize: 16 }}>暂存中的变更</div>
          <div className="muted" style={{ fontSize: 12, marginTop: 4 }}>
            <span style={{ color: 'var(--success)' }}>+{counts.add} 新增</span>
            <span style={{ margin: '0 8px' }}>·</span>
            <span style={{ color: 'var(--warning)' }}>~{counts.edit} 修改</span>
            <span style={{ margin: '0 8px' }}>·</span>
            <span style={{ color: 'var(--danger)' }}>-{counts.delete} 删除</span>
          </div>
        </div>
        <button className="icon-btn" onClick={onClose}><window.I.x size={16}/></button>
      </div>

      <div className="drawer-body">
        <div className="alert info" style={{ marginBottom: 16 }}>
          <window.I.info size={16}/>
          <div>
            发布将触发 GitHub Actions → 生成新 manifest → 部署到 Cloudflare Pages。
            一般 2-3 分钟完成。
          </div>
        </div>

        {items.map((it) => (
          <div key={it.id} className="card" style={{ marginBottom: 8 }}>
            <div className="card-header" style={{ padding: '10px 14px', cursor:'pointer' }}
                 onClick={() => setExpanded(expanded === it.id ? null : it.id)}>
              <div className="hstack">
                <KindBadge kind={it.kind}/>
                <span style={{ fontWeight: 500 }}>{it.area} / {it.npc}</span>
                <span className="muted">·</span>
                <span>{it.target}</span>
              </div>
              <div className="hstack">
                <span className="muted" style={{ fontSize: 12 }}>{it.at}</span>
                <button className="btn xs" onClick={async (e) => {
                  e.stopPropagation();
                  if (it._id) { await window.API.stagingDel(it._id).catch(()=>null); }
                  setItems(items.filter((x) => x.id !== it.id));
                  toast.push('已回滚 1 条');
                }}>回滚</button>
              </div>
            </div>
            {expanded === it.id && (
              <div className="card-pad-sm" style={{ background: 'var(--surface-2)', borderTop:'1px solid var(--border)' }}>
                <div style={{ fontSize: 13, marginBottom: 12 }}>{it.summary}</div>
                <DiffPreview kind={it.kind}/>
              </div>
            )}
          </div>
        ))}

        {items.length === 0 && (
          <window.Empty title="暂存区是空的" hint="所有改动已发布或回滚。"/>
        )}
      </div>

      <div className="drawer-footer">
        <button className="btn danger" onClick={async () => {
          await Promise.all(items.filter((x) => x._id).map((x) => window.API.stagingDel(x._id).catch(()=>null)));
          setItems([]); toast.push('已回滚全部变更');
        }}>
          回滚全部
        </button>
        <div className="hstack">
          <window.Btn onClick={onClose}>稍后</window.Btn>
          <window.Btn kind="primary" icon={publishing ? null : <window.I.upload size={14}/>}
                      disabled={publishing || items.length === 0}
                      onClick={async () => {
                        setPublishing(true);
                        try {
                          const r = await window.API.publishStaging();
                          toast.push(`已触发部署,${r.published || items.length} 条变更`);
                          setItems([]);
                          onClose();
                        } catch (e) {
                          toast.push(`发布失败:${e.message}`, 'err');
                        } finally {
                          setPublishing(false);
                        }
                      }}>
            {publishing ? <><span className="spinner"/> 发布中…</> : `发布 ${items.length} 条变更`}
          </window.Btn>
        </div>
      </div>
    </>
  );
}

function KindBadge({ kind }) {
  const map = {
    add:    { bg: 'var(--success-bg)', c: 'var(--success)', txt: '新增' },
    edit:   { bg: 'var(--warning-bg)', c: 'var(--warning)', txt: '修改' },
    delete: { bg: 'var(--danger-bg)',  c: 'var(--danger)',  txt: '删除' },
  };
  const m = map[kind];
  return (
    <span style={{
      display:'inline-flex', alignItems:'center', gap: 4,
      padding: '2px 8px', borderRadius: 'var(--r-sm)',
      background: m.bg, color: m.c, fontSize: 11, fontWeight: 500,
    }}>
      {kind === 'add' ? '+' : kind === 'edit' ? '~' : '−'} {m.txt}
    </span>
  );
}

function DiffPreview({ kind }) {
  return (
    <pre style={{
      margin: 0, padding: 12,
      background: 'var(--surface)',
      border: '1px solid var(--border)',
      borderRadius: 'var(--r-sm)',
      fontSize: 12, fontFamily:'var(--font-mono)', lineHeight: 1.6,
      whiteSpace:'pre-wrap',
    }}>
      <span style={{ color: 'var(--text-3)' }}>{`{
  "areaCode": "GUANDU",
  "npcName": "小茂",
  "idx": "第2套",
  "speed": "S",
  "weather": "晴天",
  "playerList": [`}</span>
      <br/>
      <span style={{ color: 'var(--text-3)' }}>    ...</span><br/>
      {kind === 'edit' && <><span className="diff-del">{`    {"name": "可达鸭", "skillA": "水枪"}`}</span><br/></>}
      {kind === 'edit' && <span className="diff-add">{`    {"name": "钢铁人", "skillA": "影子球"}`}</span>}
      {kind === 'add' && <span className="diff-add">{`    {"name": "妙蛙花", "skillA": "光合作用"}`}</span>}
      {kind === 'delete' && <span className="diff-del">{`    {"name": "皮卡丘", ...整套删除}`}</span>}
      <br/><span style={{ color: 'var(--text-3)' }}>    ...{`]}`}</span>
    </pre>
  );
}

function Chip({ children }) {
  return (
    <span style={{
      display:'inline-flex', alignItems:'center',
      fontSize: 11, padding: '2px 7px',
      background: 'var(--surface-2)', border: '1px solid var(--border)',
      borderRadius: 'var(--r-sm)',
      color: 'var(--text-2)', whiteSpace:'nowrap',
    }}>{children}</span>
  );
}

Object.assign(window, { DataEditorPage });
