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 {
    createTeamSalaryPolicy,
    deleteTeamSalaryPolicy,
    listTeamSalaryPolicies,
    updateTeamSalaryPolicy,
} from "@/features/host-agency-policy/api";
import { useHostAgencyPolicyAbilities } from "@/features/host-agency-policy/permissions.js";
import { teamSalaryPolicyFormSchema } from "@/features/host-agency-policy/schema";

const pageSize = 50;

const defaultLevelsByType = {
    // BD 门槛来自下属 Agency 管理主播的 Host Salary 合计，工资字段是达到该门槛后的 BD 累计应得。
    bd: [
        [1, "100", "8", "8"],
        [2, "200", "8", "16"],
        [3, "500", "8", "40"],
        [4, "1200", "8", "96"],
        [5, "2000", "8", "160"],
        [6, "5000", "9", "450"],
        [7, "10000", "10", "1000"],
    ],
    // Admin 门槛来自下属 BD 的 BD Salary 合计，工资字段是达到该门槛后的 Admin 累计应得。
    admin: [
        [1, "500", "20", "100"],
        [2, "1000", "20", "200"],
        [3, "3000", "20", "600"],
        [4, "5000", "20", "1000"],
        [5, "10000", "20", "2000"],
        [6, "20000", "20", "4000"],
    ],
};

const emptyForm = (policyType, policy = null) => ({
    effectiveFrom: normalizeTimeMs(policy?.effectiveFromMs),
    effectiveTo: normalizeTimeMs(policy?.effectiveToMs),
    enabled: policy ? policy.status === "active" : false,
    levels: policy?.levels?.length
        ? policy.levels.map(levelToForm)
        : defaultLevelsByType[policyType].map(defaultLevelToForm),
    name: policy?.name || defaultPolicyName(policyType),
    policyType,
    regionId: policy?.regionId ? String(policy.regionId) : "",
    settlementTriggerMode: policy?.settlementTriggerMode || "automatic",
});

export function useTeamSalaryPolicyPage(policyType) {
    const abilities = useHostAgencyPolicyAbilities();
    const { showToast } = useToast();
    const { loadingRegions, regionOptions } = useRegionOptions();
    const [query, setQuery] = useState("");
    const [regionId, setRegionId] = useState("");
    const [status, setStatus] = useState("");
    const [settlementTriggerMode, setSettlementTriggerMode] = useState("");
    const [page, setPage] = useState(1);
    const [form, setForm] = useState(() => emptyForm(policyType));
    const [editingPolicy, setEditingPolicy] = useState(null);
    const [drawerOpen, setDrawerOpen] = useState(false);
    const [loadingAction, setLoadingAction] = useState("");
    const filters = useMemo(
        () => ({
            keyword: query,
            policy_type: policyType,
            region_id: regionId,
            settlement_trigger_mode: settlementTriggerMode,
            status,
        }),
        [policyType, query, regionId, settlementTriggerMode, status],
    );
    const result = usePaginatedQuery({
        errorMessage: policyType === "bd" ? "加载 BD 工资政策失败" : "加载 Admin 工资政策失败",
        fetcher: listTeamSalaryPolicies,
        filters,
        page,
        pageSize,
        queryKey: ["team-salary-policy", policyType, toPageQuery({ ...filters, page, pageSize })],
    });
    const regionLabels = useMemo(
        () =>
            regionOptions.reduce((labels, item) => {
                labels[Number(item.regionId)] = item.label;
                return labels;
            }, {}),
        [regionOptions],
    );

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

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

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

    const submitPolicy = async (event) => {
        event.preventDefault();
        const editing = Boolean(editingPolicy?.id);
        await runAction(
            editing ? "team-policy-update" : "team-policy-create",
            editing ? "工资政策已更新" : "工资政策已创建",
            async () => {
                const payload = buildPayload(parseForm(teamSalaryPolicyFormSchema, form));
                if (editing) {
                    await updateTeamSalaryPolicy(editingPolicy.id, payload);
                } else {
                    await createTeamSalaryPolicy(payload);
                }
                closeDrawer();
                setForm(emptyForm(policyType));
                await result.reload();
            },
        );
    };

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

    const togglePolicyStatus = async (policy, nextEnabled = policy.status !== "active") => {
        if (!policy?.id || !abilities.canTeamUpdate || (policy.status === "active") === nextEnabled) {
            return;
        }
        await runAction(
            `team-policy-status-${policy.id}`,
            nextEnabled ? "工资政策已启用" : "工资政策已停用",
            async () => {
                await updateTeamSalaryPolicy(
                    policy.id,
                    buildPayload({ ...emptyForm(policyType, policy), enabled: nextEnabled }),
                );
                await result.reload();
            },
        );
    };

    const resetFilters = () => {
        setQuery("");
        setRegionId("");
        setStatus("");
        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;
            return {
                ...current,
                levels: [
                    ...current.levels,
                    {
                        level: String(nextLevel),
                        ratePercent: last?.ratePercent || "0",
                        salaryUsd: last?.salaryUsd || "0",
                        sortOrder: String(nextLevel),
                        status: "active",
                        thresholdUsd: "",
                    },
                ],
            };
        });
    };

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

    const runAction = async (action, successMessage, submitter) => {
        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);
        },
        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,
        policyType,
        query,
        regionId,
        regionLabels,
        regionOptions,
        reload: result.reload,
        removeLevel,
        removePolicy,
        resetFilters,
        setForm,
        setPage,
        settlementTriggerMode,
        status,
        submitPolicy,
        togglePolicyStatus,
        updateLevel,
    };
}

function levelToForm(level) {
    return {
        level: String(level.level || ""),
        ratePercent: level.ratePercent || "0",
        salaryUsd: level.salaryUsd || "0",
        sortOrder: String(level.sortOrder || level.level || ""),
        status: level.status || "active",
        thresholdUsd: level.thresholdUsd || "0",
    };
}

function defaultLevelToForm([level, thresholdUsd, ratePercent, salaryUsd]) {
    return {
        level: String(level),
        ratePercent,
        salaryUsd,
        sortOrder: String(level),
        status: "active",
        thresholdUsd,
    };
}

function buildPayload(form) {
    return {
        effective_from_ms: timeValueToMs(form.effectiveFrom),
        effective_to_ms: timeValueToMs(form.effectiveTo),
        levels: form.levels
            .map((level) => ({
                level: Number(level.level || 0),
                rate_percent: String(level.ratePercent || "0").trim(),
                salary_usd: String(level.salaryUsd || "0").trim(),
                sort_order: Number(level.sortOrder || level.level || 0),
                status: level.status || "active",
                threshold_usd: String(level.thresholdUsd || "0").trim(),
            }))
            .sort((left, right) => left.level - right.level),
        name: String(form.name || "").trim(),
        policy_type: form.policyType,
        region_id: Number(form.regionId || 0),
        settlement_trigger_mode: form.settlementTriggerMode || "automatic",
        status: form.enabled ? "active" : "disabled",
    };
}

function defaultPolicyName(policyType) {
    return policyType === "bd" ? "Lalu BD Salary Policy" : "Lalu Admin Salary Policy";
}

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);
    return Number.isFinite(number) && number > 0 ? number : 0;
}
