'use client';

import { useEffect, useRef, useState } from 'react';
import { Sparkles, Loader2, AlertCircle, RotateCw } from 'lucide-react';
import type { VersionPlan } from '@/lib/version-plan';
import type { VersionWithContext } from '@/lib/derive';
import { useVersionPlanStore } from '@/stores/useVersionPlanStore';
import { useRequirementStore } from '@/stores/useRequirementStore';
import { useAuthStore } from '@/stores/useAuthStore';
import { useDevTaskStore } from '@/stores/useDevTaskStore';
import { useTestCaseStore } from '@/stores/useTestCaseStore';
import { useTaskCategoryStore } from '@/stores/useTaskCategoryStore';
import { api } from '@/lib/api';
import { filterDuplicateDecomposeDrafts } from '@/lib/ai-decompose-dedupe';
import { DecomposeReportModal } from './DecomposeReportModal';
import type {
  AgentDecomposeTarget,
  AgentDecomposeRequest,
  AgentDecomposeResponse,
  AgentDecomposeError,
} from '@ftb/shared';

interface Props {
  plan: VersionPlan;
  version: VersionWithContext;
}

/** in_progress 视为"卡死"的阈值（秒）— 超过这个时间，按钮允许重新点击 */
const STUCK_THRESHOLD_SEC = 240;

function formatElapsed(sec: number): string {
  if (sec < 60) return `${sec}s`;
  const m = Math.floor(sec / 60);
  const s = sec % 60;
  return `${m}m${s}s`;
}

export function AiDecomposeButton({ plan, version }: Props) {
  const { updatePlan } = useVersionPlanStore();
  const { requirements } = useRequirementStore();
  const devTasks = useDevTaskStore((s) => s.tasks);
  const testCases = useTestCaseStore((s) => s.testCases);
  const categories = useTaskCategoryStore((s) => s.categories);
  const user = useAuthStore((s) => s.user);

  const [activeTarget, setActiveTarget] = useState<AgentDecomposeTarget | null>(null);
  const [result, setResult] = useState<AgentDecomposeResponse | null>(null);
  const [resultTarget, setResultTarget] = useState<AgentDecomposeTarget>('all');
  const [dedupeSummary, setDedupeSummary] = useState({ removedDevTaskCount: 0, removedTestCaseCount: 0 });
  const [tick, setTick] = useState(0);
  const startedAtRef = useRef<number | null>(null);
  const loading = activeTarget !== null;

  // plan 上的状态（持久化在 localStorage）
  const persistStatus = plan.aiDecomposeStatus;
  const persistError = plan.aiDecomposeError;
  const persistAt = plan.aiDecomposeAt;

  // 计算"已用时"
  const elapsedSec = (() => {
    if (loading && startedAtRef.current) {
      return Math.floor((tick - startedAtRef.current) / 1000);
    }
    if (persistStatus === 'in_progress' && persistAt) {
      const start = new Date(persistAt).getTime();
      return Math.max(0, Math.floor((Date.now() - start) / 1000));
    }
    return 0;
  })();

  const isStaleInProgress = persistStatus === 'in_progress' && elapsedSec > STUCK_THRESHOLD_SEC;
  const isInProgress = (loading || persistStatus === 'in_progress') && !isStaleInProgress;
  const isError = persistStatus === 'error' && !loading;
  const wasCompleted = persistStatus === 'completed' && !loading;

  // tick 每秒更新一次，让"已用时"实时跳
  useEffect(() => {
    if (!isInProgress) return;
    const id = setInterval(() => setTick(Date.now()), 1000);
    return () => clearInterval(id);
  }, [isInProgress]);

  const linkedReqs = requirements
    .filter((r) => r.versionId === version.id)
    .map((r) => ({
      id: r.id,
      code: r.code,
      title: r.title,
      description: r.description,
    }));

  const targetText = (target: AgentDecomposeTarget) => {
    if (target === 'dev_tasks') return '开发任务';
    if (target === 'test_cases') return '测试用例';
    return '任务和用例';
  };

  const handleClick = async (target: AgentDecomposeTarget) => {
    if (loading) return;
    // 即便 persistStatus 是 in_progress，只要超过阈值就允许重新点
    if (persistStatus === 'in_progress' && !isStaleInProgress) return;

    startedAtRef.current = Date.now();
    setTick(Date.now());
    setActiveTarget(target);

    updatePlan(plan.id, {
      aiDecomposeStatus: 'in_progress',
      aiDecomposeBy: user?.name,
      aiDecomposeAt: new Date().toISOString(),
      aiDecomposeError: undefined,
    });

    const members = (version.members ?? []).map((m) => ({
      name: m.name,
      role: m.role,
    }));

    const payload: AgentDecomposeRequest = {
      prototypeUrl: plan.resultUrl || '',
      requirements: linkedReqs,
      members,
      versionId: version.id,
      planId: plan.id,
      target,
    };

    try {
      const resp = await api.postRaw<AgentDecomposeResponse | AgentDecomposeError>(
        '/ai/decompose',
        payload,
        300000,
      );
      if (!resp.ok) {
        updatePlan(plan.id, {
          aiDecomposeStatus: 'error',
          aiDecomposeError: resp.error,
        });
      } else {
        const requirementIdSet = new Set(linkedReqs.map((req) => req.id));
        const deduped = filterDuplicateDecomposeDrafts(resp.result, {
          existingDevTasks: devTasks.filter((task) => requirementIdSet.has(task.requirementId)),
          existingTestCases: testCases.filter((testCase) => testCase.versionId === version.id),
          categories,
          requirements: linkedReqs,
        });
        setResult({ ...resp, result: deduped.result });
        setDedupeSummary({
          removedDevTaskCount: deduped.removedDevTaskCount,
          removedTestCaseCount: deduped.removedTestCaseCount,
        });
        setResultTarget(target);
        updatePlan(plan.id, {
          aiDecomposeStatus: 'completed',
          aiDecomposeError: undefined,
        });
      }
    } catch (e: any) {
      const msg = e?.message || '调用 AI 服务失败';
      updatePlan(plan.id, {
        aiDecomposeStatus: 'error',
        aiDecomposeError: msg,
      });
    } finally {
      setActiveTarget(null);
      startedAtRef.current = null;
    }
  };

  if (plan.type !== 'product' || plan.status !== 'completed' || !plan.resultUrl) {
    return null;
  }

  return (
    <>
      <span className="inline-flex items-center gap-1.5">
        {(['dev_tasks', 'test_cases'] as AgentDecomposeTarget[]).map((target) => {
          const showSpinner = isInProgress && (!activeTarget || activeTarget === target);
          const label = wasCompleted ? `重新拆解${targetText(target)}` : `AI 拆解${targetText(target)}`;
          return (
            <button
              key={target}
              onClick={() => handleClick(target)}
              disabled={isInProgress}
              className={`inline-flex items-center gap-1 rounded-md border px-2 py-1 text-[11px] font-medium disabled:cursor-not-allowed disabled:opacity-70 ${
                isError
                  ? 'border-red-200 bg-red-50 text-red-700 hover:bg-red-100'
                  : 'border-purple-200 bg-purple-50 text-purple-700 hover:bg-purple-100'
              }`}
              title={
                isError
                  ? `上次失败：${persistError || '未知错误'}（点击重试${targetText(target)}）`
                  : wasCompleted
                    ? `此前已拆解过，再次点击会重新拆解${targetText(target)}`
                    : `使用 AI 把原型 + 关联需求拆解成${targetText(target)}`
              }
            >
              {showSpinner ? (
                <>
                  <Loader2 className="h-3 w-3 animate-spin" />
                  拆解中 {formatElapsed(elapsedSec)}
                </>
              ) : isError ? (
                <>
                  <RotateCw className="h-3 w-3" />
                  重试{targetText(target)}
                </>
              ) : (
                <>
                  <Sparkles className="h-3 w-3" />
                  {label}
                </>
              )}
            </button>
          );
        })}
      </span>

      {/* 错误信息：在按钮旁悬浮显示 */}
      {isError && persistError && (
        <span className="ml-1 inline-flex items-center gap-1 text-[11px] text-red-600 max-w-[260px]" title={persistError}>
          <AlertCircle className="h-3 w-3 shrink-0" />
          <span className="truncate">{persistError}</span>
        </span>
      )}

      {/* 卡死提示：persistStatus 是 in_progress 但已超时 */}
      {isStaleInProgress && (
        <span className="ml-1 text-[11px] text-amber-600" title="上次拆解记录残留，点击按钮重新拆解">
          上次未完成（{formatElapsed(elapsedSec)}）
        </span>
      )}

      {result && (
        <DecomposeReportModal
          result={result}
          version={version}
          plan={plan}
          requirements={linkedReqs}
          target={resultTarget}
          dedupeSummary={dedupeSummary}
          onClose={() => setResult(null)}
        />
      )}
    </>
  );
}
