import { useState, useEffect } from 'react';
import { api, getProjectId } from '../api';
import { useStore } from '../store';

// ── 类型定义（对齐后端 checkpoints 表） ──

interface Checkpoint {
  id: string;
  task_id: string;
  type: 'verify' | 'decision' | 'action';
  title: string;
  description: string | null;
  status: 'pending' | 'approved' | 'rejected';
  payload: string;  // JSON string
  created_at: string;
  resolved_at: string | null;
  resolved_by: string | null;
  resolve_note: string | null;
}

// payload 结构
type VerifyPayload = {
  version: 1;
  auto_checks?: { label: string; passed: boolean }[];
  human_steps?: string[];
  preview_url?: string;
};

type DecisionPayload = {
  version: 1;
  options: { id: string; label: string; desc?: string; pros?: string[]; cons?: string[]; recommended?: boolean }[];
};

type ActionPayload = {
  version: 1;
  steps: { id: string; desc: string; command?: string }[];
  verify_command?: string;
};

const AGENT_EMOJI: Record<string, string> = {
  'pangtong-fujunshi': '🐦', 'simayi-challenger': '🦅', 'jiangwei-infra': '🔧',
  'guanyu-dev': '⚔️', 'zhangfei-dev': '💪', 'zhaoyun-data': '📊',
};

// ── Decision Checkpoint ──

function DecisionCheckpoint({
  taskId, cp, onDone,
}: { taskId: string; cp: Checkpoint; onDone: () => void }) {
  const payload: DecisionPayload = JSON.parse(cp.payload || '{}');
  const [selected, setSelected] = useState<string | null>(null);
  const [note, setNote] = useState('');
  const [loading, setLoading] = useState(false);
  const toast = useStore((s) => s.toast);

  const handleSubmit = async () => {
    if (!selected) return;
    setLoading(true);
    try {
      const res = await fetch(`/api/projects/${getProjectId()}/tasks/${taskId}/checkpoints/${cp.id}/approve`, {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ resolved_by: 'user', note: `选择: ${selected}${note ? '\n' + note : ''}` }),
      });
      const r = await res.json();
      if (r.ok) { toast('✅ 已御批', 'ok'); onDone(); }
      else toast(r.error || '操作失败', 'err');
    } catch { toast('服务器连接失败', 'err'); }
    setLoading(false);
  };

  return (
    <div>
      {cp.description && (
        <div style={{ fontSize: 13, color: 'var(--muted)', lineHeight: 1.6, marginBottom: 14, padding: 12, background: 'var(--panel2)', borderRadius: 8 }}>
          {cp.description}
        </div>
      )}
      <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--muted)', marginBottom: 8 }}>📋 备选方案</div>
      <div style={{ display: 'flex', gap: 8, marginBottom: 14, flexWrap: 'wrap' }}>
        {(payload.options || []).map((opt) => (
          <div key={opt.id}
            onClick={() => setSelected(opt.id)}
            style={{
              flex: '1 1 180px', padding: 14, borderRadius: 10, cursor: 'pointer',
              border: `2px solid ${selected === opt.id ? 'var(--acc)' : 'var(--line)'}`,
              background: selected === opt.id ? 'rgba(201,162,39,0.08)' : 'var(--panel)',
              transition: 'all 0.15s',
            }}>
            {opt.recommended && (
              <div style={{ float: 'right', background: '#22c55e', color: '#fff', fontSize: 10, fontWeight: 700, padding: '1px 6px', borderRadius: 3 }}>荐</div>
            )}
            <div style={{ fontSize: 13, fontWeight: 700, marginBottom: 4 }}>{opt.label}</div>
            {opt.desc && <div style={{ fontSize: 11, color: 'var(--muted)', marginBottom: 6 }}>{opt.desc}</div>}
            {opt.pros?.map((p, i) => <div key={i} style={{ fontSize: 11, color: '#22c55e' }}>👍 {p}</div>)}
            {opt.cons?.map((c, i) => <div key={i} style={{ fontSize: 11, color: '#ef4444' }}>👎 {c}</div>)}
          </div>
        ))}
      </div>
      <div style={{ marginBottom: 14 }}>
        <div style={{ fontSize: 11, color: 'var(--muted)', marginBottom: 4 }}>📝 御批备注（可选）</div>
        <textarea style={{ width: '100%', height: 48, background: 'var(--panel2)', border: '1px solid var(--line)', borderRadius: 6, padding: 8, color: 'var(--fg)', fontSize: 12 }}
          value={note} onChange={(e) => setNote(e.target.value)} placeholder="记录决策理由..." />
      </div>
      <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
        <button disabled={!selected || loading} onClick={handleSubmit} style={{ padding: '6px 16px', borderRadius: 6, border: 'none', background: selected ? '#4a90d9' : '#555', color: '#fff', cursor: selected ? 'pointer' : 'not-allowed', fontSize: 13, fontWeight: 600 }}>
          🎯 依此方案施行
        </button>
      </div>
    </div>
  );
}

// ── Verify Checkpoint ──

function VerifyCheckpoint({
  taskId, cp, onDone,
}: { taskId: string; cp: Checkpoint; onDone: () => void }) {
  const payload: VerifyPayload = JSON.parse(cp.payload || '{}');
  const [reason, setReason] = useState('');
  const [showReject, setShowReject] = useState(false);
  const [loading, setLoading] = useState(false);
  const toast = useStore((s) => s.toast);

  const handleAction = async (action: string) => {
    if (action === 'reject' && !showReject) { setShowReject(true); return; }
    setLoading(true);
    try {
      const res = await fetch(`/api/projects/${getProjectId()}/tasks/${taskId}/checkpoints/${cp.id}/${action}`, {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ resolved_by: 'user', note: reason }),
      });
      const r = await res.json();
      if (r.ok) { toast(action === 'approve' ? '✅ 已御批' : '❌ 已驳回', 'ok'); onDone(); }
      else toast(r.error || '操作失败', 'err');
    } catch { toast('服务器连接失败', 'err'); }
    setLoading(false);
  };

  return (
    <div>
      <div style={{ fontSize: 13, color: 'var(--muted)', lineHeight: 1.6, marginBottom: 12, padding: 12, background: 'var(--panel2)', borderRadius: 8 }}>
        {cp.description}
      </div>
      {/* 自动核验 */}
      {payload.auto_checks?.length ? (
        <div style={{ marginBottom: 12 }}>
          <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--muted)', marginBottom: 6 }}>自动核验结果</div>
          <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
            {payload.auto_checks.map((r, i) => (
              <span key={i} style={{ fontSize: 11, padding: '3px 10px', borderRadius: 4, background: r.passed ? '#22c55e22' : '#ef444422', color: r.passed ? '#22c55e' : '#ef4444' }}>
                {r.passed ? '✅' : '❌'} {r.label}
              </span>
            ))}
          </div>
        </div>
      ) : null}
      {/* 人工核验步骤 */}
      {payload.human_steps?.length ? (
        <div style={{ marginBottom: 12 }}>
          <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--muted)', marginBottom: 6 }}>人工核验步骤</div>
          <div style={{ fontSize: 12, lineHeight: 1.8, paddingLeft: 16, borderLeft: '2px solid var(--line)' }}>
            {payload.human_steps.map((s, i) => <div key={i}>{i + 1}. {s}</div>)}
          </div>
        </div>
      ) : null}
      {/* 预览链接 */}
      {payload.preview_url && (
        <div style={{ marginBottom: 12 }}>
          <a href={payload.preview_url} target="_blank" rel="noreferrer" style={{ fontSize: 11, color: 'var(--acc)' }}>🔗 预览产出</a>
        </div>
      )}
      {/* 驳回输入 */}
      {showReject && (
        <div style={{ marginBottom: 12 }}>
          <div style={{ fontSize: 11, color: 'var(--muted)', marginBottom: 4 }}>驳回缘由</div>
          <textarea style={{ width: '100%', height: 60, background: 'var(--panel2)', border: '1px solid var(--line)', borderRadius: 6, padding: 8, color: 'var(--fg)', fontSize: 12 }}
            value={reason} onChange={(e) => setReason(e.target.value)} placeholder="请说明驳回原因..." />
        </div>
      )}
      <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
        <button style={{ padding: '5px 12px', borderRadius: 6, fontSize: 11, cursor: 'pointer', background: '#ef444422', color: '#ef4444', border: '1px solid #ef444444', fontWeight: 600 }} onClick={() => handleAction('reject')} disabled={loading}>
          ❌ 驳回另议
        </button>
        <button style={{ padding: '5px 12px', borderRadius: 6, fontSize: 11, cursor: 'pointer', background: '#22c55e22', color: '#22c55e', border: '1px solid #22c55e44', fontWeight: 600 }} onClick={() => handleAction('approve')} disabled={loading}>
          ✅ 御批依准施行
        </button>
      </div>
    </div>
  );
}

// ── Action Checkpoint ──

function ActionCheckpoint({
  taskId, cp, onDone,
}: { taskId: string; cp: Checkpoint; onDone: () => void }) {
  const payload: ActionPayload = JSON.parse(cp.payload || '{}');
  const steps = payload.steps || [];
  const [completedSteps, setCompletedSteps] = useState<Set<string>>(new Set());
  const [note, setNote] = useState('');
  const [loading, setLoading] = useState(false);
  const toast = useStore((s) => s.toast);

  const toggleStep = (id: string) => {
    setCompletedSteps((prev) => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  };

  const allDone = completedSteps.size >= steps.length;

  const handleSubmit = async () => {
    if (!allDone) return;
    setLoading(true);
    try {
      const res = await fetch(`/api/projects/${getProjectId()}/tasks/${taskId}/checkpoints/${cp.id}/approve`, {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ resolved_by: 'user', note }),
      });
      const r = await res.json();
      if (r.ok) { toast('✅ 已确认', 'ok'); onDone(); }
      else toast(r.error || '操作失败', 'err');
    } catch { toast('服务器连接失败', 'err'); }
    setLoading(false);
  };

  return (
    <div>
      <div style={{ fontSize: 13, color: 'var(--muted)', lineHeight: 1.6, marginBottom: 12, padding: 12, background: 'var(--panel2)', borderRadius: 8 }}>
        {cp.description}
      </div>
      {/* 进度条 */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 14 }}>
        <div style={{ flex: 1, background: 'var(--panel2)', borderRadius: 4, height: 6, overflow: 'hidden' }}>
          <div style={{ height: '100%', borderRadius: 4, background: '#f59e0b', transition: 'width 0.3s', width: `${steps.length ? (completedSteps.size / steps.length * 100) : 0}%` }} />
        </div>
        <span style={{ fontSize: 11, color: 'var(--muted)' }}>{completedSteps.size}/{steps.length} 步骤</span>
      </div>
      {/* 步骤列表 */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginBottom: 14 }}>
        {steps.map((s) => (
          <div key={s.id} onClick={() => toggleStep(s.id)} style={{ display: 'flex', alignItems: 'flex-start', gap: 10, padding: 10, background: 'var(--panel2)', borderRadius: 8, cursor: 'pointer' }}>
            <div style={{
              width: 20, height: 20, borderRadius: 4, border: `2px solid ${completedSteps.has(s.id) ? '#22c55e' : 'var(--line)'}`,
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontSize: 12, flexShrink: 0,
              background: completedSteps.has(s.id) ? '#22c55e' : 'transparent', color: '#fff',
            }}>{completedSteps.has(s.id) ? '✓' : ''}</div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 12, fontWeight: 600, textDecoration: completedSteps.has(s.id) ? 'line-through' : 'none' }}>{s.desc}</div>
              {s.command && (
                <pre style={{ marginTop: 4, fontSize: 11, padding: '4px 8px', background: '#0d1117', borderRadius: 4, color: '#e6edf3', fontFamily: 'monospace' }}>{s.command}</pre>
              )}
            </div>
          </div>
        ))}
      </div>
      {/* 验证命令 */}
      {payload.verify_command && (
        <div style={{ marginBottom: 14 }}>
          <div style={{ fontSize: 11, color: 'var(--muted)', marginBottom: 4 }}>验证命令</div>
          <pre style={{ fontSize: 11, padding: '6px 10px', background: '#0d1117', borderRadius: 6, color: '#e6edf3', fontFamily: 'monospace' }}>{payload.verify_command}</pre>
        </div>
      )}
      {/* 验证说明 */}
      <div style={{ marginBottom: 14 }}>
        <div style={{ fontSize: 11, color: 'var(--muted)', marginBottom: 4 }}>验证结果说明</div>
        <input style={{ width: '100%', background: 'var(--panel2)', border: '1px solid var(--line)', borderRadius: 6, padding: '6px 10px', color: 'var(--fg)', fontSize: 12 }}
          value={note} onChange={(e) => setNote(e.target.value)} placeholder="如：返回 200 OK，服务正常运行" />
      </div>
      <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
        <button className="btn-primary" disabled={!allDone || loading} onClick={handleSubmit} title={allDone ? '' : '请完成所有步骤后提交'}>
          ✅ 臣已办妥，继续执行
        </button>
      </div>
    </div>
  );
}

// ── 主面板 ──

export default function CheckpointPanel({
  taskId,
  onDone,
}: {
  taskId: string;
  onDone: () => void;
}) {
  const [checkpoints, setCheckpoints] = useState<Checkpoint[]>([]);
  const [pendingIdx, setPendingIdx] = useState(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const pid = getProjectId();
    if (!pid) { setLoading(false); return; }
    setLoading(true);
    setError(null);
    fetch(`/api/projects/${pid}/tasks/${taskId}/checkpoints`)
      .then(r => r.json())
      .then(d => { setCheckpoints(d.checkpoints || []); setLoading(false); })
      .catch(() => { setError('加载失败'); setLoading(false); });
  }, [taskId]);

  if (loading) return <div style={{ fontSize: 12, color: 'var(--muted)', textAlign: 'center', padding: 20 }}>加载中...</div>;
  if (error) return (
    <div style={{ fontSize: 12, color: '#ef4444', textAlign: 'center', padding: 20 }}>
      <div>{error}</div>
      <button onClick={() => { setCheckpoints([]); setLoading(true); }} style={{ marginTop: 8, fontSize: 11, padding: '4px 12px', borderRadius: 4, border: '1px solid var(--line)', background: 'transparent', color: 'var(--fg)', cursor: 'pointer' }}>重试</button>
    </div>
  );

  // 只显示 pending 的（BUG-34: 直接基于 pendingCps 管理索引）
  const pendingCps = checkpoints.filter(c => c.status === 'pending');
  if (pendingCps.length === 0) return <div style={{ fontSize: 12, color: 'var(--muted)', textAlign: 'center', padding: 20 }}>所有 Checkpoint 已处理</div>;

  const activeCp = pendingCps[pendingIdx] || pendingCps[0];
  const activeIdx = pendingCps.indexOf(activeCp);

  const typeIcon = activeCp.type === 'verify' ? '🔍' : activeCp.type === 'decision' ? '🎯' : '🔧';
  const typeColor = activeCp.type === 'verify' ? '#6a9eff' : activeCp.type === 'decision' ? '#818cf8' : '#f59e0b';
  const typeLabel = activeCp.type === 'verify' ? '验证 Checkpoint' : activeCp.type === 'decision' ? '决策 Checkpoint' : '执行 Checkpoint';

  return (
    <div>
      {/* 多 checkpoint Tab */}
      {pendingCps.length > 1 && (
        <div style={{ display: 'flex', borderBottom: '1px solid var(--line)', marginBottom: 12 }}>
          {pendingCps.map((c, i) => (
            <button key={c.id}
              onClick={() => setPendingIdx(i)}
              style={{ fontSize: 12, padding: '6px 12px', border: 'none', background: 'transparent', cursor: 'pointer',
                color: i === activeIdx ? typeColor : 'var(--muted)', borderBottom: `2px solid ${i === activeIdx ? typeColor : 'transparent'}` }}
            >{typeIcon} {c.title}</button>
          ))}
        </div>
      )}

      {/* 类型头部 */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12 }}>
        <div style={{ width: 36, height: 36, borderRadius: '50%', background: `${typeColor}22`, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 16 }}>{typeIcon}</div>
        <div>
          <div style={{ fontSize: 14, fontWeight: 700, color: typeColor }}>{typeLabel}</div>
        </div>
      </div>

      {/* 标题 */}
      <div style={{ fontSize: 15, fontWeight: 700, marginBottom: 6 }}>{activeCp.title}</div>

      {/* 按类型渲染 */}
      {activeCp.type === 'verify' && <VerifyCheckpoint taskId={taskId} cp={activeCp} onDone={onDone} />}
      {activeCp.type === 'decision' && <DecisionCheckpoint taskId={taskId} cp={activeCp} onDone={onDone} />}
      {activeCp.type === 'action' && <ActionCheckpoint taskId={taskId} cp={activeCp} onDone={onDone} />}
    </div>
  );
}
