/**
 * AI 预热进度页面。
 *
 * 监控 app2_finance 的 72 组合（8 时间维度 × 9 区域）缓存覆盖率。
 * 支持：
 * - 进度条 + 缺失组合表格
 * - 一键补跑所有缺失（串行 POST /admin/ai/run/app2_finance）
 * - 触发全量预热（POST /admin/ai/trigger-event）
 * - 按单组合手动重跑
 */

import React, { useCallback, useEffect, useState } from "react";
import {
  Card, Progress, Table, Button, Space, Tag, message, Select,
  Typography, Descriptions, Modal, Alert,
} from "antd";
import { ReloadOutlined, ThunderboltOutlined, PlayCircleOutlined } from "@ant-design/icons";
import type { ColumnsType } from "antd/es/table";
import {
  getPrewarmProgress, runApp, triggerEvent,
  type PrewarmProgressResponse, type PrewarmMissingItem,
} from "../api/adminAI";

const { Title, Paragraph, Text } = Typography;

const TIME_LABELS: Record<string, string> = {
  this_month: "本月", last_month: "上月",
  this_week: "本周", last_week: "上周",
  this_quarter: "本季度", last_quarter: "上季度",
  last_3_months: "近三个月", last_6_months: "近六个月",
};

const AREA_LABELS: Record<string, string> = {
  all: "全部区域", hall: "大厅", hallA: "A区", hallB: "B区", hallC: "C区",
  vip: "台球包厢", snooker: "斯诺克", mahjong: "麻将房", ktv: "团建房",
};

/**
 * 按 area 选 app_type：
 * - area = 'all' → app2_finance（全域，8 组合）
 * - area != 'all' → app2a_finance_area（区域精简版，64 组合）
 */
function areaToAppType(area: string): "app2_finance" | "app2a_finance_area" {
  return area === "all" ? "app2_finance" : "app2a_finance_area";
}

function fmtTime(raw: string | null): string {
  if (!raw) return "—";
  const d = new Date(raw);
  return Number.isNaN(d.getTime()) ? raw : d.toLocaleString("zh-CN");
}

// 用于在 missing 表格插入分组标题行（AntD onCell 合并单元格方案）
type MissingRowWithGroup = PrewarmMissingItem & { __group_header?: string };

const AIPrewarm: React.FC = () => {
  const [siteId, setSiteId] = useState<number>(2790685415443269);
  const [data, setData] = useState<PrewarmProgressResponse | null>(null);
  const [loading, setLoading] = useState(false);

  // 单组合重跑
  const [runningTarget, setRunningTarget] = useState<string | null>(null);

  // 批量补缺
  const [backfillOpen, setBackfillOpen] = useState(false);
  const [backfillRunning, setBackfillRunning] = useState(false);
  const [backfillProgress, setBackfillProgress] = useState<{ done: number; total: number; current: string } | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const res = await getPrewarmProgress(siteId);
      setData(res);
    } catch {
      message.error("加载预热进度失败");
    } finally {
      setLoading(false);
    }
  }, [siteId]);

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

  const handleRunOne = async (item: PrewarmMissingItem) => {
    setRunningTarget(item.target_id);
    try {
      const res = await runApp(areaToAppType(item.area), {
        site_id: siteId,
        time_dimension: item.time_dimension,
        area: item.area,
      });
      if (res.success) {
        message.success(`${TIME_LABELS[item.time_dimension]} × ${AREA_LABELS[item.area]} 已生成`);
        load();
      } else {
        message.error(res.error || "生成失败");
      }
    } catch {
      message.error("请求失败");
    } finally {
      setRunningTarget(null);
    }
  };

  const handleTriggerFullPrewarm = async () => {
    Modal.confirm({
      title: "全量预热",
      content: `将触发 dws_completed 事件，后台串行生成 72 组合缓存（预计 1-2 小时）。继续？`,
      okText: "开始预热",
      onOk: async () => {
        try {
          const res = await triggerEvent({
            event_type: "dws_completed",
            site_id: siteId,
            is_forced: true,
          });
          message.success(`已触发全量预热（trigger_job_id=${res.trigger_job_id}），在后台异步执行`);
          load();
        } catch {
          message.error("触发失败");
        }
      },
    });
  };

  const handleBackfillMissing = async () => {
    if (!data || data.missing.length === 0) return;
    setBackfillOpen(false);
    setBackfillRunning(true);
    const total = data.missing.length;
    let done = 0;
    let fail = 0;
    for (const item of data.missing) {
      setBackfillProgress({ done, total, current: `${TIME_LABELS[item.time_dimension]} × ${AREA_LABELS[item.area]}` });
      try {
        const res = await runApp(areaToAppType(item.area), {
          site_id: siteId,
          time_dimension: item.time_dimension,
          area: item.area,
        });
        if (!res.success) fail++;
      } catch {
        fail++;
      }
      done++;
    }
    setBackfillProgress({ done, total, current: "完成" });
    setBackfillRunning(false);
    if (fail === 0) {
      message.success(`已补齐 ${done}/${total} 组合`);
    } else {
      message.warning(`完成 ${done - fail}/${total}，失败 ${fail} 条（详见调用明细）`);
    }
    load();
  };

  // 按 area 分组的缺失列表（插入 group header 行）
  const groupedMissing: MissingRowWithGroup[] = (() => {
    if (!data || data.missing.length === 0) return [];
    const global = data.missing.filter((i) => i.area === "all");
    const area = data.missing.filter((i) => i.area !== "all");
    const result: MissingRowWithGroup[] = [];
    if (global.length > 0) {
      result.push({
        time_dimension: "__header_global",
        area: "__header_global",
        target_id: "__header_global",
        __group_header: `🌐 全域组合（app2_finance）· 缺失 ${global.length} / 8 条`,
      });
      result.push(...global);
    }
    if (area.length > 0) {
      result.push({
        time_dimension: "__header_area",
        area: "__header_area",
        target_id: "__header_area",
        __group_header: `🏷️ 区域组合（app2a_finance_area）· 缺失 ${area.length} / 64 条`,
      });
      result.push(...area);
    }
    return result;
  })();

  // 全域 / 区域 完成统计
  const globalDone = data ? 8 - data.missing.filter((i) => i.area === "all").length : 0;
  const areaDone = data ? 64 - data.missing.filter((i) => i.area !== "all").length : 0;

  const missingColumns: ColumnsType<MissingRowWithGroup> = [
    {
      title: "时间维度",
      dataIndex: "time_dimension",
      key: "time_dimension",
      width: 220,
      onCell: (r) => (r.__group_header ? { colSpan: 4 } : {}),
      render: (v: string, r) =>
        r.__group_header ? (
          <div style={{ padding: "6px 4px", background: "#fafafa", fontWeight: 600, color: "#595959" }}>
            {r.__group_header}
          </div>
        ) : (
          <span>{TIME_LABELS[v] || v} <Text type="secondary" style={{ fontSize: 12 }}>({v})</Text></span>
        ),
    },
    {
      title: "区域",
      dataIndex: "area",
      key: "area",
      width: 140,
      onCell: (r) => (r.__group_header ? { colSpan: 0 } : {}),
      render: (v: string) => (
        <span>{AREA_LABELS[v] || v} <Text type="secondary" style={{ fontSize: 12 }}>({v})</Text></span>
      ),
    },
    {
      title: "缓存键",
      dataIndex: "target_id",
      key: "target_id",
      onCell: (r) => (r.__group_header ? { colSpan: 0 } : {}),
      render: (v: string) => <code>{v}</code>,
    },
    {
      title: "操作",
      key: "action",
      width: 100,
      fixed: "right",
      onCell: (r) => (r.__group_header ? { colSpan: 0 } : {}),
      render: (_: unknown, r) =>
        r.__group_header ? null : (
          <Button
            size="small"
            type="primary"
            icon={<PlayCircleOutlined />}
            loading={runningTarget === r.target_id}
            onClick={() => handleRunOne(r as PrewarmMissingItem)}
          >
            单独生成
          </Button>
        ),
    },
  ];

  const donePercent = data ? Math.round((data.done / data.total) * 100) : 0;

  return (
    <div>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }}>
        <div>
          <Title level={4} style={{ margin: 0 }}>AI 预热进度（App2 财务洞察）</Title>
          <Paragraph type="secondary" style={{ margin: 0, fontSize: 13 }}>
            监控 <code>app2_finance</code> 共 72 组合缓存覆盖率。cron <code>ai_dws_prewarm_1000</code> 每日 10:00 自动补齐。
          </Paragraph>
        </div>
        <Space>
          <Select
            value={siteId} onChange={setSiteId} style={{ width: 200 }}
            options={[{ label: "默认门店 (2790685415443269)", value: 2790685415443269 }]}
          />
          <Button icon={<ReloadOutlined />} onClick={load} loading={loading}>刷新</Button>
        </Space>
      </div>

      <Card size="small" style={{ marginBottom: 16 }}>
        <Descriptions column={4} size="small">
          <Descriptions.Item label="总完成度">
            <Text strong style={{ fontSize: 16 }}>{data?.done ?? 0} / {data?.total ?? 72}</Text>
          </Descriptions.Item>
          <Descriptions.Item label="全域 (app2_finance)">
            <Tag color={globalDone === 8 ? "success" : "warning"}>{globalDone} / 8</Tag>
          </Descriptions.Item>
          <Descriptions.Item label="区域 (app2a_finance_area)">
            <Tag color={areaDone === 64 ? "success" : "warning"}>{areaDone} / 64</Tag>
          </Descriptions.Item>
          <Descriptions.Item label="最近更新">{fmtTime(data?.last_updated ?? null)}</Descriptions.Item>
        </Descriptions>
        <div style={{ marginTop: 12 }}>
          <Progress
            percent={donePercent}
            status={donePercent === 100 ? "success" : "active"}
            strokeColor={{ from: "#108ee9", to: "#87d068" }}
          />
        </div>
        <Space style={{ marginTop: 16 }}>
          <Button
            type="primary" icon={<ThunderboltOutlined />}
            onClick={handleTriggerFullPrewarm}
          >触发全量预热</Button>
          <Button
            icon={<PlayCircleOutlined />}
            disabled={!data || data.missing.length === 0}
            onClick={() => setBackfillOpen(true)}
          >一键补齐缺失（{data?.missing.length ?? 0}）</Button>
        </Space>
      </Card>

      {backfillRunning && backfillProgress && (
        <Alert
          type="info" showIcon style={{ marginBottom: 16 }}
          message={`补齐进行中：${backfillProgress.done}/${backfillProgress.total} — ${backfillProgress.current}`}
        />
      )}

      <Card title={`缺失组合（${data?.missing.length ?? 0}） · 按全域 / 区域分组`} size="small">
        <Table<MissingRowWithGroup>
          columns={missingColumns}
          dataSource={groupedMissing}
          rowKey="target_id"
          loading={loading}
          pagination={{ pageSize: 30 }}
          size="small"
        />
      </Card>

      <Modal
        title="一键补齐缺失组合"
        open={backfillOpen}
        onCancel={() => setBackfillOpen(false)}
        onOk={handleBackfillMissing}
        okText="开始补齐" cancelText="取消"
      >
        <p>将串行调用 <code>POST /admin/ai/run/app2_finance</code>，逐个生成共 <strong>{data?.missing.length ?? 0}</strong> 条缓存。</p>
        <p>每条耗时约 30-120 秒，总耗时 <strong>{Math.ceil((data?.missing.length ?? 0) * 1.5)}</strong>~<strong>{Math.ceil((data?.missing.length ?? 0) * 2.5)}</strong> 分钟。</p>
        <p style={{ color: "#d46b08" }}>期间此标签页请保持打开，关闭会中断补齐。</p>
      </Modal>
    </div>
  );
};

export default AIPrewarm;
