import React, { useState, useEffect } from 'react';
import { Card, Upload, Button, Table, Tag, message, Typography, Space, Alert, Descriptions, Progress, Select, DatePicker } from 'antd';
import { UploadOutlined, FileExcelOutlined, CheckCircleOutlined, CloseCircleOutlined, DownloadOutlined } from '@ant-design/icons';
import * as XLSX from 'xlsx';
import apiClient from '../../utils/request';
import dayjs from 'dayjs';

const { Title } = Typography;

const TXN_TYPE_MAP: Record<string, string> = { '收入': 'income', '支出': 'expense' };
const LEVEL1_MAP: Record<string, string> = { '收入': 'income', '项目支出': 'project', '公司支出': 'company' };
const COUNTERPARTY_TYPE_MAP: Record<string, string> = {
  '供应商': 'supplier', '分包商': 'subcontractor', '客户': 'customer',
  '员工': 'employee', '物流公司': 'logistics', '股东': 'shareholder', '其他': 'other'
};

interface ParsedRow {
  row: number;
  record_date: string;
  txn_type: string;
  category_level1: string;
  category_level2: string;
  project_name: string;
  amount_original: number;
  currency: string;
  exchange_rate: number;
  amount_cny: number;
  counterparty_name: string;
  counterparty_type: string;
  user_name: string;
  description: string;
  voucher_no: string;
  errors: string[];
}

const ExcelImport: React.FC = () => {
  const [parsedData, setParsedData] = useState<ParsedRow[]>([]);
  const [categories, setCategories] = useState<any>({});
  const [importing, setImporting] = useState(false);
  const [importResult, setImportResult] = useState<any>(null);

  useEffect(() => {
    apiClient.get('/expense-categories/grouped').then(res => {
      if (res.data.success) setCategories(res.data.data);
    }).catch(() => {});
  }, []);

  const getCategoryMap = () => {
    const map: Record<string, string> = {};
    Object.entries(categories).forEach(([level1, items]: [string, any]) => {
      items.forEach((item: any) => { map[item.label] = item.value; });
    });
    return map;
  };

  const handleFileUpload = (file: File) => {
    const reader = new FileReader();
    reader.onload = (e) => {
      try {
        const data = new Uint8Array(e.target?.result as ArrayBuffer);
        const workbook = XLSX.read(data, { type: 'array' });
        const sheet = workbook.Sheets[workbook.SheetNames[0]];
        const json = XLSX.utils.sheet_to_json(sheet, { header: 1 });

        if (json.length < 2) {
          message.error('Excel文件没有数据行');
          return;
        }

        const categoryMap = getCategoryMap();
        const rows: ParsedRow[] = [];

        for (let i = 1; i < json.length; i++) {
          const r: any[] = json[i];
          if (!r || r.length === 0 || !r[0]) continue;

          const errors: string[] = [];
          const dateVal = r[0];
          let recordDate = '';
          if (typeof dateVal === 'number') {
            const d = XLSX.SSF.parse_date_code(dateVal);
            recordDate = `${d.y}-${String(d.m).padStart(2, '0')}-${String(d.d).padStart(2, '0')}`;
          } else if (typeof dateVal === 'string') {
            recordDate = dateVal;
          }

          const txnTypeLabel = String(r[1] || '').trim();
          const level1Label = String(r[2] || '').trim();
          const level2Label = String(r[3] || '').trim();
          const projectName = String(r[4] || '').trim();
          const amountOriginal = parseFloat(r[5]) || 0;
          const currency = String(r[6] || 'CNY').trim();
          const exchangeRate = parseFloat(r[7]) || 1;
          const amountCny = parseFloat(r[8]) || (amountOriginal * exchangeRate);
          const counterpartyName = String(r[9] || '').trim();
          const counterpartyTypeLabel = String(r[10] || '').trim();
          const userName = String(r[11] || '').trim();
          const description = String(r[12] || '').trim();
          const voucherNo = String(r[13] || '').trim();

          const txnType = TXN_TYPE_MAP[txnTypeLabel] || '';
          const level1 = LEVEL1_MAP[level1Label] || '';
          const level2 = categoryMap[level2Label] || '';

          if (!recordDate) errors.push('日期为空');
          if (!txnType) errors.push(`收支类型无效: ${txnTypeLabel}`);
          if (!level1) errors.push(`一级分类无效: ${level1Label}`);
          if (!level2) errors.push(`二级分类无效: ${level2Label}`);
          if (amountOriginal <= 0) errors.push('金额必须大于0');
          if ((level1 === 'project' || (level1 === 'income' && level2 !== 'shareholder_investment')) && !projectName) {
            errors.push('项目支出/项目收入必须填写项目名称');
          }

          rows.push({
            row: i + 1,
            record_date: recordDate,
            txn_type: txnType,
            category_level1: level1,
            category_level2: level2,
            project_name: projectName,
            amount_original: amountOriginal,
            currency,
            exchange_rate: exchangeRate,
            amount_cny: Math.round(amountCny * 100) / 100,
            counterparty_name: counterpartyName,
            counterparty_type: COUNTERPARTY_TYPE_MAP[counterpartyTypeLabel] || '',
            user_name: userName,
            description,
            voucher_no: voucherNo,
            errors
          });
        }

        setParsedData(rows);
        setImportResult(null);
        message.success(`解析完成，共 ${rows.length} 条记录`);
      } catch (err: any) {
        message.error('解析Excel失败: ' + err.message);
      }
    };
    reader.readAsArrayBuffer(file);
    return false;
  };

  const handleImport = async () => {
    const validRows = parsedData.filter(r => r.errors.length === 0);
    if (validRows.length === 0) {
      message.error('没有有效的数据可导入');
      return;
    }

    setImporting(true);
    try {
      const records = validRows.map(r => ({
        txn_type: r.txn_type,
        category_level1: r.category_level1,
        category_level2: r.category_level2,
        project_name: r.project_name,
        amount_original: r.amount_original,
        currency: r.currency,
        exchange_rate: r.exchange_rate,
        amount_cny: r.amount_cny,
        record_date: r.record_date,
        counterparty_name: r.counterparty_name,
        counterparty_type: r.counterparty_type,
        user_name: r.user_name,
        description: r.description,
        voucher_no: r.voucher_no,
        source: 'manual'
      }));

      const res = await apiClient.post('/financial-records/batch', { records });
      if (res.data.success) {
        setImportResult(res.data.data);
        message.success(`导入完成：成功 ${res.data.data.imported} 条，失败 ${res.data.data.failed} 条`);
      }
    } catch (e: any) {
      message.error('导入失败: ' + (e.response?.data?.message || e.message));
    }
    setImporting(false);
  };

  const errorCount = parsedData.filter(r => r.errors.length > 0).length;
  const validCount = parsedData.filter(r => r.errors.length === 0).length;

  const columns = [
    { title: '行号', dataIndex: 'row', width: 50 },
    { title: '日期', dataIndex: 'record_date', width: 100 },
    { title: '收支', dataIndex: 'txn_type', width: 60, render: (v: string) => <Tag color={v === 'income' ? 'green' : 'red'}>{v === 'income' ? '收入' : '支出'}</Tag> },
    { title: '一级', dataIndex: 'category_level1', width: 80, render: (v: string) => {
      const m: Record<string, string> = { income: '收入', project: '项目', company: '公司' };
      return m[v] || v;
    }},
    { title: '二级', dataIndex: 'category_level2', width: 100 },
    { title: '项目', dataIndex: 'project_name', width: 120, ellipsis: true },
    { title: '金额', dataIndex: 'amount_original', width: 90, render: (v: number) => v?.toLocaleString() },
    { title: '币种', dataIndex: 'currency', width: 50 },
    { title: '汇率', dataIndex: 'exchange_rate', width: 60 },
    { title: '等效人民币', dataIndex: 'amount_cny', width: 100, render: (v: number) => v?.toLocaleString() },
    { title: '描述', dataIndex: 'description', width: 150, ellipsis: true },
    {
      title: '校验', width: 80,
      render: (_: unknown, r: ParsedRow) => r.errors.length === 0
        ? <CheckCircleOutlined style={{ color: '#52c41a' }} />
        : <CloseCircleOutlined style={{ color: '#ff4d4f' }} title={r.errors.join('; ')} />
    }
  ];

  return (
    <div style={{ padding: 24 }}>
      <Card>
        <Title level={4}>Excel 批量导入财务记录</Title>

        <Alert
          type="info"
          showIcon
          style={{ marginBottom: 16 }}
          message="Excel 模板格式要求"
          description={
            <div>
              <p>列顺序：日期 | 收支类型 | 一级分类 | 二级分类 | 项目名称 | 金额 | 币种 | 汇率 | 等效人民币 | 对方名称 | 对方类型 | 人员姓名 | 描述 | 凭证编号</p>
              <p>收支类型：收入 / 支出 ｜ 一级分类：收入 / 项目支出 / 公司支出 ｜ 币种：CNY / USD / LAK / THB</p>
              <p>二级分类必须使用系统中已有的分类名称（如：材料采购、工资薪酬等）</p>
            </div>
          }
        />

        <Upload
          accept=".xlsx,.xls"
          showUploadList={false}
          beforeUpload={handleFileUpload}
        >
          <Button icon={<FileExcelOutlined />} type="primary">选择 Excel 文件</Button>
        </Upload>

        <a href="/templates/财务记账导入模板.xlsx" download="财务记账导入模板.xlsx" style={{ marginLeft: 12 }}>
          <Button icon={<DownloadOutlined />}>下载模板文件</Button>
        </a>

        {parsedData.length > 0 && (
          <>
            <div style={{ margin: '16px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <Space>
                <span>共 {parsedData.length} 条</span>
                <Tag color="green">有效 {validCount}</Tag>
                {errorCount > 0 && <Tag color="red">有误 {errorCount}</Tag>}
              </Space>
              <Button
                type="primary"
                onClick={handleImport}
                loading={importing}
                disabled={validCount === 0}
              >
                导入 {validCount} 条有效记录
              </Button>
            </div>

            <Table
              dataSource={parsedData}
              columns={columns}
              rowKey="row"
              size="small"
              scroll={{ x: 1200 }}
              pagination={{ pageSize: 20 }}
              rowClassName={(r) => r.errors.length > 0 ? 'row-error' : ''}
            />

            {importResult && (
              <Alert
                type={importResult.failed > 0 ? 'warning' : 'success'}
                showIcon
                style={{ marginTop: 16 }}
                message={`导入完成：成功 ${importResult.imported} 条，失败 ${importResult.failed} 条`}
                description={
                  importResult.errors?.length > 0
                    ? importResult.errors.map((e: any, i: number) => <div key={i}>第 {e.row} 行：{e.message}</div>)
                    : undefined
                }
              />
            )}
          </>
        )}
      </Card>

      <style>{`.row-error { background: #fff2f0 !important; }`}</style>
    </div>
  );
};

export default ExcelImport;
