/**
 * P18 任务引擎参数管理页面。
 *
 * 展示 biz.cfg_task_generator_params 全局默认 + 门店覆盖参数。
 * 超级管理员可编辑/新增/删除；门店管理员只读。
 * 权重参数（w_rs/w_ms/w_ml）以卡片形式整体编辑，后端联合校验。
 */

import React, { useEffect, useState, useCallback } from "react";
import {
  Table, Card, Typography, Button, Space, Tag, InputNumber,
  Modal, Select, Popconfirm, Tooltip, message,
} from "antd";
import {
  ReloadOutlined, SettingOutlined, PlusOutlined,
  EditOutlined, DeleteOutlined, SaveOutlined,
} from "@ant-design/icons";
import type { ColumnsType } from "antd/es/table";
import dayjs from "dayjs";
import {
  fetchConfigParams, updateConfigParam, createConfigParam, deleteConfigParam,
  type ConfigParam,
} from "../api/taskEngine";
import { useAuthStore } from "../store/authStore";

const { Title, Text } = Typography;

/** 参数中文描述映射 */
const PARAM_LABELS: Record<string, string> = {
  high_priority_recall_threshold: "高优先召回阈值",
  priority_recall_threshold: "优先召回阈值",
  rs_min_for_relationship: "关系构建 RS 下限",
  rs_max_for_relationship: "关系构建 RS 上限",
  consecutive_recall_fail_cycles: "连续失败触发转移轮数",
  min_wbi_for_transfer: "触发转移最低 WBI",
  guard_assistant_coverage_ratio: "助教绑定率保护阈值",
  guard_new_assistant_days: "新助教入驻保护天数",
  transfer_score_w_rs: "转移排序 RS 权重",
  transfer_score_w_ms: "转移排序 MS 权重",
  transfer_score_w_ml: "转移排序 ML 权重",
  max_transfer_count: "单客户最大转移次数",
  follow_up_visit_retention_hours: "回访任务保留时长(h)",
};

const WEIGHT_KEYS = ["transfer_score_w_rs", "transfer_score_w_ms", "transfer_score_w_ml"];

const TaskEngineConfig: React.FC = () => {
  const user = useAuthStore((s) => s.user);
  const isSuperAdmin = user?.roles?.includes("super_admin") ?? false;

  const [params, setParams] = useState<ConfigParam[]>([]);
  const [loading, setLoading] = useState(false);

  // 行内编辑
  const [editingId, setEditingId] = useState<number | null>(null);
  const [editValue, setEditValue] = useState<number>(0);
  const [saving, setSaving] = useState(false);

  // 新增弹窗
  const [addVisible, setAddVisible] = useState(false);
  const [addSiteId, setAddSiteId] = useState<number | null>(null);
  const [addKey, setAddKey] = useState<string>("");
  const [addValue, setAddValue] = useState<number>(0);
  const [adding, setAdding] = useState(false);

  // 权重卡片编辑
  const [weightVisible, setWeightVisible] = useState(false);
  const [weightSiteId, setWeightSiteId] = useState<number | null>(null);
  const [wRs, setWRs] = useState(0.5);
  const [wMs, setWMs] = useState(0.3);
  const [wMl, setWMl] = useState(0.2);
  const [weightSaving, setWeightSaving] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const data = await fetchConfigParams();
      setParams(data.params);
    } catch {
      message.error("加载参数配置失败");
    } finally {
      setLoading(false);
    }
  }, []);

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

  const handleSave = async () => {
    if (editingId == null) return;
    setSaving(true);
    try {
      await updateConfigParam(editingId, editValue);
      message.success("参数已更新");
      setEditingId(null);
      load();
    } catch (err: unknown) {
      const msg = (err as { response?: { data?: { detail?: string } } })?.response?.data?.detail;
      message.error(msg || "更新失败");
    } finally {
      setSaving(false);
    }
  };

  const handleAdd = async () => {
    if (!addSiteId || !addKey) return;
    setAdding(true);
    try {
      await createConfigParam(addSiteId, addKey, addValue);
      message.success("门店覆盖参数已添加");
      setAddVisible(false);
      setAddKey("");
      setAddValue(0);
      load();
    } catch (err: unknown) {
      const msg = (err as { response?: { data?: { detail?: string } } })?.response?.data?.detail;
      message.error(msg || "添加失败");
    } finally {
      setAdding(false);
    }
  };

  const handleDelete = async (paramId: number) => {
    try {
      await deleteConfigParam(paramId);
      message.success("门店覆盖已删除");
      load();
    } catch (err: unknown) {
      const msg = (err as { response?: { data?: { detail?: string } } })?.response?.data?.detail;
      message.error(msg || "删除失败");
    }
  };

  /** 打开权重卡片编辑弹窗 */
  const openWeightEditor = (siteId: number | null) => {
    const siteParams = params.filter(
      (p) => p.site_id === siteId && WEIGHT_KEYS.includes(p.param_key),
    );
    const findVal = (key: string) => siteParams.find((p) => p.param_key === key)?.param_value ?? 0;
    setWeightSiteId(siteId);
    setWRs(findVal("transfer_score_w_rs"));
    setWMs(findVal("transfer_score_w_ms"));
    setWMl(findVal("transfer_score_w_ml"));
    setWeightVisible(true);
  };

  const handleWeightSave = async () => {
    const sum = wRs + wMs + wMl;
    if (Math.abs(sum - 1.0) > 0.001) {
      message.error(`权重之和必须为 1.0，当前为 ${sum.toFixed(4)}`);
      return;
    }
    setWeightSaving(true);
    try {
      // 逐个更新三个权重参数
      const weightParams = params.filter(
        (p) => p.site_id === weightSiteId && WEIGHT_KEYS.includes(p.param_key),
      );
      const valMap: Record<string, number> = {
        transfer_score_w_rs: wRs,
        transfer_score_w_ms: wMs,
        transfer_score_w_ml: wMl,
      };
      for (const wp of weightParams) {
        await updateConfigParam(wp.id, valMap[wp.param_key]);
      }
      message.success("权重配置已更新");
      setWeightVisible(false);
      load();
    } catch (err: unknown) {
      const msg = (err as { response?: { data?: { detail?: string } } })?.response?.data?.detail;
      message.error(msg || "权重更新失败");
    } finally {
      setWeightSaving(false);
    }
  };

  const columns: ColumnsType<ConfigParam> = [
    {
      title: "参数", dataIndex: "param_key", key: "param_key", width: 220,
      render: (v: string) => (
        <Tooltip title={v}>
          <Text strong>{PARAM_LABELS[v] || v}</Text>
          <br />
          <Text type="secondary" style={{ fontSize: 11 }}>{v}</Text>
        </Tooltip>
      ),
    },
    {
      title: "门店", key: "site", width: 120,
      render: (_: unknown, r) => r.site_id == null
        ? <Tag color="blue">全局默认</Tag>
        : <span>{r.site_name || `#${r.site_id}`}</span>,
    },
    {
      title: "参数值", key: "value", width: 160,
      render: (_: unknown, r) => {
        if (editingId === r.id) {
          return (
            <Space>
              <InputNumber
                size="small"
                value={editValue}
                onChange={(v) => v != null && setEditValue(v)}
                step={WEIGHT_KEYS.includes(r.param_key) ? 0.01 : 1}
              />
              <Button size="small" type="primary" icon={<SaveOutlined />} loading={saving} onClick={handleSave} />
              <Button size="small" onClick={() => setEditingId(null)}>取消</Button>
            </Space>
          );
        }
        return <Text>{r.param_value}</Text>;
      },
    },
    {
      title: "说明", dataIndex: "description", key: "desc", width: 200,
      render: (v: string | null) => v || "—",
    },
    {
      title: "更新时间", dataIndex: "updated_at", key: "updated_at", width: 160,
      render: (v: string) => dayjs(v).format("YYYY-MM-DD HH:mm"),
    },
  ];

  if (isSuperAdmin) {
    columns.push({
      title: "操作", key: "action", width: 160, fixed: "right",
      render: (_: unknown, r) => {
        // 权重参数用卡片编辑
        if (WEIGHT_KEYS.includes(r.param_key)) {
          return (
            <Button
              size="small" icon={<EditOutlined />}
              onClick={() => openWeightEditor(r.site_id)}
            >
              权重编辑
            </Button>
          );
        }
        return (
          <Space size={4}>
            <Button
              size="small" icon={<EditOutlined />}
              onClick={() => { setEditingId(r.id); setEditValue(r.param_value); }}
            >
              编辑
            </Button>
            {r.site_id != null && (
              <Popconfirm title="确认删除此门店覆盖？" onConfirm={() => handleDelete(r.id)}>
                <Button size="small" danger icon={<DeleteOutlined />}>删除</Button>
              </Popconfirm>
            )}
          </Space>
        );
      },
    });
  }

  return (
    <div>
      <div style={{ marginBottom: 16, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <Title level={4} style={{ margin: 0 }}>
          <SettingOutlined style={{ marginRight: 8 }} />
          任务引擎参数管理
        </Title>
        <Space>
          {isSuperAdmin && (
            <Button type="primary" icon={<PlusOutlined />} onClick={() => setAddVisible(true)}>
              新增门店覆盖
            </Button>
          )}
          <Button icon={<ReloadOutlined />} onClick={load} loading={loading}>刷新</Button>
        </Space>
      </div>

      <Card size="small">
        <Table<ConfigParam>
          rowKey="id"
          columns={columns}
          dataSource={params}
          loading={loading}
          size="small"
          scroll={{ x: 1000 }}
          pagination={false}
        />
      </Card>

      {/* 新增门店覆盖弹窗 */}
      <Modal
        title="新增门店覆盖参数"
        open={addVisible}
        onOk={handleAdd}
        onCancel={() => setAddVisible(false)}
        confirmLoading={adding}
        okButtonProps={{ disabled: !addSiteId || !addKey }}
      >
        <Space direction="vertical" style={{ width: "100%" }}>
          <div>
            <Text>门店 ID：</Text>
            <InputNumber style={{ width: "100%" }} value={addSiteId} onChange={(v) => setAddSiteId(v)} />
          </div>
          <div>
            <Text>参数名：</Text>
            <Select
              style={{ width: "100%" }}
              value={addKey || undefined}
              onChange={(v) => setAddKey(v)}
              placeholder="选择参数"
              options={Object.entries(PARAM_LABELS).map(([k, label]) => ({ value: k, label: `${label} (${k})` }))}
            />
          </div>
          <div>
            <Text>参数值：</Text>
            <InputNumber style={{ width: "100%" }} value={addValue} onChange={(v) => v != null && setAddValue(v)} />
          </div>
        </Space>
      </Modal>

      {/* 权重卡片编辑弹窗 */}
      <Modal
        title={`权重配置${weightSiteId != null ? ` — 门店 #${weightSiteId}` : "（全局）"}`}
        open={weightVisible}
        onOk={handleWeightSave}
        onCancel={() => setWeightVisible(false)}
        confirmLoading={weightSaving}
      >
        <Text type="secondary" style={{ display: "block", marginBottom: 12 }}>
          三项权重之和必须等于 1.0（容差 0.001）
        </Text>
        <Space direction="vertical" style={{ width: "100%" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <Text style={{ width: 120 }}>RS 权重 (w_rs)：</Text>
            <InputNumber value={wRs} onChange={(v) => v != null && setWRs(v)} step={0.05} min={0} max={1} style={{ flex: 1 }} />
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <Text style={{ width: 120 }}>MS 权重 (w_ms)：</Text>
            <InputNumber value={wMs} onChange={(v) => v != null && setWMs(v)} step={0.05} min={0} max={1} style={{ flex: 1 }} />
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <Text style={{ width: 120 }}>ML 权重 (w_ml)：</Text>
            <InputNumber value={wMl} onChange={(v) => v != null && setWMl(v)} step={0.05} min={0} max={1} style={{ flex: 1 }} />
          </div>
          <div style={{ textAlign: "right", marginTop: 8 }}>
            <Text type={Math.abs(wRs + wMs + wMl - 1.0) > 0.001 ? "danger" : "success"}>
              当前合计：{(wRs + wMs + wMl).toFixed(4)}
            </Text>
          </div>
        </Space>
      </Modal>
    </div>
  );
};

export default TaskEngineConfig;
