"use client";

import { useState, useCallback } from "react";
import { useParams, useRouter } from "next/navigation";
import { motion } from "motion/react";
import { ArrowLeft, CheckCircle, Loader2, FileSpreadsheet } from "lucide-react";

import { api } from "@/lib/api/client";
import { ENDPOINTS } from "@/lib/api/endpoints";
import { useToast } from "@/lib/hooks/useToast";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { FieldMappingTable } from "@/components/mapping/FieldMappingTable";
import { AISuggestionPanel } from "@/components/mapping/AISuggestionPanel";
import type { TaskMappingOverview } from "@/lib/api/types";

// 模拟数据（实际应从 API 获取）
const mockMappingData: TaskMappingOverview = {
  task_id: 1,
  total_files: 3,
  total_fields: 18,
  confirmed_fields: 5,
  needs_review: true,
  files: [
    {
      file_id: 1,
      file_type: "工资表",
      file_name: "2024年1月工资表.xlsx",
      total_fields: 6,
      confirmed_fields: 2,
      high_confidence: 4,
      medium_confidence: 1,
      low_confidence: 1,
      mappings: [
        {
          id: 1,
          company_id: 1,
          file_id: 1,
          source_field: "员工姓名",
          standard_field: "员工姓名",
          confidence: 1.0,
          reasoning: "字段名完全匹配",
          sample_values: ["张三", "李四", "王五"],
          is_skipped: false,
          confirmed: true,
          confirmed_by: 1,
          confirmed_at: new Date().toISOString(),
        },
        {
          id: 2,
          company_id: 1,
          file_id: 1,
          source_field: "工号",
          standard_field: "工号",
          confidence: 1.0,
          reasoning: "字段名完全匹配",
          sample_values: ["EMP001", "EMP002"],
          is_skipped: false,
          confirmed: true,
          confirmed_by: 1,
          confirmed_at: new Date().toISOString(),
        },
        {
          id: 3,
          company_id: 1,
          file_id: 1,
          source_field: "基本薪资",
          standard_field: "基本工资",
          confidence: 0.85,
          reasoning: "字段名相似，样例值验证为数值类型",
          sample_values: [8000, 10000, 12000],
          is_skipped: false,
          confirmed: false,
        },
        {
          id: 4,
          company_id: 1,
          file_id: 1,
          source_field: "岗位津贴",
          standard_field: "补贴",
          confidence: 0.75,
          reasoning: "字段名包含关键词：'津贴'",
          sample_values: [500, 800, 1000],
          is_skipped: false,
          confirmed: false,
        },
        {
          id: 5,
          company_id: 1,
          file_id: 1,
          source_field: "实发合计",
          standard_field: "实发工资",
          confidence: 0.6,
          reasoning: "字段名部分匹配，需要确认",
          sample_values: [8500, 10800, 13000],
          is_skipped: false,
          confirmed: false,
        },
        {
          id: 6,
          company_id: 1,
          file_id: 1,
          source_field: "备注",
          standard_field: "",
          confidence: 0.0,
          reasoning: "无法识别字段类型",
          sample_values: ["正常", "补发"],
          is_skipped: false,
          confirmed: false,
        },
      ],
    },
    {
      file_id: 2,
      file_type: "社保表",
      file_name: "2024年1月社保表.xlsx",
      total_fields: 6,
      confirmed_fields: 2,
      high_confidence: 3,
      medium_confidence: 2,
      low_confidence: 1,
      mappings: [
        {
          id: 7,
          company_id: 1,
          file_id: 2,
          source_field: "姓名",
          standard_field: "员工姓名",
          confidence: 0.95,
          reasoning: "字段名包含关键词：'姓名'",
          sample_values: ["张三", "李四"],
          is_skipped: false,
          confirmed: true,
        },
        {
          id: 8,
          company_id: 1,
          file_id: 2,
          source_field: "养老保险",
          standard_field: "养老保险",
          confidence: 1.0,
          reasoning: "字段名完全匹配",
          sample_values: [800, 960, 1200],
          is_skipped: false,
          confirmed: true,
        },
        {
          id: 9,
          company_id: 1,
          file_id: 2,
          source_field: "医疗",
          standard_field: "医疗保险",
          confidence: 0.8,
          reasoning: "字段名部分匹配",
          sample_values: [200, 240, 300],
          is_skipped: false,
          confirmed: false,
        },
        {
          id: 10,
          company_id: 1,
          file_id: 2,
          source_field: "失业",
          standard_field: "失业保险",
          confidence: 0.75,
          reasoning: "字段名相似",
          sample_values: [50, 60, 75],
          is_skipped: false,
          confirmed: false,
        },
        {
          id: 11,
          company_id: 1,
          file_id: 2,
          source_field: "公积金",
          standard_field: "公积金",
          confidence: 0.5,
          reasoning: "需要确认具体含义",
          sample_values: [500, 600, 750],
          is_skipped: false,
          confirmed: false,
        },
        {
          id: 12,
          company_id: 1,
          file_id: 2,
          source_field: "合计",
          standard_field: "社保合计",
          confidence: 0.6,
          reasoning: "可能是合计字段",
          sample_values: [1550, 1800, 2325],
          is_skipped: false,
          confirmed: false,
        },
      ],
    },
    {
      file_id: 3,
      file_type: "个税表",
      file_name: "2024年1月个税表.xlsx",
      total_fields: 6,
      confirmed_fields: 1,
      high_confidence: 2,
      medium_confidence: 3,
      low_confidence: 1,
      mappings: [
        {
          id: 13,
          company_id: 1,
          file_id: 3,
          source_field: "姓名",
          standard_field: "员工姓名",
          confidence: 0.95,
          reasoning: "字段名包含关键词：'姓名'",
          sample_values: ["张三", "李四"],
          is_skipped: false,
          confirmed: true,
        },
        {
          id: 14,
          company_id: 1,
          file_id: 3,
          source_field: "应税工资",
          standard_field: "应税收入",
          confidence: 0.9,
          reasoning: "字段名包含关键词：'应税'",
          sample_values: [8000, 10000],
          is_skipped: false,
          confirmed: false,
        },
        {
          id: 15,
          company_id: 1,
          file_id: 3,
          source_field: "专项扣除",
          standard_field: "税前扣除",
          confidence: 0.8,
          reasoning: "可能为税前扣除项",
          sample_values: [1000, 1500],
          is_skipped: false,
          confirmed: false,
        },
        {
          id: 16,
          company_id: 1,
          file_id: 3,
          source_field: "个税",
          standard_field: "应缴个税",
          confidence: 0.7,
          reasoning: "可能为个税字段",
          sample_values: [200, 300],
          is_skipped: false,
          confirmed: false,
        },
        {
          id: 17,
          company_id: 1,
          file_id: 3,
          source_field: "税后工资",
          standard_field: "税后收入",
          confidence: 0.85,
          reasoning: "字段名相似",
          sample_values: [6800, 8500],
          is_skipped: false,
          confirmed: false,
        },
        {
          id: 18,
          company_id: 1,
          file_id: 3,
          source_field: "银行账号",
          standard_field: "银行账号",
          confidence: 1.0,
          reasoning: "字段名完全匹配",
          sample_values: ["6222021234567890"],
          is_skipped: false,
          confirmed: false,
        },
      ],
    },
  ],
};

const container = {
  hidden: { opacity: 0 },
  show: {
    opacity: 1,
    transition: { staggerChildren: 0.08 },
  },
};

const item = {
  hidden: { opacity: 0, y: 12 },
  show: { opacity: 1, y: 0, transition: { duration: 0.4, ease: [0.16, 1, 0.3, 1] as const } },
};

export default function MappingPage() {
  const params = useParams();
  const router = useRouter();
  const toast = useToast();
  const taskId = params.id as string;

  const [data, setData] = useState<TaskMappingOverview | null>(mockMappingData);
  const [loading, setLoading] = useState(false);
  const [activeFile, setActiveFile] = useState<number>(mockMappingData?.files[0]?.file_id || 1);

  // 统计
  const totalHigh = data?.files.reduce((acc, f) => acc + f.high_confidence, 0) || 0;
  const totalMedium = data?.files.reduce((acc, f) => acc + f.medium_confidence, 0) || 0;
  const totalLow = data?.files.reduce((acc, f) => acc + f.low_confidence, 0) || 0;

  // 更新映射
  const handleUpdateMapping = useCallback(
    async (mappingId: number, standardField: string) => {
      try {
        await api.put(ENDPOINTS.MAPPING.UPDATE(mappingId), {
          standard_field: standardField,
        });

        setData((prev) => {
          if (!prev) return prev;
          const newFiles = prev.files.map((file) => ({
            ...file,
            mappings: file.mappings.map((m) =>
              m.id === mappingId ? { ...m, standard_field: standardField, confidence: 1.0 } : m
            ),
          }));
          return { ...prev, files: newFiles };
        });

        toast.success("字段已更新");
      } catch {
        toast.error("更新失败");
      }
    },
    [toast]
  );

  // 跳过映射
  const handleSkipMapping = useCallback(
    async (mappingId: number) => {
      try {
        await api.put(ENDPOINTS.MAPPING.UPDATE(mappingId), {
          is_skipped: true,
        });

        setData((prev) => {
          if (!prev) return prev;
          const newFiles = prev.files.map((file) => ({
            ...file,
            mappings: file.mappings.map((m) =>
              m.id === mappingId ? { ...m, is_skipped: true } : m
            ),
          }));
          return { ...prev, files: newFiles };
        });

        toast.success("字段已跳过");
      } catch {
        toast.error("操作失败");
      }
    },
    [toast]
  );

  // 确认单个映射
  const handleConfirmMapping = useCallback(
    async (mappingId: number) => {
      try {
        await api.post(ENDPOINTS.MAPPING.CONFIRM, {
          mapping_ids: [mappingId],
        });

        setData((prev) => {
          if (!prev) return prev;
          const newFiles = prev.files.map((file) => ({
            ...file,
            mappings: file.mappings.map((m) =>
              m.id === mappingId
                ? { ...m, confirmed: true, confirmed_at: new Date().toISOString() }
                : m
            ),
            confirmed_fields: file.mappings.filter(
              (m) => m.id === mappingId || m.confirmed
            ).length,
          }));
          const totalConfirmed = newFiles.reduce((acc, f) => acc + f.confirmed_fields, 0);
          return { ...prev, files: newFiles, confirmed_fields: totalConfirmed };
        });

        toast.success("字段已确认");
      } catch {
        toast.error("确认失败");
      }
    },
    [toast]
  );

  // 批量确认
  const handleConfirmAll = useCallback(
    async (mappingIds: number[]) => {
      if (mappingIds.length === 0) return;

      try {
        setLoading(true);
        await api.post(ENDPOINTS.MAPPING.CONFIRM, {
          mapping_ids: mappingIds,
        });

        setData((prev) => {
          if (!prev) return prev;
          const newFiles = prev.files.map((file) => {
            const fileIds = file.mappings.map((m) => m.id);
            const confirmedIds = mappingIds.filter((id) => fileIds.includes(id));
            return {
              ...file,
              mappings: file.mappings.map((m) =>
                confirmedIds.includes(m.id)
                  ? { ...m, confirmed: true, confirmed_at: new Date().toISOString() }
                  : m
              ),
              confirmed_fields: file.mappings.filter(
                (m) => m.confirmed || confirmedIds.includes(m.id)
              ).length,
            };
          });
          const totalConfirmed = newFiles.reduce((acc, f) => acc + f.confirmed_fields, 0);
          return { ...prev, files: newFiles, confirmed_fields: totalConfirmed };
        });

        toast.success(`已确认 ${mappingIds.length} 个字段`);
      } catch {
        toast.error("批量确认失败");
      } finally {
        setLoading(false);
      }
    },
    [toast]
  );

  // 确认并进入下一步 - 跳转到对账结果页面
  const handleConfirmAndNext = useCallback(async () => {
    try {
      setLoading(true);
      toast.success("字段映射已确认，正在进入对账...");
      router.push(`/tasks/${taskId}/result`);
    } catch {
      toast.error("操作失败");
    } finally {
      setLoading(false);
    }
  }, [taskId, router, toast]);

  const currentFile = data?.files.find((f) => f.file_id === activeFile);

  if (!data) {
    return (
      <div className="min-h-full flex items-center justify-center">
        <div className="flex items-center gap-2 text-muted-foreground">
          <Loader2 className="h-5 w-5 animate-spin" />
          加载中...
        </div>
      </div>
    );
  }

  return (
    <div className="min-h-full p-6 lg:p-8 max-w-7xl mx-auto space-y-6">
      {/* 页面头部 */}
      <motion.div
        initial={{ opacity: 0, y: -8 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.4, ease: [0.16, 1, 0.3, 1] }}
        className="flex items-center justify-between"
      >
        <div className="flex items-center gap-4">
          <Button variant="ghost" size="icon" onClick={() => router.push("/tasks")} className="hover:bg-muted">
            <ArrowLeft className="h-4 w-4" />
          </Button>
          <div>
            <h1 className="text-heading-1 text-foreground">字段映射确认</h1>
            <p className="text-muted-foreground mt-1">
              任务 #{taskId} - 确认 AI 识别的字段映射关系
            </p>
          </div>
        </div>

        <Button onClick={handleConfirmAndNext} disabled={loading} className="btn-press">
          {loading ? (
            <Loader2 className="h-4 w-4 animate-spin" />
          ) : (
            <CheckCircle className="h-4 w-4" />
          )}
          确认并进入对账
        </Button>
      </motion.div>

      {/* AI 建议面板 */}
      <motion.div
        initial={{ opacity: 0, y: 8 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.4, delay: 0.1, ease: [0.16, 1, 0.3, 1] }}
      >
        <AISuggestionPanel
          totalFields={data.total_fields}
          highConfidence={totalHigh}
          mediumConfidence={totalMedium}
          lowConfidence={totalLow}
          confirmedCount={data.confirmed_fields}
          onAutoConfirm={() => {
            const ids = data.files
              .flatMap((f) => f.mappings)
              .filter((m) => !m.confirmed && !m.is_skipped && m.standard_field)
              .map((m) => m.id);
            handleConfirmAll(ids);
          }}
        />
      </motion.div>

      {/* 文件标签页 */}
      <motion.div
        initial={{ opacity: 0, y: 8 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.4, delay: 0.2, ease: [0.16, 1, 0.3, 1] }}
      >
        <div className="flex gap-2 border-b border-border overflow-x-auto">
          {data.files.map((file) => (
            <button
              key={file.file_id}
              onClick={() => setActiveFile(file.file_id)}
              className={`flex items-center gap-2 px-4 py-2.5 text-sm font-medium border-b-2 -mb-px whitespace-nowrap transition-colors ${
                activeFile === file.file_id
                  ? "border-primary text-primary"
                  : "border-transparent text-muted-foreground hover:text-foreground"
              }`}
            >
              <FileSpreadsheet className="w-4 h-4" />
              {file.file_type}
              <Badge variant={activeFile === file.file_id ? "default" : "secondary"} className="ml-1 text-xs">
                {file.confirmed_fields}/{file.total_fields}
              </Badge>
            </button>
          ))}
        </div>
      </motion.div>

      {/* 字段映射表格 */}
      <motion.div
        initial={{ opacity: 0, y: 8 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.4, delay: 0.3, ease: [0.16, 1, 0.3, 1] }}
      >
        {currentFile && (
          <FieldMappingTable
            mappings={currentFile.mappings}
            fileName={currentFile.file_name}
            fileType={currentFile.file_type}
            onUpdate={handleUpdateMapping}
            onSkip={handleSkipMapping}
            onConfirm={handleConfirmMapping}
            onConfirmAll={handleConfirmAll}
          />
        )}
      </motion.div>

      {/* 文件概览卡片 */}
      <motion.div
        variants={container}
        initial="hidden"
        animate="show"
        className="grid grid-cols-1 md:grid-cols-3 gap-4"
      >
        {data.files.map((file) => (
          <motion.div key={file.file_id} variants={item}>
            <Card
              className={`cursor-pointer transition-all hover-lift ${
                activeFile === file.file_id
                  ? "ring-2 ring-primary"
                  : ""
              }`}
              onClick={() => setActiveFile(file.file_id)}
            >
              <CardContent className="p-5">
                <div className="flex items-center gap-3 mb-3">
                  <div className="p-2 rounded-lg bg-muted">
                    <FileSpreadsheet className="w-5 h-5 text-muted-foreground" />
                  </div>
                  <div className="flex-1 min-w-0">
                    <h3 className="font-medium text-foreground truncate">
                      {file.file_type}
                    </h3>
                    <p className="text-caption text-muted-foreground truncate">
                      {file.file_name}
                    </p>
                  </div>
                </div>
                <div className="flex items-center justify-between">
                  <span className="text-caption text-muted-foreground">
                    已确认 {file.confirmed_fields}/{file.total_fields}
                  </span>
                  {file.low_confidence > 0 && (
                    <Badge variant="destructive" className="text-xs">
                      {file.low_confidence} 个待检查
                    </Badge>
                  )}
                </div>
                {/* 置信度进度条 */}
                <div className="mt-3 h-1.5 bg-muted rounded-full overflow-hidden">
                  <motion.div
                    initial={{ width: 0 }}
                    animate={{ width: `${(file.confirmed_fields / file.total_fields) * 100}%` }}
                    transition={{ duration: 0.6, ease: [0.16, 1, 0.3, 1] }}
                    className="h-full bg-primary rounded-full"
                  />
                </div>
              </CardContent>
            </Card>
          </motion.div>
        ))}
      </motion.div>
    </div>
  );
}