// AI Worker Platform — React App
const { useState, useEffect, useRef, useCallback } = React;

const API = '/api';
const apiFetch = (path, opts = {}) =>
  fetch(API + path, { headers: { 'Content-Type': 'application/json' }, ...opts });

const TOOL_ICONS = {
  tw_stock_list:        '📊', tw_stock_price:     '📈',
  tw_stock_fundamental: '💹', tw_stock_news:      '📰',
  tw_stock_revenue:     '💰', tw_stock_realtime:  '⚡',
  us_stock_quote:       '🇺🇸', write_notebook:     '📝',
  read_notebook:        '📖',
};

const MODEL_OPTIONS = [
  'claude-sonnet-4-6', 'claude-opus-4-8', 'claude-haiku-4-5-20251001',
];

// ─── Sidebar ──────────────────────────────────────────

function Sidebar({ agents, departments, selectedId, onSelect, onNew, onNewDept }) {
  const byDept = {};
  departments.forEach(d => { byDept[d.id] = []; });
  agents.forEach(a => {
    if (!byDept[a.department_id]) byDept[a.department_id] = [];
    byDept[a.department_id].push(a);
  });
  const unassigned = agents.filter(a => !a.department_id);

  return (
    <aside className="sidebar">
      <div className="sidebar-header">
        <div className="sidebar-brand">
          <div className="dot"/>
          AI Worker
        </div>
      </div>
      <div className="sidebar-scroll">
        {departments.map(d => (
          <div key={d.id}>
            <div className="dept-label">{d.icon} {d.name}</div>
            {(byDept[d.id] || []).map(a => (
              <AgentItem key={a.id} agent={a} active={a.id === selectedId} onClick={() => onSelect(a.id)} />
            ))}
          </div>
        ))}
        {unassigned.length > 0 && (
          <div>
            <div className="dept-label">未分配</div>
            {unassigned.map(a => (
              <AgentItem key={a.id} agent={a} active={a.id === selectedId} onClick={() => onSelect(a.id)} />
            ))}
          </div>
        )}
        <button className="sidebar-new-btn" onClick={onNew}>+ 新增員工</button>
      </div>
    </aside>
  );
}

function AgentItem({ agent, active, onClick }) {
  return (
    <div className={`agent-item ${active ? 'active' : ''}`} onClick={onClick}>
      <div className={`agent-status ${agent.status || 'idle'}`} />
      <div style={{ minWidth: 0 }}>
        <div className="agent-name">{agent.name}</div>
        <div className="agent-sub">{agent.status === 'running' ? '執行中…' : agent.last_run_at ? `上次：${new Date(agent.last_run_at).toLocaleTimeString('zh-TW',{hour:'2-digit',minute:'2-digit'})}` : '閒置'}</div>
      </div>
    </div>
  );
}

// ─── Tools Picker ─────────────────────────────────────

function ToolsPicker({ selected = [], onChange, allTools }) {
  const toggle = (name) => {
    if (selected.includes(name)) onChange(selected.filter(t => t !== name));
    else onChange([...selected, name]);
  };
  return (
    <div className="tools-grid">
      {allTools.map(t => (
        <div key={t.name} className={`tool-chip ${selected.includes(t.name) ? 'on' : ''}`} onClick={() => toggle(t.name)}>
          <span className="tool-icon">{TOOL_ICONS[t.name] || '🔧'}</span>
          {t.name.replace(/_/g,' ')}
        </div>
      ))}
    </div>
  );
}

// ─── Agent Form (create / edit) ───────────────────────

function AgentForm({ agent, departments, allAgents, notebooks, allTools, onSave, onCancel, onDelete }) {
  const [form, setForm] = useState({
    name: agent?.name || '',
    instructions: agent?.instructions || '',
    model: agent?.model || 'claude-sonnet-4-6',
    tools: agent ? (typeof agent.tools === 'string' ? JSON.parse(agent.tools || '[]') : agent.tools || []) : [],
    department_id: agent?.department_id || '',
    handoff_agent_id: agent?.handoff_agent_id || '',
    notebook_id: agent?.notebook_id || '',
    schedule: agent?.schedule || '',
  });
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  return (
    <div>
      <div className="form-row">
        <div className="form-group">
          <label className="form-label">員工名稱</label>
          <input className="form-input" value={form.name} onChange={e => set('name', e.target.value)} placeholder="AI台指研究員" />
        </div>
        <div className="form-group">
          <label className="form-label">所屬部門</label>
          <select className="form-select" value={form.department_id} onChange={e => set('department_id', e.target.value)}>
            <option value="">— 未分配 —</option>
            {departments.map(d => <option key={d.id} value={d.id}>{d.icon} {d.name}</option>)}
          </select>
        </div>
      </div>

      <div className="form-group">
        <label className="form-label">員工指令 (System Prompt)</label>
        <textarea className="form-textarea" value={form.instructions}
          onChange={e => set('instructions', e.target.value)}
          placeholder="描述這位 AI 員工的職責和工作流程…" />
      </div>

      <div className="form-group">
        <label className="form-label">可用工具 (台股 API + 筆記)</label>
        <ToolsPicker selected={form.tools} onChange={v => set('tools', v)} allTools={allTools} />
      </div>

      <div className="form-row">
        <div className="form-group">
          <label className="form-label">AI 模型</label>
          <select className="form-select" value={form.model} onChange={e => set('model', e.target.value)}>
            {MODEL_OPTIONS.map(m => <option key={m} value={m}>{m}</option>)}
          </select>
        </div>
        <div className="form-group">
          <label className="form-label">完成後交接給</label>
          <select className="form-select" value={form.handoff_agent_id} onChange={e => set('handoff_agent_id', e.target.value)}>
            <option value="">— 不交接 —</option>
            {allAgents.filter(a => a.id !== agent?.id).map(a => <option key={a.id} value={a.id}>{a.name}</option>)}
          </select>
        </div>
      </div>

      <div className="form-row">
        <div className="form-group">
          <label className="form-label">寫入筆記本</label>
          <select className="form-select" value={form.notebook_id} onChange={e => set('notebook_id', e.target.value)}>
            <option value="">— 不儲存 —</option>
            {notebooks.map(n => <option key={n.id} value={n.id}>{n.name}</option>)}
          </select>
        </div>
        <div className="form-group">
          <label className="form-label">定期排程 (Cron)</label>
          <input className="form-input" value={form.schedule} onChange={e => set('schedule', e.target.value)}
            placeholder="0 9 * * 1-5  (每週一~五9點)" />
        </div>
      </div>

      <div style={{ display:'flex', gap:8, justifyContent:'space-between', marginTop:8 }}>
        {agent && (
          <button className="btn btn-danger" onClick={() => onDelete(agent.id)}>刪除員工</button>
        )}
        <div style={{ display:'flex', gap:8, marginLeft:'auto' }}>
          <button className="btn btn-ghost" onClick={onCancel}>取消</button>
          <button className="btn btn-primary" onClick={() => onSave(form)}>儲存</button>
        </div>
      </div>
    </div>
  );
}

// ─── Run Panel ────────────────────────────────────────

function RunPanel({ agentId, agentName, onRunComplete }) {
  const [input, setInput] = useState('');
  const [running, setRunning] = useState(false);
  const [events, setEvents] = useState([]);
  const [error, setError] = useState('');
  const outputRef = useRef(null);

  useEffect(() => {
    if (outputRef.current) outputRef.current.scrollTop = outputRef.current.scrollHeight;
  }, [events]);

  async function doRun() {
    setRunning(true); setEvents([]); setError('');
    try {
      const r = await apiFetch(`/agents/${agentId}/run`, {
        method: 'POST',
        body: JSON.stringify({ input }),
      });
      const data = await r.json();
      if (!r.ok) throw new Error(data.error || `HTTP ${r.status}`);
      setEvents(data.events || []);
      onRunComplete && onRunComplete();
    } catch (e) {
      setError(e.message);
    }
    setRunning(false);
  }

  return (
    <div className="run-panel">
      <div className="run-input-area">
        <input className="run-input" value={input} onChange={e => setInput(e.target.value)}
          placeholder="給員工額外指令（留空則依系統指令執行）…"
          onKeyDown={e => e.key === 'Enter' && !running && doRun()} />
        <button className={running ? 'stop-btn' : 'run-btn'} onClick={doRun} disabled={running}>
          {running ? '執行中…' : '▶ 執行'}
        </button>
      </div>

      <div className="output-wrap" ref={outputRef}>
        {events.length === 0 && !running && (
          <div className="run-placeholder">按「執行」啟動 {agentName}，輸出將顯示在這裡。</div>
        )}
        {events.map((e, i) => {
          if (e.type === 'tool_call') return (
            <div key={i} className="evt-tool">
              🔧 呼叫工具: <b>{e.name}</b>
              {e.input && Object.keys(e.input).length > 0 && (
                <span style={{opacity:.6}}> ({JSON.stringify(e.input)})</span>
              )}
            </div>
          );
          if (e.type === 'tool_result') return (
            <div key={i} className="evt-result">{e.result}</div>
          );
          if (e.type === 'text') return (
            <div key={i} className="evt-text">{e.text}</div>
          );
          return null;
        })}
        {error && <div className="evt-error">❌ {error}</div>}
        {running && <div className="evt-tool" style={{marginTop:8}}>⏳ 思考中…</div>}
      </div>
    </div>
  );
}

// ─── Runs History ─────────────────────────────────────

function RunsHistory({ agentId }) {
  const [runs, setRuns] = useState([]);
  const [detail, setDetail] = useState(null);

  useEffect(() => {
    apiFetch(`/agents/${agentId}/runs`).then(r => r.json()).then(setRuns);
  }, [agentId]);

  async function viewRun(id) {
    const r = await apiFetch(`/runs/${id}`);
    setDetail(await r.json());
  }

  if (detail) return (
    <div>
      <button className="btn btn-ghost" style={{marginBottom:16}} onClick={() => setDetail(null)}>← 返回列表</button>
      <div style={{marginBottom:8,fontSize:12,color:'var(--muted)'}}>
        Run #{detail.id} · {detail.started_at?.slice(0,16)} ·
        <span className={`run-status-badge ${detail.status}`} style={{marginLeft:6}}>{detail.status}</span>
      </div>
      {detail.input && <div style={{marginBottom:12,padding:'8px 12px',background:'var(--bg3)',borderRadius:6,fontSize:13}}>
        <span style={{color:'var(--muted)'}}>輸入: </span>{detail.input}
      </div>}
      <div className="output-wrap">
        {(JSON.parse(detail.messages || '[]')).map((e, i) => {
          if (e.type === 'tool_call') return <div key={i} className="evt-tool">🔧 {e.name} ({JSON.stringify(e.input)})</div>;
          if (e.type === 'tool_result') return <div key={i} className="evt-result">{e.result}</div>;
          if (e.type === 'text') return <div key={i} className="evt-text">{e.text}</div>;
          return null;
        })}
        {detail.error && <div className="evt-error">❌ {detail.error}</div>}
      </div>
    </div>
  );

  return (
    <div className="runs-list">
      {runs.length === 0 && <div className="empty">尚無執行記錄</div>}
      {runs.map(r => (
        <div key={r.id} className="run-row" onClick={() => viewRun(r.id)}>
          <div className="run-row-head">
            <span className={`run-status-badge ${r.status}`}>{r.status}</span>
            <span className="run-time">{r.started_at?.slice(0,16)}</span>
          </div>
          <div className="run-preview">{r.input || '（無額外指令）'}</div>
        </div>
      ))}
    </div>
  );
}

// ─── Overview Tab ─────────────────────────────────────

function OverviewTab({ agent, departments }) {
  const dept = departments.find(d => d.id === agent.department_id);
  let tools = [];
  try { tools = JSON.parse(agent.tools || '[]'); } catch (_) {}

  return (
    <div>
      <div className="overview-grid">
        <div className="stat-card">
          <div className="stat-num">{tools.length}</div>
          <div className="stat-label">可用工具</div>
        </div>
        <div className="stat-card">
          <div className="stat-num" style={{fontSize:20}}>{dept ? `${dept.icon} ${dept.name}` : '—'}</div>
          <div className="stat-label">所屬部門</div>
        </div>
        <div className="stat-card">
          <div className="stat-num" style={{fontSize:16}}>{agent.model?.split('-').slice(1, 3).join(' ') || '—'}</div>
          <div className="stat-label">AI 模型</div>
        </div>
      </div>

      <div style={{marginBottom:16}}>
        <div className="form-label" style={{marginBottom:8}}>系統指令</div>
        <div style={{background:'var(--bg3)',border:'1px solid var(--border)',borderRadius:8,padding:'12px 16px',fontSize:13,lineHeight:1.7,whiteSpace:'pre-wrap'}}>
          {agent.instructions || '（無指令）'}
        </div>
      </div>

      {tools.length > 0 && (
        <div>
          <div className="form-label" style={{marginBottom:8}}>工具清單</div>
          <div className="tools-grid">
            {tools.map(t => (
              <div key={t} className="tool-chip on">
                {TOOL_ICONS[t] || '🔧'} {t.replace(/_/g,' ')}
              </div>
            ))}
          </div>
        </div>
      )}

      {agent.handoff_agent_id && (
        <div style={{marginTop:16,padding:'10px 14px',border:'1px solid var(--border)',borderRadius:8,fontSize:13,color:'var(--muted)'}}>
          完成後交接給 <b style={{color:'var(--accent)'}}>{agent.handoff_agent_id}</b>
        </div>
      )}
    </div>
  );
}

// ─── Notebooks Page ───────────────────────────────────

function NotebooksPage({ notebooks, onRefresh }) {
  const [selected, setSelected] = useState(null);
  const [nb, setNb] = useState(null);

  async function open(id) {
    const r = await apiFetch(`/notebooks/${id}`);
    setNb(await r.json());
    setSelected(id);
  }
  async function save() {
    await apiFetch(`/notebooks/${nb.id}`, { method: 'PUT', body: JSON.stringify(nb) });
    onRefresh();
  }

  if (selected && nb) return (
    <div>
      <button className="btn btn-ghost" style={{marginBottom:16}} onClick={() => setSelected(null)}>← 返回</button>
      <div style={{display:'flex',gap:8,alignItems:'center',marginBottom:16}}>
        <input className="form-input" style={{width:240}} value={nb.name} onChange={e => setNb({...nb, name:e.target.value})} />
        <button className="btn btn-primary" onClick={save}>儲存</button>
      </div>
      <textarea className="form-textarea" style={{minHeight:400,fontFamily:'monospace'}}
        value={nb.content} onChange={e => setNb({...nb, content:e.target.value})} />
    </div>
  );

  return (
    <div>
      <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:16}}>
        <div style={{fontSize:16,fontWeight:700}}>📓 筆記本</div>
        <button className="btn btn-primary" onClick={async () => {
          const name = prompt('筆記本名稱：');
          if (!name) return;
          await apiFetch('/notebooks', {method:'POST',body:JSON.stringify({name})});
          onRefresh();
        }}>新增筆記本</button>
      </div>
      <div className="nb-list">
        {notebooks.map(n => (
          <div key={n.id} className="nb-card" onClick={() => open(n.id)}>
            <div className="nb-card-name">📓 {n.name}</div>
            <div className="nb-card-meta">
              {n.size ? `${n.size} 字` : '空'} · 更新 {n.updated_at?.slice(0,10) || '—'}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ─── Main App ─────────────────────────────────────────

function App() {
  const [departments, setDepartments] = useState([]);
  const [agents, setAgents] = useState([]);
  const [notebooks, setNotebooks] = useState([]);
  const [allTools, setAllTools] = useState([]);
  const [selectedId, setSelectedId] = useState(null);
  const [tab, setTab] = useState('overview');  // overview | settings | run | runs | notebooks
  const [showForm, setShowForm] = useState(false);
  const [page, setPage] = useState('agents'); // agents | notebooks

  const selectedAgent = agents.find(a => a.id === selectedId);

  async function load() {
    const [depts, agts, nbs, tools] = await Promise.all([
      apiFetch('/departments').then(r => r.json()),
      apiFetch('/agents').then(r => r.json()),
      apiFetch('/notebooks').then(r => r.json()),
      apiFetch('/tools').then(r => r.json()),
    ]);
    setDepartments(Array.isArray(depts) ? depts : []);
    setAgents(Array.isArray(agts) ? agts : []);
    setNotebooks(Array.isArray(nbs) ? nbs : []);
    setAllTools(Array.isArray(tools) ? tools : []);
  }

  useEffect(() => { load(); }, []);

  // 輪詢 running agents 狀態
  useEffect(() => {
    const hasRunning = agents.some(a => a.status === 'running');
    if (!hasRunning) return;
    const t = setTimeout(load, 3000);
    return () => clearTimeout(t);
  }, [agents]);

  async function saveAgent(form) {
    if (showForm === 'new') {
      await apiFetch('/agents', { method: 'POST', body: JSON.stringify(form) });
    } else {
      await apiFetch(`/agents/${selectedId}`, { method: 'PUT', body: JSON.stringify(form) });
    }
    await load();
    setShowForm(false);
    setTab('overview');
  }

  async function deleteAgent(id) {
    if (!confirm('確定刪除此員工？')) return;
    await apiFetch(`/agents/${id}`, { method: 'DELETE' });
    setSelectedId(null);
    setShowForm(false);
    await load();
  }

  function selectAgent(id) {
    setSelectedId(id);
    setTab('overview');
    setShowForm(false);
    setPage('agents');
  }

  const TABS = [
    { id: 'overview',  label: '總覽' },
    { id: 'settings',  label: '設定' },
    { id: 'run',       label: '執行' },
    { id: 'runs',      label: '記錄' },
  ];

  return (
    <div className="layout">
      <Sidebar
        agents={agents} departments={departments}
        selectedId={selectedId}
        onSelect={selectAgent}
        onNew={() => { setShowForm('new'); setSelectedId(null); setPage('agents'); }}
        onNewDept={() => {}}
      />

      <div className="main">
        {/* Topbar */}
        <div className="topbar">
          {page === 'notebooks' ? (
            <>
              <span className="topbar-title">📓 筆記本</span>
              <button className="btn btn-ghost" style={{marginLeft:'auto'}} onClick={() => setPage('agents')}>← 員工列表</button>
            </>
          ) : showForm === 'new' ? (
            <span className="topbar-title">+ 新增員工</span>
          ) : selectedAgent ? (
            <>
              <div className={`agent-status ${selectedAgent.status || 'idle'}`} style={{width:9,height:9}}/>
              <span className="topbar-title">{selectedAgent.name}</span>
              <div className="topbar-tabs">
                {TABS.map(t => (
                  <button key={t.id} className={`tab-btn ${tab === t.id ? 'active' : ''}`} onClick={() => setTab(t.id)}>
                    {t.label}
                  </button>
                ))}
              </div>
              {tab === 'run' ? null : (
                <button className="run-btn" onClick={() => setTab('run')}>▶ 執行</button>
              )}
            </>
          ) : (
            <span className="topbar-title">AI Worker</span>
          )}
          <button className="btn btn-ghost" style={{marginLeft: selectedAgent ? 8 : 'auto', fontSize:12}}
            onClick={() => setPage('notebooks')}>📓 筆記本</button>
        </div>

        {/* Content */}
        <div className="content">
          {page === 'notebooks' ? (
            <NotebooksPage notebooks={notebooks} onRefresh={load} />
          ) : showForm === 'new' ? (
            <AgentForm
              agent={null} departments={departments} allAgents={agents}
              notebooks={notebooks} allTools={allTools}
              onSave={saveAgent} onCancel={() => setShowForm(false)}
              onDelete={deleteAgent}
            />
          ) : !selectedAgent ? (
            <div className="dashboard">
              <div className="dash-title">👋 歡迎使用 AI Worker</div>
              <div className="dash-sub">選擇左側員工開始工作，或新增員工。台股 API 已發包就緒。</div>
              <div className="overview-grid">
                <div className="stat-card"><div className="stat-num">{agents.length}</div><div className="stat-label">AI 員工</div></div>
                <div className="stat-card"><div className="stat-num">{departments.length}</div><div className="stat-label">部門</div></div>
                <div className="stat-card"><div className="stat-num">{notebooks.length}</div><div className="stat-label">筆記本</div></div>
              </div>
              <div style={{marginTop:24}}>
                <div className="form-label" style={{marginBottom:12}}>台股工具（已發包 tw-stock-qa.pages.dev）</div>
                <div className="tools-grid">
                  {allTools.map(t => (
                    <div key={t.name} className="tool-chip on" title={t.description}>
                      {TOOL_ICONS[t.name] || '🔧'} {t.name.replace(/_/g,' ')}
                    </div>
                  ))}
                </div>
              </div>
            </div>
          ) : (
            <>
              {tab === 'overview' && <OverviewTab agent={selectedAgent} departments={departments} />}
              {tab === 'settings' && (
                <AgentForm agent={selectedAgent} departments={departments} allAgents={agents}
                  notebooks={notebooks} allTools={allTools}
                  onSave={saveAgent} onCancel={() => setTab('overview')}
                  onDelete={deleteAgent} />
              )}
              {tab === 'run' && (
                <RunPanel agentId={selectedId} agentName={selectedAgent.name} onRunComplete={load} />
              )}
              {tab === 'runs' && <RunsHistory agentId={selectedId} />}
            </>
          )}
        </div>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
