import { useMemo, useState } from "react";
import { parseForm } from "@/shared/forms/validation";
import { usePaginatedQuery } from "@/shared/hooks/usePaginatedQuery.js";
import { useRegionOptions } from "@/shared/hooks/useRegionOptions.js";
import { useToast } from "@/shared/ui/ToastProvider.jsx";
import {
    createCoinSeller,
    creditCoinSellerStock,
    debitCoinSellerStock,
    getCoinSellerSalaryRates,
    listCoinSellers,
    replaceCoinSellerSalaryRates,
    setCoinSellerStatus,
} from "@/features/host-org/api";
import { useCoinSellerAbilities } from "@/features/host-org/permissions.js";
import {
    coinSellerStatusSchema,
    coinSellerStockCreditSchema,
    coinSellerStockDebitSchema,
    createCoinSellerSchema,
} from "@/features/host-org/schema";

const pageSize = 50;
const emptyData = { items: [], page: 1, pageSize, total: 0 };
const emptyCreateForm = () => ({ commandId: makeCommandId("coin-seller"), contact: "", reason: "", targetUserId: "" });
const emptyEditForm = () => ({
    commandId: makeCommandId("coin-seller-status"),
    contact: "",
    reason: "",
    status: "active",
    targetUserId: "",
});
const emptyStockForm = () => ({
    coinAmount: "",
    commandId: makeCommandId("coin-seller-stock"),
    reason: "",
    rechargeAmount: "",
    type: "usdt_purchase",
});
const emptyStockDebitForm = () => ({
    coinAmount: "",
    commandId: makeCommandId("coin-seller-stock-debit"),
    reason: "",
    rechargeAmount: "",
});
const emptyRateTier = (index = 0) => ({
    coinPerUsd: "",
    enabled: true,
    maxUsd: "",
    minUsd: "",
    sortOrder: (index + 1) * 10,
});

export function useHostCoinSellersPage() {
    const abilities = useCoinSellerAbilities();
    const { showToast } = useToast();
    const { loadingRegions, regionOptions } = useRegionOptions();
    const [query, setQuery] = useState("");
    const [status, setStatus] = useState("");
    const [regionId, setRegionId] = useState("");
    const [sortBy, setSortBy] = useState("");
    const [sortDirection, setSortDirection] = useState("");
    const [page, setPage] = useState(1);
    const [activeAction, setActiveAction] = useState("");
    const [createForm, setCreateForm] = useState(emptyCreateForm);
    const [editForm, setEditForm] = useState(emptyEditForm);
    const [stockForm, setStockForm] = useState(emptyStockForm);
    const [stockDebitForm, setStockDebitForm] = useState(emptyStockDebitForm);
    const [rateRegionId, setRateRegionId] = useState("");
    const [rateTiers, setRateTiers] = useState([]);
    const [loadingRates, setLoadingRates] = useState(false);
    const [selectedSeller, setSelectedSeller] = useState(null);
    const [loadingAction, setLoadingAction] = useState("");
    const [contactSavingIds, setContactSavingIds] = useState({});
    const [sellerRowPatches, setSellerRowPatches] = useState({});
    const filters = useMemo(
        () => ({
            keyword: query,
            region_id: regionId,
            sort_by: sortBy,
            sort_direction: sortDirection,
            status,
        }),
        [query, regionId, sortBy, sortDirection, status],
    );
    const {
        data: queryData = emptyData,
        error,
        loading,
        reload,
    } = usePaginatedQuery({
        errorMessage: "加载币商列表失败",
        fetcher: listCoinSellers,
        filters,
        page,
        pageSize,
        queryKey: ["host-org", "coin-sellers", filters, page],
    });
    const data = useMemo(() => {
        const sourceItems = Array.isArray(queryData.items) ? queryData.items : [];
        return {
            ...queryData,
            items: sourceItems.map((seller) => ({
                ...seller,
                ...(sellerRowPatches[seller.userId] || {}),
            })),
        };
    }, [queryData, sellerRowPatches]);

    const changeQuery = (value) => {
        setQuery(value);
        setPage(1);
    };

    const changeStatus = (value) => {
        setStatus(value);
        setPage(1);
    };

    const changeRegionId = (value) => {
        setRegionId(value);
        setPage(1);
    };

    const changeSort = (field) => {
        setSortDirection((current) => (sortBy === field ? (current === "asc" ? "desc" : "asc") : "desc"));
        setSortBy(field);
        setPage(1);
    };

    const resetFilters = () => {
        setQuery("");
        setStatus("");
        setRegionId("");
        setSortBy("");
        setSortDirection("");
        setPage(1);
    };

    const openCreateSeller = () => {
        setCreateForm(emptyCreateForm());
        setSelectedSeller(null);
        setActiveAction("create");
    };

    const openEditSeller = (seller) => {
        if (!seller?.userId) {
            return;
        }
        setSelectedSeller(seller);
        setEditForm({
            commandId: makeCommandId("coin-seller-status"),
            contact: seller.contact || "",
            reason: "update coin seller contact",
            status: seller.status || "active",
            targetUserId: seller.userId,
        });
        setActiveAction("edit");
    };

    const openStockCredit = (seller) => {
        if (!seller?.userId || !abilities.canStockCredit) {
            return;
        }
        setSelectedSeller(seller);
        setStockForm(emptyStockForm());
        setActiveAction("stock");
    };

    const openStockDebit = (seller) => {
        if (!seller?.userId || !abilities.canStockCredit) {
            return;
        }
        setSelectedSeller(seller);
        setStockDebitForm(emptyStockDebitForm());
        setActiveAction("stock-debit");
    };

    const openSellerLedger = (seller) => {
        if (!seller?.userId || !abilities.canLedger) {
            return;
        }
        setSelectedSeller(seller);
        setActiveAction("ledger");
    };

    const openRateSettings = async () => {
        if (!abilities.canExchangeRate) {
            return;
        }
        const nextRegionId = rateRegionId || regionId || regionOptions[0]?.value || "";
        setRateRegionId(nextRegionId);
        setActiveAction("rates");
        if (nextRegionId) {
            await loadRateTiers(nextRegionId);
        } else {
            setRateTiers([]);
        }
    };

    const closeAction = () => {
        setActiveAction("");
        setSelectedSeller(null);
    };

    const changeRateRegionId = async (value) => {
        setRateRegionId(value);
        if (value) {
            await loadRateTiers(value);
        } else {
            setRateTiers([]);
        }
    };

    const loadRateTiers = async (targetRegionId = rateRegionId) => {
        if (!targetRegionId) {
            return;
        }
        setLoadingRates(true);
        try {
            const data = await getCoinSellerSalaryRates(targetRegionId);
            const next = (data?.tiers || []).map((tier, index) => ({
                coinPerUsd: String(tier.coinPerUsd || ""),
                enabled: tier.status ? tier.status === "active" : tier.enabled !== false,
                maxUsd: tier.maxUsd || centsToUSD(tier.maxUsdMinor),
                minUsd: tier.minUsd || centsToUSD(tier.minUsdMinor),
                sortOrder: tier.sortOrder || (index + 1) * 10,
            }));
            setRateTiers(next.length ? next : [emptyRateTier(0)]);
        } catch (err) {
            setRateTiers([emptyRateTier(0)]);
            showToast(err.message || "加载兑换比例失败", "error");
        } finally {
            setLoadingRates(false);
        }
    };

    const addRateTier = () => {
        setRateTiers((items) => [...items, emptyRateTier(items.length)]);
    };

    const removeRateTier = (index) => {
        setRateTiers((items) => items.filter((_, itemIndex) => itemIndex !== index));
    };

    const updateRateTier = (index, patch) => {
        setRateTiers((items) => items.map((item, itemIndex) => (itemIndex === index ? { ...item, ...patch } : item)));
    };

    const submitCreateSeller = async (event) => {
        event.preventDefault();
        await runAction("coin-seller-create", "币商已添加", async () => {
            const payload = parseForm(createCoinSellerSchema, createForm);
            await createCoinSeller(payload);
            setCreateForm(emptyCreateForm());
            closeAction();
            await reload();
        });
    };

    const submitEditSeller = async (event) => {
        event.preventDefault();
        await runAction(
            `coin-seller-edit-${editForm.targetUserId || selectedSeller?.userId || ""}`,
            "币商已更新",
            async () => {
                const payload = parseForm(coinSellerStatusSchema, editForm);
                const { targetUserId, ...body } = payload;
                await setCoinSellerStatus(targetUserId, body);
                setEditForm(emptyEditForm());
                closeAction();
                await reload();
            },
        );
    };

    const saveSellerContact = async (seller, rawContact) => {
        if (!abilities.canUpdate || !seller?.userId) {
            return false;
        }
        const contact = String(rawContact ?? "").trim();
        if (contact === String(seller.contact || "").trim()) {
            return true;
        }
        const sellerID = seller.userId;
        setContactSavingIds((current) => ({ ...current, [sellerID]: true }));
        try {
            await setCoinSellerStatus(sellerID, {
                commandId: makeCommandId("coin-seller-contact"),
                contact,
                reason: "update coin seller contact",
                status: seller.status || "active",
            });
            setSellerRowPatches((current) => ({
                ...current,
                [sellerID]: {
                    ...(current[sellerID] || {}),
                    contact,
                },
            }));
            showToast("联系方式已保存", "success");
            return true;
        } catch (err) {
            showToast(err.message || "保存联系方式失败", "error");
            return false;
        } finally {
            setContactSavingIds((current) => {
                const next = { ...current };
                delete next[sellerID];
                return next;
            });
        }
    };

    const submitStockCredit = async (event) => {
        event.preventDefault();
        if (!selectedSeller?.userId) {
            return;
        }
        await runAction(`coin-seller-stock-${selectedSeller.userId}`, "币商库存已入账", async () => {
            const payload = parseForm(coinSellerStockCreditSchema, stockForm);
            await creditCoinSellerStock(selectedSeller.userId, payload);
            setStockForm(emptyStockForm());
            closeAction();
            await reload();
        });
    };

    const submitStockDebit = async (event) => {
        event.preventDefault();
        if (!selectedSeller?.userId) {
            return;
        }
        await runAction(`coin-seller-stock-debit-${selectedSeller.userId}`, "币商金币已扣除", async () => {
            const payload = parseForm(coinSellerStockDebitSchema, stockDebitForm);
            await debitCoinSellerStock(selectedSeller.userId, payload);
            setStockDebitForm(emptyStockDebitForm());
            closeAction();
            await reload();
        });
    };

    const submitRateSettings = async (event) => {
        event.preventDefault();
        if (!rateRegionId) {
            showToast("请选择区域", "error");
            return;
        }
        await runAction("coin-seller-rates", "兑换比例已保存", async () => {
            const payload = {
                tiers: rateTiers
                    .filter((tier) => tier.minUsd || tier.maxUsd || tier.coinPerUsd)
                    .map((tier, index) => ({
                        coinPerUsd: Number(tier.coinPerUsd),
                        enabled: tier.enabled !== false,
                        maxUsd: String(tier.maxUsd || "").trim(),
                        minUsd: String(tier.minUsd || "").trim(),
                        sortOrder: Number(tier.sortOrder || (index + 1) * 10),
                    })),
            };
            await replaceCoinSellerSalaryRates(rateRegionId, payload);
            await loadRateTiers(rateRegionId);
        });
    };

    const toggleSeller = async (seller, nextEnabled = seller.status !== "active") => {
        if (!abilities.canUpdate || !seller?.userId) {
            return;
        }
        const nextStatus = nextEnabled ? "active" : "disabled";
        if (seller.status === nextStatus) {
            return;
        }
        await runAction(`coin-seller-status-${seller.userId}`, nextEnabled ? "币商已启用" : "币商已停用", async () => {
            await setCoinSellerStatus(seller.userId, {
                commandId: makeCommandId("coin-seller-status"),
                reason: "",
                status: nextStatus,
            });
            await reload();
        });
    };

    const runAction = async (action, successMessage, submitter) => {
        setLoadingAction(action);
        try {
            await submitter();
            showToast(successMessage, "success");
        } catch (err) {
            showToast(err.message || "操作失败", "error");
        } finally {
            setLoadingAction("");
        }
    };

    return {
        abilities,
        activeAction,
        changeQuery,
        changeRegionId,
        changeSort,
        changeStatus,
        closeAction,
        contactSavingIds,
        createForm,
        data,
        editForm,
        error,
        loading,
        loadingAction,
        loadingRates,
        loadingRegions,
        openRateSettings,
        openCreateSeller,
        openEditSeller,
        openSellerLedger,
        openStockCredit,
        openStockDebit,
        page,
        query,
        regionId,
        regionOptions,
        rateRegionId,
        rateTiers,
        reload,
        addRateTier,
        changeRateRegionId,
        removeRateTier,
        resetFilters,
        saveSellerContact,
        selectedSeller,
        setCreateForm,
        setEditForm,
        setPage,
        setStockForm,
        setStockDebitForm,
        status,
        stockDebitForm,
        stockForm,
        sortBy,
        sortDirection,
        submitRateSettings,
        submitCreateSeller,
        submitEditSeller,
        submitStockCredit,
        submitStockDebit,
        toggleSeller,
        updateRateTier,
    };
}

function makeCommandId(prefix) {
    return `${prefix}-${Date.now()}`;
}

function centsToUSD(value) {
    const amount = Number(value || 0);
    if (!Number.isFinite(amount) || amount <= 0) {
        return "";
    }
    return `${Math.trunc(amount / 100)}.${String(Math.abs(amount % 100)).padStart(2, "0")}`;
}
