/**
 * AI 手动操作页面。
 *
 * 4 个 Card 区域：
 * - Card 1：手动重跑（App + member_id + site_id → 执行）
 * - Card 2：缓存失效（app_type + member_id + site_id → 失效）
 * - Card 3：批量执行（app_types + member_ids + site_id → 预估 → 确认）
 * - Card 4：告警管理（告警列表 + 确认/忽略）
 */

import React, { useEffect, useState, useCallback } from "react";
import {
  Alert, Card, Row, Col, Select, Input, Button, Table, Tag, Space,
  Checkbox, Modal, Statistic, message, Typography,
} from "antd";
import { ReloadOutlined } from "@ant-design/icons";
import type { ColumnsType } from "antd/es/table";
import {
  retryTriggerJob, invalidateCache, createBatchRun, confirmBatchRun,
  getAlerts, ackAlert, ignoreAlert, runApp, triggerEvent,
  type AlertItem, type AppType, type BatchRunEstimate,
} from "../api/adminAI";
// F1-5a: sandbox 模式提示条数据源
import { fetchRuntimeContext, type RuntimeContext } from "../api/runtimeContext";

const EVENT_TYPE_OPTIONS = [
  { label: "消费事件（App3→App8→App7 [+ App4→App5]）", value: "consumption" },
  { label: "备注事件（App6→App8）", value: "note_created" },
  { label: "任务分配（App4→App5）", value: "task_assigned" },
  { label: "DWS 完成（App2 × 72 组合预热）", value: "dws_completed" },
];

const { TextArea } = Input;
const { Title } = Typography;

export const CACHE_TYPE_OPTIONS = [
  { label: "App3 维客线索", value: "app3_clue" },
  { label: "App4 关系分析", value: "app4_analysis" },
  { label: "App5 话术参考", value: "app5_tactics" },
  { label: "App6 备注分析", value: "app6_note_analysis" },
  { label: "App7 客户分析", value: "app7_customer_analysis" },
  { label: "App8 线索整理", value: "app8_clue_consolidated" },
];

export const RUN_APP_TYPE_OPTIONS: { label: string; value: AppType }[] = [
  { label: "App3 维客线索", value: "app3_clue" },
  { label: "App4 关系分析", value: "app4_analysis" },
  { label: "App5 话术参考", value: "app5_tactics" },
  { label: "App6 备注分析", value: "app6_note" },
  { label: "App7 客户分析", value: "app7_customer" },
  { label: "App8 线索整理", value: "app8_consolidation" },
];

const ALERT_STATUS_COLOR: Record<string, string> = {
  failed: "red", timeout: "orange", circuit_open: "volcano",
};

const ALERT_MGMT_COLOR: Record<string, string> = {
  pending: "warning", acknowledged: "success", ignored: "default",
};

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

const AIOperations: React.FC = () => {
  // ---- Card 1: 手动重跑 ----
  const [retryJobId, setRetryJobId] = useState<string>("");
  const [retryLoading, setRetryLoading] = useState(false);

  const handleRetry = async () => {
    const id = Number(retryJobId);
    if (!id || Number.isNaN(id)) { message.warning("请输入有效的任务 ID"); return; }
    setRetryLoading(true);
    try {
      const res = await retryTriggerJob(id);
      message.success(`已创建重跑任务 #${res.trigger_job_id}`);
      setRetryJobId("");
    } catch {
      message.error("重跑失败");
    } finally {
      setRetryLoading(false);
    }
  };

  // ---- Card 2: 缓存失效 ----
  const [cacheAppType, setCacheAppType] = useState<string | undefined>();
  const [cacheMemberId, setCacheMemberId] = useState<string>("");
  const [cacheSiteId, setCacheSiteId] = useState<number>(2790685415443269);
  const [cacheLoading, setCacheLoading] = useState(false);
  const [cacheResult, setCacheResult] = useState<number | null>(null);

  const handleInvalidate = async () => {
    setCacheLoading(true);
    setCacheResult(null);
    try {
      const res = await invalidateCache({
        site_id: cacheSiteId,
        app_type: cacheAppType,
        member_id: cacheMemberId ? Number(cacheMemberId) : undefined,
      });
      setCacheResult(res.affected_count);
      message.success(`已失效 ${res.affected_count} 条缓存`);
    } catch {
      message.error("缓存失效操作失败");
    } finally {
      setCacheLoading(false);
    }
  };

  // ---- Card 2.5: 按需重新生成 ----
  const [runAppType, setRunAppType] = useState<AppType | undefined>();
  const [runMemberId, setRunMemberId] = useState<string>("");
  const [runSiteId, setRunSiteId] = useState<number>(2790685415443269);
  const [runLoading, setRunLoading] = useState(false);
  const [runResult, setRunResult] = useState<{ success: boolean; text: string } | null>(null);

  const handleRunApp = async () => {
    if (!runAppType) { message.warning("请选择 App 类型"); return; }
    setRunLoading(true);
    setRunResult(null);
    try {
      const res = await runApp(runAppType, {
        site_id: runSiteId,
        member_id: runMemberId ? Number(runMemberId) : undefined,
      });
      if (res.success) {
        setRunResult({ success: true, text: "执行成功，缓存已更新" });
        message.success("执行成功");
      } else {
        setRunResult({ success: false, text: res.error ?? "执行失败" });
        message.error(res.error ?? "执行失败");
      }
    } catch {
      message.error("请求失败");
    } finally {
      setRunLoading(false);
    }
  };

  // ---- Card 2.6: 手动触发事件链（越过去重）----
  const [evtType, setEvtType] = useState<string>("consumption");
  const [evtSiteId, setEvtSiteId] = useState<number>(2790685415443269);
  const [evtMemberId, setEvtMemberId] = useState<string>("");
  const [evtAssistantId, setEvtAssistantId] = useState<string>("");
  const [evtForced, setEvtForced] = useState<boolean>(true);
  const [evtLoading, setEvtLoading] = useState(false);
  const [evtResult, setEvtResult] = useState<number | null>(null);

  const handleTriggerEvent = async () => {
    if (!evtType) { message.warning("请选择事件类型"); return; }
    setEvtLoading(true);
    setEvtResult(null);
    try {
      const res = await triggerEvent({
        event_type: evtType,
        site_id: evtSiteId,
        member_id: evtMemberId ? Number(evtMemberId) : undefined,
        assistant_id: evtAssistantId ? Number(evtAssistantId) : undefined,
        is_forced: evtForced,
      });
      setEvtResult(res.trigger_job_id);
      message.success(`事件已触发，job_id=${res.trigger_job_id}（后台异步执行）`);
    } catch {
      message.error("触发失败");
    } finally {
      setEvtLoading(false);
    }
  };

  // ---- Card 3: 批量执行 ----
  const [batchAppTypes, setBatchAppTypes] = useState<AppType[]>([]);
  const [batchMemberIds, setBatchMemberIds] = useState<string>("");
  const [batchSiteId, setBatchSiteId] = useState<number>(2790685415443269);
  const [batchLoading, setBatchLoading] = useState(false);
  const [batchEstimate, setBatchEstimate] = useState<BatchRunEstimate | null>(null);
  const [confirmVisible, setConfirmVisible] = useState(false);
  const [confirmLoading, setConfirmLoading] = useState(false);

  const parseMemberIds = (text: string): number[] =>
    text.split(/[\n,;\s]+/).map(Number).filter((n) => !Number.isNaN(n) && n > 0);

  const handleBatchEstimate = async () => {
    const memberIds = parseMemberIds(batchMemberIds);
    if (batchAppTypes.length === 0) { message.warning("请选择至少一个 App"); return; }
    if (memberIds.length === 0) { message.warning("请输入有效的会员 ID"); return; }
    setBatchLoading(true);
    try {
      const res = await createBatchRun({ app_types: batchAppTypes, member_ids: memberIds, site_id: batchSiteId });
      setBatchEstimate(res);
      setConfirmVisible(true);
    } catch {
      message.error("预估失败");
    } finally {
      setBatchLoading(false);
    }
  };

  const handleBatchConfirm = async () => {
    if (!batchEstimate) return;
    setConfirmLoading(true);
    try {
      await confirmBatchRun(batchEstimate.batch_id);
      message.success("批量执行已启动");
      setConfirmVisible(false);
      setBatchEstimate(null);
      setBatchAppTypes([]);
      setBatchMemberIds("");
    } catch {
      message.error("确认执行失败");
    } finally {
      setConfirmLoading(false);
    }
  };

  // ---- F1-5a: Sandbox 模式提示条 ----
  // 沙箱机制 P0-7 主线:让运维进入 AI 操作页前能看到当前 sandbox 状态,
  // 避免"以为 live 模式"误触发批量执行实际跑在 sandbox 数据集上的混淆。
  const [runtimeCtx, setRuntimeCtx] = useState<RuntimeContext | null>(null);
  useEffect(() => {
    // 复用 cacheSiteId 作为当前关注 site(默认 2790685415443269,与 cacheSiteId / runSiteId 一致)
    let cancelled = false;
    (async () => {
      try {
        const ctx = await fetchRuntimeContext(cacheSiteId);
        if (!cancelled) setRuntimeCtx(ctx);
      } catch {
        // 失败不阻断页面渲染(get_runtime_context 表不存在时后端降级 live)
      }
    })();
    return () => { cancelled = true; };
  }, [cacheSiteId]);

  // ---- Card 4: 告警管理 ----
  const [alerts, setAlerts] = useState<AlertItem[]>([]);
  const [alertTotal, setAlertTotal] = useState(0);
  const [alertLoading, setAlertLoading] = useState(false);
  const [alertPage, setAlertPage] = useState(1);

  const loadAlerts = useCallback(async () => {
    setAlertLoading(true);
    try {
      const res = await getAlerts({ page: alertPage, page_size: 10 });
      setAlerts(res.items);
      setAlertTotal(res.total);
    } catch {
      message.error("加载告警列表失败");
    } finally {
      setAlertLoading(false);
    }
  }, [alertPage]);

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

  const handleAck = async (id: number) => {
    try {
      await ackAlert(id);
      message.success("已确认告警");
      loadAlerts();
    } catch {
      message.error("确认失败");
    }
  };

  const handleIgnore = async (id: number) => {
    try {
      await ignoreAlert(id);
      message.success("已忽略告警");
      loadAlerts();
    } catch {
      message.error("忽略失败");
    }
  };

  const alertColumns: ColumnsType<AlertItem> = [
    { title: "ID", dataIndex: "id", key: "id", width: 70 },
    { title: "App", dataIndex: "app_type", key: "app_type", width: 150 },
    {
      title: "状态", dataIndex: "status", key: "status", width: 100,
      render: (v: string) => <Tag color={ALERT_STATUS_COLOR[v] ?? "default"}>{v}</Tag>,
    },
    {
      title: "告警状态", dataIndex: "alert_status", key: "alert_status", width: 100,
      render: (v: string | null) => v ? <Tag color={ALERT_MGMT_COLOR[v] ?? "default"}>{v}</Tag> : "—",
    },
    { title: "错误信息", dataIndex: "error_message", key: "error_message", ellipsis: true, render: (v) => v ?? "—" },
    { title: "时间", dataIndex: "created_at", key: "created_at", width: 160, render: fmtTime },
    {
      title: "操作", key: "action", width: 140,
      render: (_: unknown, r: AlertItem) => (
        <Space>
          <Button size="small" onClick={() => handleAck(r.id)} disabled={r.alert_status === "acknowledged"}>确认</Button>
          <Button size="small" onClick={() => handleIgnore(r.id)} disabled={r.alert_status === "ignored"}>忽略</Button>
        </Space>
      ),
    },
  ];

  return (
    <div>
      <Title level={4} style={{ marginBottom: 16 }}>AI 手动操作</Title>

      {runtimeCtx && runtimeCtx.is_sandbox && (
        <Alert
          type="warning"
          showIcon
          style={{ marginBottom: 16 }}
          message={
            <span>
              <strong>沙箱模式</strong> · 业务日 <strong>{runtimeCtx.sandbox_date ?? "—"}</strong> ·
              实例 <code>{runtimeCtx.sandbox_instance_id ?? "—"}</code>
            </span>
          }
          description={
            <span>
              当前 site_id={cacheSiteId} 处于沙箱模式。本页所有 AI 触发(手动重跑 / 缓存失效 / 按需执行 / 批量执行)将使用
              沙箱业务日 ({runtimeCtx.sandbox_date}) 而非真实今日;ETL 视图自动按业务日上界裁剪,助教/会员消费数据仅可见
              沙箱日及之前。结果写入 ai_run_logs 时 runtime_mode=sandbox + sandbox_instance_id 隔离,
              不污染 live 数据。如需切回 live,前往 <a href="/settings/runtime-context">运行上下文</a> 页。
            </span>
          }
        />
      )}

      <Row gutter={16} style={{ marginBottom: 16 }}>
        {/* Card 1: 手动重跑 */}
        <Col span={12}>
          <Card title="手动重跑" size="small">
            <Space direction="vertical" style={{ width: "100%" }}>
              <Input
                placeholder="调度任务 ID" value={retryJobId}
                onChange={(e) => setRetryJobId(e.target.value)}
              />
              <Button type="primary" onClick={handleRetry} loading={retryLoading}>执行重跑</Button>
            </Space>
          </Card>
        </Col>

        {/* Card 2: 缓存失效 */}
        <Col span={12}>
          <Card title="缓存失效" size="small">
            <Space direction="vertical" style={{ width: "100%" }}>
              <Select
                allowClear placeholder="App 类型（可选）" style={{ width: "100%" }}
                value={cacheAppType} onChange={setCacheAppType}
                options={CACHE_TYPE_OPTIONS}
              />
              <Input
                placeholder="会员 ID（可选）" value={cacheMemberId}
                onChange={(e) => setCacheMemberId(e.target.value)}
              />
              <Select
                placeholder="门店" style={{ width: "100%" }}
                value={cacheSiteId} onChange={setCacheSiteId}
                options={[{ label: "默认门店", value: 2790685415443269 }]}
              />
              <Space>
                <Button type="primary" danger onClick={handleInvalidate} loading={cacheLoading}>执行失效</Button>
                {cacheResult != null && <Statistic title="受影响记录" value={cacheResult} />}
              </Space>
            </Space>
          </Card>
        </Col>
      </Row>

      {/* Card 2.5: 按需重新生成 */}
      <Card title="按需重新生成" size="small" style={{ marginBottom: 16 }}>
        <Row gutter={16}>
          <Col span={6}>
            <Select
              allowClear placeholder="App 类型" style={{ width: "100%" }}
              value={runAppType} onChange={setRunAppType}
              options={RUN_APP_TYPE_OPTIONS}
            />
          </Col>
          <Col span={6}>
            <Input
              placeholder="会员 ID（部分 App 必填）" value={runMemberId}
              onChange={(e) => setRunMemberId(e.target.value)}
            />
          </Col>
          <Col span={6}>
            <Select
              placeholder="门店" style={{ width: "100%" }}
              value={runSiteId} onChange={setRunSiteId}
              options={[{ label: "默认门店", value: 2790685415443269 }]}
            />
          </Col>
          <Col span={6}>
            <Space>
              <Button type="primary" onClick={handleRunApp} loading={runLoading}>立即执行</Button>
              {runResult && (
                <Tag color={runResult.success ? "success" : "error"}>{runResult.text}</Tag>
              )}
            </Space>
          </Col>
        </Row>
      </Card>

      {/* Card 2.6: 手动触发事件链（越过去重，调试利器）*/}
      <Card
        title="手动触发事件链（调试用）" size="small" style={{ marginBottom: 16 }}
        extra={<Tag color="orange">默认跳过去重</Tag>}
      >
        <Row gutter={12}>
          <Col span={6}>
            <div style={{ marginBottom: 4, fontSize: 12, color: "#888" }}>事件类型</div>
            <Select
              value={evtType} onChange={setEvtType}
              options={EVENT_TYPE_OPTIONS}
              style={{ width: "100%" }}
            />
          </Col>
          <Col span={5}>
            <div style={{ marginBottom: 4, fontSize: 12, color: "#888" }}>门店</div>
            <Select
              value={evtSiteId} onChange={setEvtSiteId}
              options={[{ label: "默认门店", value: 2790685415443269 }]}
              style={{ width: "100%" }}
            />
          </Col>
          <Col span={4}>
            <div style={{ marginBottom: 4, fontSize: 12, color: "#888" }}>member_id（可选）</div>
            <Input
              placeholder="consumption/note/task 事件需填"
              value={evtMemberId}
              onChange={(e) => setEvtMemberId(e.target.value)}
            />
          </Col>
          <Col span={4}>
            <div style={{ marginBottom: 4, fontSize: 12, color: "#888" }}>assistant_id（可选）</div>
            <Input
              placeholder="task_assigned 事件需填"
              value={evtAssistantId}
              onChange={(e) => setEvtAssistantId(e.target.value)}
            />
          </Col>
          <Col span={5}>
            <div style={{ marginBottom: 4, fontSize: 12, color: "#888" }}>跳过去重 + 操作</div>
            <Space>
              <Checkbox checked={evtForced} onChange={(e) => setEvtForced(e.target.checked)}>强制</Checkbox>
              <Button type="primary" danger onClick={handleTriggerEvent} loading={evtLoading}>触发</Button>
              {evtResult != null && <Tag color="processing">job #{evtResult}</Tag>}
            </Space>
          </Col>
        </Row>
      </Card>

      {/* Card 3: 批量执行 */}
      <Card title="批量执行" size="small" style={{ marginBottom: 16 }}>
        <Row gutter={16}>
          <Col span={8}>
            <div style={{ marginBottom: 8, fontWeight: 500 }}>选择 App</div>
            <Checkbox.Group
              options={RUN_APP_TYPE_OPTIONS}
              value={batchAppTypes}
              onChange={(v) => setBatchAppTypes(v as AppType[])}
              style={{ display: "flex", flexDirection: "column", gap: 4 }}
            />
          </Col>
          <Col span={8}>
            <div style={{ marginBottom: 8, fontWeight: 500 }}>会员 ID（每行一个或逗号分隔）</div>
            <TextArea
              rows={6} value={batchMemberIds}
              onChange={(e) => setBatchMemberIds(e.target.value)}
              placeholder="例如：&#10;12345&#10;67890"
            />
          </Col>
          <Col span={8}>
            <div style={{ marginBottom: 8, fontWeight: 500 }}>门店</div>
            <Select
              style={{ width: "100%", marginBottom: 16 }}
              value={batchSiteId} onChange={setBatchSiteId}
              options={[{ label: "默认门店", value: 2790685415443269 }]}
            />
            <Button type="primary" onClick={handleBatchEstimate} loading={batchLoading}>
              预估并执行
            </Button>
          </Col>
        </Row>
      </Card>

      {/* 批量执行确认弹窗 */}
      <Modal
        title="确认批量执行"
        open={confirmVisible}
        onCancel={() => { setConfirmVisible(false); setBatchEstimate(null); }}
        onOk={handleBatchConfirm}
        confirmLoading={confirmLoading}
        okText="确认执行" cancelText="取消"
      >
        {batchEstimate && (
          <Row gutter={16}>
            <Col span={12}>
              <Statistic title="预估调用次数" value={batchEstimate.estimated_calls} suffix="次" />
            </Col>
            <Col span={12}>
              <Statistic title="预估 Token 消耗" value={batchEstimate.estimated_tokens} />
            </Col>
          </Row>
        )}
        <p style={{ marginTop: 16, color: "#faad14" }}>
          确认后将在后台异步执行，请确保预算充足。
        </p>
      </Modal>

      {/* Card 4: 告警管理 */}
      <Card
        title="告警管理" size="small"
        extra={<Button icon={<ReloadOutlined />} size="small" onClick={loadAlerts}>刷新</Button>}
      >
        <Table<AlertItem>
          columns={alertColumns}
          dataSource={alerts}
          rowKey="id" size="small"
          loading={alertLoading}
          pagination={{
            current: alertPage, pageSize: 10, total: alertTotal,
            onChange: (p) => setAlertPage(p),
            showTotal: (t) => `共 ${t} 条`,
          }}
        />
      </Card>
    </div>
  );
};

export default AIOperations;
