/**
 * Excel 上传页 — 模板选择 + 文件上传 + 校验结果 + 冲突处理 + 上传记录。
 *
 * - Ant Design Tabs 切换"上传"和"上传记录"
 * - 模板类型选择（Radio.Group：4 种模板）
 * - 模板下载按钮（GET /excel/template/{type}）
 * - 文件上传（Upload，限 .xlsx/.xls，单文件）
 * - 校验结果展示：错误行标红、警告行黄色高亮
 * - 汇总：通过行数、警告行数、错误行数
 * - 冲突处理：无冲突直接确认，有冲突展示 DiffTable
 * - 上传记录 Tab：历史记录列表 + 分页
 */

import React, { useState, useEffect, useCallback } from "react";
import {
  Tabs,
  Radio,
  Button,
  Upload,
  Table,
  Tag,
  Space,
  Alert,
  message,
  Statistic,
  Card,
  Row,
  Col,
} from "antd";
import {
  UploadOutlined,
  DownloadOutlined,
  CheckCircleOutlined,
  WarningOutlined,
  CloseCircleOutlined,
} from "@ant-design/icons";
import type { UploadFile, UploadProps } from "antd/es/upload";
import type { ColumnsType, TablePaginationConfig } from "antd/es/table";
import { tenantApi } from "@/services/api";
import DiffTable from "@/components/DiffTable";
import type { ConflictRow } from "@/components/DiffTable";

/* ------------------------------------------------------------------ */
/*  类型定义                                                           */
/* ------------------------------------------------------------------ */

/** 模板类型 */
type UploadType = "finance_expense" | "platform_income" | "salary_adj" | "recharge_commission";

const UPLOAD_TYPE_OPTIONS: { label: string; value: UploadType }[] = [
  { label: "财务支出", value: "finance_expense" },
  { label: "团购收入", value: "platform_income" },
  { label: "助教奖罚", value: "salary_adj" },
  { label: "充值业绩归属", value: "recharge_commission" },
];

const UPLOAD_TYPE_LABEL: Record<string, string> = {
  finance_expense: "财务支出",
  platform_income: "团购收入",
  salary_adj: "助教奖罚",
  recharge_commission: "充值业绩归属",
};

/** 校验行状态 */
type RowStatus = "ok" | "warning" | "error";

/** 校验结果行 */
interface ValidationRow {
  rowIndex: number;
  status: RowStatus;
  data: Record<string, unknown>;
  errors?: { column: string; message: string }[];
  warnings?: { column: string; message: string }[];
}

/** 上传响应 */
interface UploadResponse {
  uploadId: number;
  rows: ValidationRow[];
  conflicts: ConflictRow[];
  summary: {
    total: number;
    passed: number;
    warnings: number;
    errors: number;
  };
}

/** 上传记录 */
interface UploadLogItem {
  id: number;
  uploadType: string;
  fileName: string;
  uploadedByName: string | null;
  createdAt: string;
  rowCount: number;
  conflictCount: number;
  status: string;
}

interface PaginatedResponse<T> {
  items: T[];
  total: number;
  page: number;
  pageSize: number;
}

/* ------------------------------------------------------------------ */
/*  上传 Tab                                                           */
/* ------------------------------------------------------------------ */

const UploadTab: React.FC = () => {
  const [uploadType, setUploadType] = useState<UploadType>("finance_expense");
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [uploading, setUploading] = useState(false);
  const [result, setResult] = useState<UploadResponse | null>(null);
  const [confirming, setConfirming] = useState(false);

  /** 下载模板 */
  const handleDownloadTemplate = async () => {
    try {
      const res = await tenantApi.get(`/excel/template/${uploadType}`, {
        responseType: "blob",
      });
      const blob = new Blob([res.data as BlobPart]);
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `${UPLOAD_TYPE_LABEL[uploadType]}模板.xlsx`;
      a.click();
      window.URL.revokeObjectURL(url);
    } catch {
      message.error("模板下载失败");
    }
  };

  /** 上传文件 */
  const handleUpload = async () => {
    if (fileList.length === 0) {
      message.warning("请先选择文件");
      return;
    }
    const file = fileList[0]?.originFileObj;
    if (!file) return;

    const formData = new FormData();
    formData.append("file", file);
    formData.append("upload_type", uploadType);

    setUploading(true);
    setResult(null);
    try {
      const res = await tenantApi.post<UploadResponse>("/excel/upload", formData, {
        headers: { "Content-Type": "multipart/form-data" },
      });
      setResult(res.data);
      if (res.data.summary.errors > 0) {
        message.warning("文件存在校验错误，请修正后重新上传");
      } else {
        message.success("文件解析完成");
      }
    } catch {
      message.error("上传失败，请重试");
    } finally {
      setUploading(false);
    }
  };

  /** Upload 组件 props */
  const uploadProps: UploadProps = {
    accept: ".xlsx,.xls",
    maxCount: 1,
    fileList,
    beforeUpload: () => false, // 手动上传
    onChange: ({ fileList: newList }) => {
      setFileList(newList);
      setResult(null); // 换文件时清除结果
    },
    onRemove: () => {
      setFileList([]);
      setResult(null);
    },
  };

  /** 确认写入（无冲突或冲突已解决） */
  const handleConfirm = async (resolutions?: { rowIndex: number; action: "replace" | "keep" }[]) => {
    if (!result) return;
    setConfirming(true);
    try {
      await tenantApi.post("/excel/confirm", {
        uploadId: result.uploadId,
        resolutions: resolutions ?? [],
      });
      message.success("数据写入成功");
      // 重置状态
      setResult(null);
      setFileList([]);
    } catch {
      message.error("写入失败，请重试");
    } finally {
      setConfirming(false);
    }
  };

  /** 校验结果表格列 */
  const validationColumns: ColumnsType<ValidationRow> = [
    {
      title: "行号",
      dataIndex: "rowIndex",
      key: "rowIndex",
      width: 80,
    },
    {
      title: "状态",
      dataIndex: "status",
      key: "status",
      width: 100,
      render: (status: RowStatus) => {
        if (status === "error") return <Tag color="red">错误</Tag>;
        if (status === "warning") return <Tag color="orange">警告</Tag>;
        return <Tag color="green">通过</Tag>;
      },
    },
    {
      title: "数据",
      dataIndex: "data",
      key: "data",
      render: (data: Record<string, unknown>) =>
        Object.entries(data)
          .map(([k, v]) => `${k}: ${String(v ?? "")}`)
          .join("，"),
    },
    {
      title: "问题详情",
      key: "issues",
      render: (_, record) => {
        const issues = [
          ...(record.errors ?? []).map((e) => `❌ ${e.column}: ${e.message}`),
          ...(record.warnings ?? []).map((w) => `⚠️ ${w.column}: ${w.message}`),
        ];
        return issues.length > 0 ? issues.join("；") : "-";
      },
    },
  ];

  return (
    <Space direction="vertical" size="large" style={{ width: "100%" }}>
      {/* 模板类型选择 */}
      <Card size="small" title="模板类型">
        <Space direction="vertical" size="middle">
          <Radio.Group
            value={uploadType}
            onChange={(e) => {
              setUploadType(e.target.value);
              setResult(null);
              setFileList([]);
            }}
            optionType="button"
            buttonStyle="solid"
            options={UPLOAD_TYPE_OPTIONS}
          />
          <Button icon={<DownloadOutlined />} onClick={handleDownloadTemplate}>
            下载模板
          </Button>
        </Space>
      </Card>

      {/* 文件上传 */}
      <Card size="small" title="上传文件">
        <Space>
          <Upload {...uploadProps}>
            <Button icon={<UploadOutlined />}>选择文件</Button>
          </Upload>
          <Button
            type="primary"
            onClick={handleUpload}
            loading={uploading}
            disabled={fileList.length === 0}
          >
            上传并校验
          </Button>
        </Space>
      </Card>

      {/* 校验结果 */}
      {result && (
        <>
          {/* 汇总统计 */}
          <Row gutter={16}>
            <Col span={8}>
              <Card>
                <Statistic
                  title="通过行数"
                  value={result.summary.passed}
                  prefix={<CheckCircleOutlined style={{ color: "#52c41a" }} />}
                  valueStyle={{ color: "#52c41a" }}
                />
              </Card>
            </Col>
            <Col span={8}>
              <Card>
                <Statistic
                  title="警告行数"
                  value={result.summary.warnings}
                  prefix={<WarningOutlined style={{ color: "#faad14" }} />}
                  valueStyle={{ color: "#faad14" }}
                />
              </Card>
            </Col>
            <Col span={8}>
              <Card>
                <Statistic
                  title="错误行数"
                  value={result.summary.errors}
                  prefix={<CloseCircleOutlined style={{ color: "#ff4d4f" }} />}
                  valueStyle={{ color: "#ff4d4f" }}
                />
              </Card>
            </Col>
          </Row>

          {/* 校验详情表格 */}
          {result.summary.errors > 0 && (
            <Card size="small" title="校验详情">
              <Table<ValidationRow>
                rowKey="rowIndex"
                columns={validationColumns}
                dataSource={result.rows}
                pagination={{ pageSize: 10 }}
                size="small"
                rowClassName={(record) => {
                  if (record.status === "error") return "row-error";
                  if (record.status === "warning") return "row-warning";
                  return "";
                }}
              />
              <style>{`
                .row-error { background-color: #fff2f0 !important; }
                .row-error:hover > td { background-color: #fff1f0 !important; }
                .row-warning { background-color: #fffbe6 !important; }
                .row-warning:hover > td { background-color: #fff8cc !important; }
              `}</style>
            </Card>
          )}

          {/* 冲突处理 / 确认写入 */}
          {result.summary.errors === 0 && (
            <>
              {result.conflicts.length > 0 ? (
                <Card size="small" title="冲突处理">
                  <Alert
                    message={`检测到 ${result.conflicts.length} 行冲突，请逐行选择处理方式`}
                    type="warning"
                    showIcon
                    style={{ marginBottom: 16 }}
                  />
                  <DiffTable
                    conflicts={result.conflicts}
                    onConfirm={(resolutions) => handleConfirm(resolutions)}
                    loading={confirming}
                  />
                </Card>
              ) : (
                <Card size="small">
                  <Alert
                    message="校验通过，无冲突数据"
                    type="success"
                    showIcon
                    style={{ marginBottom: 16 }}
                  />
                  <Button
                    type="primary"
                    size="large"
                    onClick={() => handleConfirm()}
                    loading={confirming}
                  >
                    确认写入
                  </Button>
                </Card>
              )}
            </>
          )}
        </>
      )}
    </Space>
  );
};


/* ------------------------------------------------------------------ */
/*  上传记录 Tab                                                       */
/* ------------------------------------------------------------------ */

const STATUS_TAG_MAP: Record<string, { color: string; text: string }> = {
  pending: { color: "orange", text: "待确认" },
  confirmed: { color: "green", text: "已写入" },
  failed: { color: "red", text: "失败" },
};

const UploadLogsTab: React.FC = () => {
  const [data, setData] = useState<UploadLogItem[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(20);
  const [loading, setLoading] = useState(false);

  const fetchLogs = useCallback(async () => {
    setLoading(true);
    try {
      const res = await tenantApi.get<PaginatedResponse<UploadLogItem>>("/excel/logs", {
        params: { page, page_size: pageSize },
      });
      setData(res.data.items);
      setTotal(res.data.total);
    } catch {
      message.error("获取上传记录失败");
    } finally {
      setLoading(false);
    }
  }, [page, pageSize]);

  useEffect(() => {
    fetchLogs();
  }, [fetchLogs]);

  const handleTableChange = (pagination: TablePaginationConfig) => {
    setPage(pagination.current ?? 1);
    setPageSize(pagination.pageSize ?? 20);
  };

  const columns: ColumnsType<UploadLogItem> = [
    {
      title: "模板类型",
      dataIndex: "uploadType",
      key: "uploadType",
      render: (v: string) => UPLOAD_TYPE_LABEL[v] ?? v,
    },
    { title: "文件名", dataIndex: "fileName", key: "fileName" },
    {
      title: "上传人",
      dataIndex: "uploadedByName",
      key: "uploadedByName",
      render: (v) => v ?? "-",
    },
    { title: "上传时间", dataIndex: "createdAt", key: "createdAt" },
    { title: "行数", dataIndex: "rowCount", key: "rowCount", width: 80 },
    { title: "冲突数", dataIndex: "conflictCount", key: "conflictCount", width: 80 },
    {
      title: "状态",
      dataIndex: "status",
      key: "status",
      render: (status: string) => {
        const tag = STATUS_TAG_MAP[status];
        return tag ? <Tag color={tag.color}>{tag.text}</Tag> : status;
      },
    },
  ];

  return (
    <Table<UploadLogItem>
      rowKey="id"
      columns={columns}
      dataSource={data}
      loading={loading}
      pagination={{
        current: page,
        pageSize,
        total,
        showSizeChanger: true,
        showTotal: (t) => `共 ${t} 条`,
      }}
      onChange={handleTableChange}
    />
  );
};

/* ------------------------------------------------------------------ */
/*  主页面组件                                                         */
/* ------------------------------------------------------------------ */

const ExcelUpload: React.FC = () => {
  return (
    <Tabs
      defaultActiveKey="upload"
      items={[
        { key: "upload", label: "上传", children: <UploadTab /> },
        { key: "logs", label: "上传记录", children: <UploadLogsTab /> },
      ]}
    />
  );
};

export default ExcelUpload;
