'use client';

// Mira repo 總管 + 工作台
// SDD: polaris/mira/.agents/specs/mira-app/design.md §3.9.1.2 + §5.2 v2.1
// 對應 task: 階段 10-B
// GitHub = repo 全清單 SSOT；clone 到 Hetzner = 激活進工作態
// 資料源：mira daemon GET /projects（轉發 AI-Meka GitHub 掃描器）

import { useEffect, useMemo, useState } from 'react';
import '../mira.css';

// mira daemon（nginx mira.uncle6.me/mira/ → 容器）
const DAEMON = process.env.NEXT_PUBLIC_MIRA_DAEMON ?? 'https://mira.uncle6.me/mira';
const API_BASE = process.env.NEXT_PUBLIC_API_BASE ?? 'https://cypher.arcrun.dev';
const KBDB_BASE = 'https://kbdb.finally.click'; // 既有技術債（同 feed/wiki），KI-3 未解前沿用

export type RepoSummary = {
  name: string;
  full_name: string;
  cloned: boolean;
  has_sdd: boolean;
  archived: boolean;
  fork: boolean;
  total: number;
  done: number;
  in_progress: number;
  ai_count: number;
  leo_count: number;
  blocked_count: number;
  last_activity: string | null;
};

// project_detector 拆出的 todo block（type=note, source=ai-project-detector）
// G1：一篇河道筆記可拆多條 todo，各自掛 suggested-repo（design.md §3.7.5.7）
type Todo = {
  id: string;
  content: string;
  suggested_repo: string; // repo name 或 "new"
  raw_id: string;         // 溯源回河道原 raw（raw: tag），給「來自河道」連結
};

type Filter = 'sdd' | 'all';

// 從 tags_json 解析 detector 打的 tag
function parseTodoTags(tagsJson: string | null): { isTodo: boolean; repo: string; rawId: string } {
  let tags: string[] = [];
  try { tags = JSON.parse(tagsJson || '[]'); } catch { /* */ }
  const isTodo = tags.includes('is_todo:true');
  const repoTag = tags.find(t => t.startsWith('suggested-repo:'));
  const repo = repoTag ? repoTag.slice('suggested-repo:'.length) : '';
  const rawTag = tags.find(t => t.startsWith('raw:'));
  const rawId = rawTag ? rawTag.slice('raw:'.length) : '';
  return { isTodo, repo, rawId };
}

export default function ProjectsPage() {
  const [repos, setRepos] = useState<RepoSummary[] | null>(null);
  const [todos, setTodos] = useState<Todo[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [filter, setFilter] = useState<Filter>('sdd');
  const [cloning, setCloning] = useState<string | null>(null);
  const [newRepo, setNewRepo] = useState('');

  const load = () => {
    setError(null);
    fetch(`${DAEMON}/projects`)
      .then(async r => {
        if (!r.ok) throw new Error(`daemon 回 ${r.status}`);
        return r.json() as Promise<{ repos: RepoSummary[] }>;
      })
      .then(d => setRepos(d.repos ?? []))
      .catch(e => setError(e instanceof Error ? e.message : String(e)));
    void loadTodos();
  };

  // 撈 project_detector 拆出的 todo block（source=ai-project-detector，G1 一篇拆多條）
  // client 過濾 is_todo:true（KI-3 tag query bug 故用 source filter 而非 tag query）
  const loadTodos = async () => {
    try {
      const me = await fetch(`${API_BASE}/me`, { credentials: 'include' }).then(r => r.ok ? r.json() : null);
      if (!me?.api_key) return;
      const res = await fetch(`${KBDB_BASE}/blocks?type=note&source=ai-project-detector&limit=300`, {
        headers: { Authorization: `Bearer ${me.api_key}` },
      });
      if (!res.ok) return;
      const data = await res.json() as { blocks?: Array<{ id: string; content: string; tags_json: string | null }> };
      const list: Todo[] = [];
      for (const b of data.blocks ?? []) {
        const { isTodo, repo, rawId } = parseTodoTags(b.tags_json);
        if (isTodo) list.push({ id: b.id, content: b.content, suggested_repo: repo || 'new', raw_id: rawId });
      }
      setTodos(list);
    } catch { /* todos best-effort */ }
  };

  useEffect(load, []);

  const clone = async (fullName: string) => {
    setCloning(fullName);
    setError(null);
    try {
      const r = await fetch(`${DAEMON}/projects/clone`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ repo: fullName }),
      });
      if (!r.ok) throw new Error(`clone 失敗 ${r.status}`);
      setNewRepo('');
      load();
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setCloning(null);
    }
  };

  const addRepo = () => {
    const v = newRepo.trim();
    if (!v) return;
    // 允許輸入 "name" 或 "owner/name"
    const full = v.includes('/') ? v : `richblack/${v}`;
    clone(full);
  };

  const shown = useMemo(() => {
    if (!repos) return [];
    const arr = repos.filter(r => {
      if (filter === 'sdd') return r.has_sdd;
      return true;
    });
    // 有進度等你處理的優先，其次已 clone，其次最近活動
    arr.sort((a, b) =>
      b.leo_count - a.leo_count ||
      Number(b.cloned) - Number(a.cloned) ||
      (b.last_activity ?? '').localeCompare(a.last_activity ?? ''),
    );
    return arr;
  }, [repos, filter]);

  // 待辦按 suggested_repo 分組（outliner：Repo 父 → todo 子）
  const todosByRepo = useMemo(() => {
    const m = new Map<string, Todo[]>();
    for (const t of todos) {
      const key = t.suggested_repo || 'new';
      if (!m.has(key)) m.set(key, []);
      m.get(key)!.push(t);
    }
    return m;
  }, [todos]);

  const newTodos = todosByRepo.get('new') ?? [];

  return (
    <main className="mira-page">
      <div className="mira-content">
        <header className="mira-proj-header">
          <h1 className="mira-proj-title">📋 專案總管</h1>
          <p className="mira-proj-sub">已 clone 到工作台的 repo · 🤖 Mira 做 / 👤 等你</p>
          <div className="mira-proj-controls">
            <div className="mira-proj-sort">
              {([['sdd', '有進度'], ['all', '全部']] as [Filter, string][]).map(([k, label]) => (
                <button
                  key={k}
                  className={`mira-proj-sort-btn${filter === k ? ' is-active' : ''}`}
                  onClick={() => setFilter(k)}
                >
                  {label}
                </button>
              ))}
            </div>
            <div className="mira-proj-add">
              <input
                className="mira-proj-add-input"
                placeholder="加 repo：name 或 owner/name"
                value={newRepo}
                onChange={e => setNewRepo(e.target.value)}
                onKeyDown={e => { if (e.key === 'Enter') addRepo(); }}
              />
              <button className="mira-proj-add-btn" onClick={addRepo} disabled={!!cloning || !newRepo.trim()}>
                {cloning ? 'clone 中…' : '↓ clone'}
              </button>
            </div>
          </div>
        </header>

        {error && (
          <div className="mira-card mira-proj-error">
            <strong>讀取 repo 清單失敗：</strong>{error}
            <div className="mira-proj-error-hint">
              掃描器在 mira daemon（{DAEMON}/projects）。確認 daemon 已部署掃描 endpoint（階段 10-A）。
            </div>
          </div>
        )}

        {!error && repos === null && <div className="mira-proj-loading">載入中…</div>}
        {!error && repos?.length === 0 && (
          <div className="mira-card mira-proj-empty">GitHub 沒掃到任何 repo。</div>
        )}

        <div className="mira-proj-grid">
          {shown.map(r => (
            <RepoCard
              key={r.full_name}
              r={r}
              cloning={cloning === r.full_name}
              onClone={() => clone(r.full_name)}
              todos={todosByRepo.get(r.name) ?? []}
            />
          ))}
        </div>

        {newTodos.length > 0 && (
          <div className="mira-card mira-proj-new-group">
            <div className="mira-proj-new-title">💡 建議新建專案（{newTodos.length}）</div>
            <ul className="mira-proj-todo-list">
              {newTodos.map(t => (
                <li key={t.id} className="mira-proj-todo-item">
                  <span className="mira-proj-todo-dot">·</span> {t.content}
                  {t.raw_id && (
                    <a className="mira-proj-todo-src" href={`/mira/feed#raw=${t.raw_id}`}>來自河道 ↗</a>
                  )}
                </li>
              ))}
            </ul>
          </div>
        )}
      </div>
    </main>
  );
}

function pct(r: RepoSummary): number {
  return r.total === 0 ? 0 : Math.round((r.done / r.total) * 100);
}

function relTime(iso: string | null): string {
  if (!iso) return '—';
  const t = new Date(iso).getTime();
  if (Number.isNaN(t)) return '—';
  const days = Math.floor((Date.now() - t) / 86400000);
  if (days <= 0) return '今天';
  if (days === 1) return '昨天';
  if (days < 30) return `${days} 天前`;
  return `${Math.floor(days / 30)} 個月前`;
}

function RepoCard({ r, cloning, onClone, todos }: { r: RepoSummary; cloning: boolean; onClone: () => void; todos: Todo[] }) {
  const percent = pct(r);
  return (
    <div className="mira-card mira-proj-card">
      <div className="mira-proj-card-top">
        <span className="mira-proj-name">
          {r.name}
          {r.fork && <span className="mira-proj-tag">fork</span>}
          {r.archived && <span className="mira-proj-tag">archived</span>}
        </span>
        <span className="mira-proj-time mira-en">{relTime(r.last_activity)}</span>
      </div>
      <div className="mira-proj-path mira-en">{r.full_name}</div>

      {/* 河道偵測到、建議整進此專案的待辦（outliner 子項）*/}
      {todos.length > 0 && (
        <ul className="mira-proj-todo-list">
          {todos.map(t => (
            <li key={t.id} className="mira-proj-todo-item">
              <span className="mira-proj-todo-dot">·</span> {t.content}
              {t.raw_id && (
                <a className="mira-proj-todo-src" href={`/mira/feed#raw=${t.raw_id}`}>來自河道 ↗</a>
              )}
            </li>
          ))}
        </ul>
      )}

      {!r.cloned ? (
        <div className="mira-proj-uncloned">
          <span className="mira-proj-uncloned-hint">尚未 clone 到 Hetzner</span>
          <button className="mira-proj-clone-btn" onClick={onClone} disabled={cloning}>
            {cloning ? 'clone 中…' : '↓ clone 進工作態'}
          </button>
        </div>
      ) : !r.has_sdd ? (
        <div className="mira-proj-nosdd">已 clone · 無 SDD 進度追蹤（無 .agents/specs）</div>
      ) : (
        <>
          <div className="mira-proj-bar">
            <div className="mira-proj-bar-fill" style={{ width: `${percent}%` }} />
          </div>
          <div className="mira-proj-stats">
            <span className="mira-proj-pct mira-en">{percent}%</span>
            <span className="mira-en">{r.done}/{r.total}</span>
            {r.leo_count > 0 && <span className="mira-proj-chip mira-chip-leo">👤 {r.leo_count} 等你</span>}
            {r.ai_count > 0 && <span className="mira-proj-chip mira-chip-ai">🤖 {r.ai_count} Mira</span>}
            {r.blocked_count > 0 && <span className="mira-proj-chip mira-chip-blocked">⛔ {r.blocked_count}</span>}
          </div>
        </>
      )}
    </div>
  );
}
