import { useMemo, useState } from "react";
import { toPageQuery } from "@/shared/api/query";
import { usePaginatedQuery } from "@/shared/hooks/usePaginatedQuery.js";
import { useRegionOptions } from "@/shared/hooks/useRegionOptions.js";
import { parseForm } from "@/shared/forms/validation";
import { useToast } from "@/shared/ui/ToastProvider.jsx";
import {
    createHostAgencyPolicy,
    deleteHostAgencyPolicy,
    listHostAgencyPolicies,
    publishHostAgencyPolicy,
    updateHostAgencyPolicy,
} from "@/features/host-agency-policy/api";
import { useHostAgencyPolicyAbilities } from "@/features/host-agency-policy/permissions.js";
import {
    residualDiamondsPerUsdToRate,
    residualRateToDiamondsPerUsd,
} from "@/features/host-agency-policy/residualRate.js";
import { hostAgencyPolicyFormSchema } from "@/features/host-agency-policy/schema";

const pageSize = 50;

// 产品文档给出的 Lalu 首版等级表：每项分别是等级、钻石门槛、主播累计美元、主播累计金币奖励、代理累计美元。
// 这些值只用于“新建政策”的表单预填，编辑已有政策时始终以后端返回的配置为准。
const defaultLevels = [
    [1, 350000, "1.5", 90000, "0.5"],
    [2, 700000, "3", 198000, "0.8"],
    [3, 1180000, "4", 350000, "1.3"],
    [4, 1770000, "6", 531000, "1.6"],
    [5, 2660000, "9", 800000, "2.5"],
    [6, 4000000, "13", 1200000, "4"],
    [7, 6000000, "20", 1800000, "6"],
    [8, 9000000, "30", 2700000, "9"],
    [9, 13500000, "45", 4050000, "13"],
    [10, 20260000, "67", 6078000, "19"],
    [11, 30390000, "100", 9200000, "29"],
    [12, 45590000, "152", 13600000, "43"],
    [13, 68380000, "182", 25000000, "65"],
    [14, 102580000, "342", 30700000, "97"],
    [15, 153870000, "513", 46000000, "146"],
    [16, 230800000, "768", 69200000, "219"],
    [17, 346200000, "1151", 103800000, "328"],
    [18, 519310000, "1727", 155700000, "493"],
    [19, 778970000, "2589", 233700000, "739"],
    [20, 1168450000, "3884", 350500000, "1108"],
    [21, 1752680000, "5826", 525800000, "1165"],
    [22, 2629030000, "8739", 788700000, "2494"],
    [23, 3943540000, "13109", 1183000000, "3741"],
    [24, 5915310000, "19664", 1774500000, "5611"],
];

const emptyForm = (policy = null) => ({
    // 后端用 epoch ms 保存生效范围；表单里用空字符串表示“未设置”，方便时间控件展示占位。
    effectiveFrom: normalizeTimeMs(policy?.effectiveFromMs),
    effectiveTo: normalizeTimeMs(policy?.effectiveToMs),
    // 新建默认停用，运营保存草稿后再手动启用，避免半配置状态影响结算匹配。
    enabled: policy ? policy.status === "active" : false,
    // 编辑时保留后端等级；新建时一次铺满 24 个默认等级，减少运营逐级录入成本。
    levels: policy?.levels?.length ? policy.levels.map(levelToForm) : defaultLevels.map(defaultLevelToForm),
    name: policy?.name || "Lalu Host & Agency Salary Policy",
    regionId: policy?.regionId ? String(policy.regionId) : "",
    residualDiamondsPerUsd: residualRateToDiamondsPerUsd(policy?.residualDiamondToUsdRate || "0"),
    settlementMode: policy?.settlementMode || "daily",
    settlementTriggerMode: policy?.settlementTriggerMode || "automatic",
});

export function useHostAgencyPolicyPage() {
    const abilities = useHostAgencyPolicyAbilities();
    const { showToast } = useToast();
    const { loadingRegions, regionOptions } = useRegionOptions();
    const [query, setQuery] = useState("");
    const [regionId, setRegionId] = useState("");
    const [status, setStatus] = useState("");
    const [settlementMode, setSettlementMode] = useState("");
    const [settlementTriggerMode, setSettlementTriggerMode] = useState("");
    const [page, setPage] = useState(1);
    const [form, setForm] = useState(() => emptyForm());
    const [editingPolicy, setEditingPolicy] = useState(null);
    const [drawerOpen, setDrawerOpen] = useState(false);
    const [loadingAction, setLoadingAction] = useState("");
    // 列表筛选和表单状态分开维护，避免打开抽屉编辑时污染当前列表查询条件。
    const filters = useMemo(
        () => ({
            keyword: query,
            region_id: regionId,
            settlement_mode: settlementMode,
            settlement_trigger_mode: settlementTriggerMode,
            status,
        }),
        [query, regionId, settlementMode, settlementTriggerMode, status],
    );
    const result = usePaginatedQuery({
        errorMessage: "加载工资政策失败",
        fetcher: listHostAgencyPolicies,
        filters,
        page,
        pageSize,
        // queryKey 带上规整后的分页参数，筛选项变化时能稳定触发重新请求。
        queryKey: ["host-agency-policy", toPageQuery({ ...filters, page, pageSize })],
    });
    const regionLabels = useMemo(
        () =>
            regionOptions.reduce((labels, item) => {
                // 后端只返回 region_id，页面展示名称依赖区域配置接口做本地映射。
                labels[Number(item.regionId)] = item.label;
                return labels;
            }, {}),
        [regionOptions],
    );

    const openCreate = () => {
        setEditingPolicy(null);
        setForm(emptyForm());
        setDrawerOpen(true);
    };

    const openEdit = (policy) => {
        setEditingPolicy(policy);
        setForm(emptyForm(policy));
        setDrawerOpen(true);
    };

    const closeDrawer = () => {
        setDrawerOpen(false);
        setEditingPolicy(null);
    };

    const submitPolicy = async (event) => {
        event.preventDefault();
        const editing = Boolean(editingPolicy?.id);
        await runAction(
            editing ? "policy-update" : "policy-create",
            editing ? "工资政策已更新" : "工资政策已创建",
            async () => {
                // 保存前先跑前端 schema，尽早拦截等级递增和金额格式问题；后端仍保留同款强校验。
                const payload = buildPayload(parseForm(hostAgencyPolicyFormSchema, form));
                if (editing) {
                    await updateHostAgencyPolicy(editingPolicy.id, payload);
                } else {
                    await createHostAgencyPolicy(payload);
                }
                closeDrawer();
                setForm(emptyForm());
                await result.reload();
            },
        );
    };

    const removePolicy = async (policy) => {
        if (!policy?.id || !abilities.canDelete) {
            return;
        }
        await runAction(`policy-delete-${policy.id}`, "工资政策已删除", async () => {
            await deleteHostAgencyPolicy(policy.id);
            await result.reload();
        });
    };

    const publishPolicy = async (policy) => {
        if (!policy?.id || !abilities.canPublish) {
            return;
        }
        await runAction(`policy-publish-${policy.id}`, "工资政策已发布到结算运行表", async () => {
            // 发布是后台草稿配置到 wallet 运行快照的唯一入口，结算任务只读取发布后的运行表。
            await publishHostAgencyPolicy(policy.id);
            await result.reload();
        });
    };

    const togglePolicyStatus = async (policy, nextEnabled = policy.status !== "active") => {
        if (!policy?.id || !abilities.canUpdate || (policy.status === "active") === nextEnabled) {
            return;
        }
        await runAction(`policy-status-${policy.id}`, nextEnabled ? "工资政策已启用" : "工资政策已停用", async () => {
            // 启停只改变 status，其余字段走完整 payload，确保后端 PUT 整包替换时不会丢等级配置。
            await updateHostAgencyPolicy(policy.id, buildPayload({ ...emptyForm(policy), enabled: nextEnabled }));
            await result.reload();
        });
    };

    const resetFilters = () => {
        setQuery("");
        setRegionId("");
        setStatus("");
        setSettlementMode("");
        setSettlementTriggerMode("");
        setPage(1);
    };

    const updateLevel = (index, patch) => {
        // 等级表使用受控数组，单格编辑只更新当前行，保存时再统一排序和校验。
        setForm((current) => ({
            ...current,
            levels: current.levels.map((level, levelIndex) => (levelIndex === index ? { ...level, ...patch } : level)),
        }));
    };

    const addLevel = () => {
        setForm((current) => {
            const last = current.levels[current.levels.length - 1];
            const nextLevel = Number(last?.level || current.levels.length) + 1;
            // 新增等级沿用上一行金额作为起点，运营只需要调整差异字段；最终递增规则仍由 schema/backend 保底。
            return {
                ...current,
                levels: [
                    ...current.levels,
                    {
                        agencySalaryUsd: last?.agencySalaryUsd || "0",
                        hostCoinReward: last?.hostCoinReward || "0",
                        hostSalaryUsd: last?.hostSalaryUsd || "0",
                        level: String(nextLevel),
                        requiredDiamonds: "",
                        sortOrder: String(nextLevel),
                        status: "active",
                    },
                ],
            };
        });
    };

    const removeLevel = (index) => {
        setForm((current) => ({
            ...current,
            levels: current.levels.filter((_, levelIndex) => levelIndex !== index),
        }));
    };

    const runAction = async (action, successMessage, submitter) => {
        // loadingAction 带资源 ID，删除/启停这类行内操作不会把整页按钮全部锁死。
        setLoadingAction(action);
        try {
            await submitter();
            showToast(successMessage, "success");
        } catch (err) {
            showToast(err.message || "操作失败", "error");
        } finally {
            setLoadingAction("");
        }
    };

    return {
        abilities,
        addLevel,
        changeQuery: (value) => {
            setQuery(value);
            setPage(1);
        },
        changeRegionId: (value) => {
            setRegionId(value);
            setPage(1);
        },
        changeSettlementMode: (value) => {
            setSettlementMode(value);
            setPage(1);
        },
        changeSettlementTriggerMode: (value) => {
            setSettlementTriggerMode(value);
            setPage(1);
        },
        changeStatus: (value) => {
            setStatus(value);
            setPage(1);
        },
        closeDrawer,
        data: result.data,
        drawerOpen,
        editingPolicy,
        error: result.error,
        form,
        loading: result.loading,
        loadingAction,
        loadingRegions,
        openCreate,
        openEdit,
        page,
        publishPolicy,
        query,
        regionId,
        regionLabels,
        regionOptions,
        reload: result.reload,
        removeLevel,
        removePolicy,
        resetFilters,
        setForm,
        setPage,
        settlementMode,
        settlementTriggerMode,
        status,
        submitPolicy,
        togglePolicyStatus,
        updateLevel,
    };
}

function levelToForm(level) {
    // 接口层已经把 snake_case 转成 camelCase，这里只负责把数值转成输入框友好的字符串。
    return {
        agencySalaryUsd: level.agencySalaryUsd || "0",
        hostCoinReward: String(level.hostCoinReward || 0),
        hostSalaryUsd: level.hostSalaryUsd || "0",
        level: String(level.level || ""),
        requiredDiamonds: String(level.requiredDiamonds || ""),
        sortOrder: String(level.sortOrder || level.level || ""),
        status: level.status || "active",
    };
}

function defaultLevelToForm([level, requiredDiamonds, hostSalaryUsd, hostCoinReward, agencySalaryUsd]) {
    // 默认模板中的工资和奖励都是累计值，不是本等级增量；实际差额由后续结算任务计算。
    return {
        agencySalaryUsd,
        hostCoinReward: String(hostCoinReward),
        hostSalaryUsd,
        level: String(level),
        requiredDiamonds: String(requiredDiamonds),
        sortOrder: String(level),
        status: "active",
    };
}

function buildPayload(form) {
    // 后端接口使用 snake_case；这里是唯一的表单 -> API payload 转换边界。
    return {
        effective_from_ms: timeValueToMs(form.effectiveFrom),
        effective_to_ms: timeValueToMs(form.effectiveTo),
        // 主播周期钻石入账比例由“礼物钻石”配置页控制；工资政策不再提供第二套可编辑比例。
        gift_coin_to_diamond_ratio: "1",
        levels: form.levels
            .map((level) => ({
                // 保存等级时统一转 number，避免字符串数字进入后端后造成弱类型歧义。
                agency_salary_usd: String(level.agencySalaryUsd || "0").trim(),
                host_coin_reward: Number(level.hostCoinReward || 0),
                host_salary_usd: String(level.hostSalaryUsd || "0").trim(),
                level: Number(level.level || 0),
                required_diamonds: Number(level.requiredDiamonds || 0),
                sort_order: Number(level.sortOrder || level.level || 0),
                status: level.status || "active",
            }))
            // 后端也会排序校验，前端先排序可以让保存后的返回和当前表单顺序更一致。
            .sort((left, right) => left.level - right.level),
        name: String(form.name || "").trim(),
        region_id: Number(form.regionId || 0),
        residual_diamond_to_usd_rate: residualDiamondsPerUsdToRate(form.residualDiamondsPerUsd),
        settlement_mode: form.settlementMode || "daily",
        // 触发方式会被发布到 wallet 运行表；manual 表示后续只能从工资结算页人工触发。
        settlement_trigger_mode: form.settlementTriggerMode || "automatic",
        status: form.enabled ? "active" : "disabled",
    };
}

function normalizeTimeMs(value) {
    const ms = Number(value || 0);
    return Number.isFinite(ms) && ms > 0 ? ms : "";
}

function timeValueToMs(value) {
    if (value === "" || value === null || value === undefined) {
        return 0;
    }
    const number = Number(value);
    if (Number.isFinite(number) && number > 0) {
        return number;
    }
    return 0;
}
