'use client';

import { useEffect, useMemo, useRef, useState } from 'react';
import { useRouter } from 'next/navigation';
import { Layers, ShieldCheck, TriangleAlert } from 'lucide-react';
import { RouteGuard, useHasPermission } from '@/components/auth/Guard';
import { XiaobaoWarningCard } from '@/components/xiaobao-warning/XiaobaoWarningCard';
import { XiaobaoWarningDrawer } from '@/components/xiaobao-warning/XiaobaoWarningDrawer';
import { useAuthStore } from '@/stores/useAuthStore';
import { useBugStore } from '@/stores/useBugStore';
import { useDevTaskStore } from '@/stores/useDevTaskStore';
import { useProductStore } from '@/stores/useProductStore';
import { useRequirementStore } from '@/stores/useRequirementStore';
import { useTaskWorklogStore } from '@/stores/useTaskWorklogStore';
import { useTestCaseStore } from '@/stores/useTestCaseStore';
import { useVersionPlanStore } from '@/stores/useVersionPlanStore';
import { useWorkActivityStore } from '@/stores/useWorkActivityStore';
import { useXiaobaoRiskStore } from '@/stores/useXiaobaoRiskStore';
import { flattenVersions } from '@/lib/derive';
import { calcXiaobaoVersionRisk, type XiaobaoVersionRisk } from '@/lib/xiaobao-risk';
import { buildRiskInsightSignature, findPreviousRiskSnapshot, getReusableInsight, requestRiskInsight, shouldRequestRiskInsightWithCacheGate } from '@/lib/xiaobao-risk-ai';
import { buildVersionDailyEvidence, buildXiaobaoWorkItems } from '@/lib/xiaobao-risk-evidence';
import { buildRiskSignature, findLatestDailySnapshot, shouldSaveRiskSnapshot } from '@/lib/xiaobao-risk-trend';
import { filterXiaobaoWarningVersions, sanitizeRiskInsight } from '@/lib/xiaobao-warning-view';

type RiskFilter = 'all' | 'attention' | 'high';

export default function XiaobaoWarningPage() {
  return (
    <RouteGuard permission="xiaobao.warning:view">
      <XiaobaoWarningContent />
    </RouteGuard>
  );
}

function XiaobaoWarningContent() {
  const router = useRouter();
  const canManage = useHasPermission('xiaobao.warning:manage');
  const user = useAuthStore((s) => s.user);
  const { overview, fetchOverview } = useProductStore();
  const { plans, fetchPlans } = useVersionPlanStore();
  const { requirements, fetchRequirements } = useRequirementStore();
  const { tasks: devTasks, fetchTasks } = useDevTaskStore();
  const { testCases, fetchTestCases } = useTestCaseStore();
  const { bugs, fetchBugs } = useBugStore();
  const { activities, fetchActivities } = useWorkActivityStore();
  const { worklogs, fetchWorklogs } = useTaskWorklogStore();
  const { snapshots, insights, riskDataLoaded, fetchRiskData, saveSnapshot, saveInsight } = useXiaobaoRiskStore();
  const [selectedRiskId, setSelectedRiskId] = useState<string | null>(null);
  const [filter, setFilter] = useState<RiskFilter>('all');
  const [calculationNow] = useState(() => new Date());
  const savedSnapshotKeysRef = useRef(new Set<string>());
  const requestedInsightKeysRef = useRef(new Set<string>());
  const today = useMemo(() => new Date().toISOString().slice(0, 10), []);

  useEffect(() => { fetchOverview(); }, [fetchOverview]);
  useEffect(() => { fetchPlans(); }, [fetchPlans]);
  useEffect(() => { fetchRequirements(); }, [fetchRequirements]);
  useEffect(() => { fetchTasks(); }, [fetchTasks]);
  useEffect(() => { fetchTestCases(); }, [fetchTestCases]);
  useEffect(() => { fetchBugs(); }, [fetchBugs]);
  useEffect(() => { fetchActivities(); }, [fetchActivities]);
  useEffect(() => { fetchWorklogs(); }, [fetchWorklogs]);
  useEffect(() => { fetchRiskData(); }, [fetchRiskData]);

  const allVersions = useMemo(() => flattenVersions(overview), [overview]);
  const visibleVersions = useMemo(
    () => filterXiaobaoWarningVersions(allVersions, { canManage, userName: user?.name }),
    [allVersions, canManage, user?.name],
  );

  const requirementVersionMap = useMemo(() => {
    const map = new Map<string, string>();
    requirements.forEach((requirement) => {
      if (requirement.versionId) map.set(requirement.id, requirement.versionId);
    });
    return map;
  }, [requirements]);

  const workItems = useMemo(() => buildXiaobaoWorkItems({
    plans,
    devTasks,
    testCases,
    bugs,
    versions: allVersions.map((version) => ({
      id: version.id,
      name: version.name,
      productName: version.productName,
      projectName: version.projectName,
    })),
    requirementVersionMap,
  }), [allVersions, bugs, devTasks, plans, requirementVersionMap, testCases]);

  const risks = useMemo(() => visibleVersions.map((version) => {
    const versionRequirements = requirements.filter((requirement) => requirement.versionId === version.id);
    const requirementIds = new Set(versionRequirements.map((requirement) => requirement.id));
    const dailyEvidence = buildVersionDailyEvidence({
      versionId: version.id,
      workItems,
      activities,
      worklogs,
    });

    return calcXiaobaoVersionRisk({
      version,
      devTasks: devTasks.filter((task) => requirementIds.has(task.requirementId)),
      testCases: testCases.filter((testCase) => testCase.versionId === version.id),
      bugs: bugs.filter((bug) => bug.versionId === version.id),
      dailyEvidence,
      recentActivityCount: dailyEvidence.recentActivityCount,
      lastActivityAt: dailyEvidence.lastActivityAt,
      snapshots: snapshots.filter((snapshot) => snapshot.versionId === version.id && snapshot.date < today),
      now: calculationNow,
    });
  }).sort((a, b) => b.riskScore - a.riskScore), [
    activities,
    bugs,
    devTasks,
    requirements,
    testCases,
    visibleVersions,
    workItems,
    worklogs,
    snapshots,
    today,
    calculationNow,
  ]);

  useEffect(() => {
    risks.forEach((risk) => {
      const snapshot = { ...risk.currentSnapshot, createdAt: new Date().toISOString() };
      const previousToday = findLatestDailySnapshot(snapshots, snapshot.versionId, snapshot.date);
      if (!shouldSaveRiskSnapshot(snapshot, previousToday)) return;
      const key = `${snapshot.versionId}:${snapshot.date}:${buildRiskSignature(snapshot)}`;
      if (savedSnapshotKeysRef.current.has(key)) return;
      savedSnapshotKeysRef.current.add(key);
      saveSnapshot(snapshot).catch(() => {
        savedSnapshotKeysRef.current.delete(key);
      });
    });
  }, [risks, saveSnapshot, snapshots]);

  useEffect(() => {
    risks.forEach((risk) => {
      const previous = findPreviousRiskSnapshot(snapshots, risk.versionId, today);
      if (!shouldRequestRiskInsightWithCacheGate(riskDataLoaded, insights, risk, previous)) return;
      const signature = buildRiskInsightSignature(risk);
      const key = `${risk.versionId}:${signature}`;
      if (requestedInsightKeysRef.current.has(key)) return;
      requestedInsightKeysRef.current.add(key);
      requestRiskInsight(risk).then((response) => {
        if (!response.ok) return;
        saveInsight({
          versionId: risk.versionId,
          riskSignature: signature,
          insight: sanitizeRiskInsight(response.result),
          generatedAt: new Date().toISOString(),
          providerInfo: { model: response.meta.model },
        }).catch(() => {});
      }).catch(() => {});
    });
  }, [insights, riskDataLoaded, risks, saveInsight, snapshots, today]);

  const risksWithInsight = useMemo(() => risks.map((risk) => {
    const cached = getReusableInsight(insights, risk);
    return cached ? { ...risk, aiInsight: sanitizeRiskInsight(cached.insight) } : risk;
  }), [insights, risks]);

  const filteredRisks = useMemo(() => risksWithInsight.filter((risk) => {
    if (filter === 'attention') return risk.riskLevel !== 'on_track';
    if (filter === 'high') return ['at_risk', 'likely_delayed', 'blocked'].includes(risk.riskLevel);
    return true;
  }), [filter, risksWithInsight]);

  const selectedRisk = selectedRiskId ? risksWithInsight.find((risk) => risk.versionId === selectedRiskId) ?? null : null;
  const highRiskCount = risks.filter((risk) => ['at_risk', 'likely_delayed', 'blocked'].includes(risk.riskLevel)).length;
  const attentionCount = risks.filter((risk) => risk.riskLevel !== 'on_track').length;
  const avgConfidence = risks.length > 0
    ? Math.round(risks.reduce((sum, risk) => sum + risk.confidence, 0) / risks.length)
    : 0;

  return (
    <div className="flex h-full flex-col bg-[var(--bg)]">
      <header className="flex h-14 shrink-0 items-center justify-between border-b border-[var(--line)] bg-[var(--bg-card)] px-5">
        <div className="flex min-w-0 items-center gap-3">
          <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-[var(--accent-soft)] text-[var(--accent)]">
            <TriangleAlert className="h-4 w-4" />
          </div>
          <div className="min-w-0">
            <h1 className="truncate text-[15px] font-semibold text-[var(--ink)]">小宝预警</h1>
            <p className="truncate text-[11px] text-[var(--ink-muted)]">
              {canManage ? '管理视角：全部未结束版本' : '个人视角：我参与的未结束版本'}
            </p>
          </div>
        </div>
        <div className="flex items-center gap-2 text-[11px] text-[var(--ink-muted)]">
          {canManage && (
            <span className="inline-flex items-center gap-1 rounded-full bg-[var(--bg-subtle)] px-2 py-1">
              <ShieldCheck className="h-3.5 w-3.5" />
              管理权限
            </span>
          )}
          <span>{filteredRisks.length} / {risks.length} 个版本</span>
        </div>
      </header>

      <main className="flex-1 overflow-y-auto p-5">
        <section className="mb-4 grid gap-3 md:grid-cols-4">
          <SummaryTile label="可见版本" value={`${risks.length}`} />
          <SummaryTile label="需关注" value={`${attentionCount}`} />
          <SummaryTile label="高风险" value={`${highRiskCount}`} />
          <SummaryTile label="平均置信" value={`${avgConfidence}%`} />
        </section>

        <div className="mb-4 flex flex-wrap items-center justify-between gap-3">
          <div className="inline-flex rounded-lg border border-[var(--line)] bg-[var(--bg-card)] p-1">
            <FilterButton active={filter === 'all'} onClick={() => setFilter('all')}>全部</FilterButton>
            <FilterButton active={filter === 'attention'} onClick={() => setFilter('attention')}>需关注</FilterButton>
            <FilterButton active={filter === 'high'} onClick={() => setFilter('high')}>高风险</FilterButton>
          </div>
          <div className="flex items-center gap-1.5 text-[11px] text-[var(--ink-muted)]">
            <Layers className="h-3.5 w-3.5" />
            截止日期按版本期望发版日期计算
          </div>
        </div>

        {filteredRisks.length === 0 ? (
          <div className="rounded-lg border border-dashed border-[var(--line)] bg-[var(--bg-card)] p-12 text-center">
            <p className="text-[13px] font-medium text-[var(--ink-soft)]">暂无小宝预警</p>
            <p className="mt-1 text-[12px] text-[var(--ink-muted)]">当前筛选范围内没有需要展示的未结束版本</p>
          </div>
        ) : (
          <div className="grid gap-3 xl:grid-cols-2">
            {filteredRisks.map((risk) => (
              <XiaobaoWarningCard key={risk.versionId} risk={risk} onClick={() => setSelectedRiskId(risk.versionId)} />
            ))}
          </div>
        )}
      </main>

      {selectedRisk && (
        <XiaobaoWarningDrawer
          risk={selectedRisk}
          onClose={() => setSelectedRiskId(null)}
          onNavigate={() => router.push(`/versions/${selectedRisk.versionId}`)}
        />
      )}
    </div>
  );
}

function SummaryTile({ label, value }: { label: string; value: string }) {
  return (
    <div className="rounded-lg border border-[var(--line)] bg-[var(--bg-card)] p-3">
      <p className="text-[11px] text-[var(--ink-muted)]">{label}</p>
      <p className="mt-1 text-[20px] font-semibold tabular-nums text-[var(--ink)]">{value}</p>
    </div>
  );
}

function FilterButton({ active, onClick, children }: { active: boolean; onClick: () => void; children: React.ReactNode }) {
  return (
    <button
      type="button"
      onClick={onClick}
      className={`h-7 rounded-md px-3 text-[12px] transition-colors ${
        active
          ? 'bg-[var(--accent)] text-white'
          : 'text-[var(--ink-soft)] hover:bg-[var(--bg-subtle)] hover:text-[var(--ink)]'
      }`}
    >
      {children}
    </button>
  );
}
