import { useCallback, useMemo, useState } from "react";
import { parseForm } from "@/shared/forms/validation";
import { useAdminQuery } from "@/shared/hooks/useAdminQuery.js";
import { useToast } from "@/shared/ui/ToastProvider.jsx";
import {
    createRegion,
    disableRegion,
    enableRegion,
    listCountries,
    listRegions,
    replaceRegionCountries,
    updateRegion,
} from "@/features/host-org/api";
import { useRegionAbilities } from "@/features/host-org/permissions.js";
import { regionCreateSchema, regionUpdateSchema } from "@/features/host-org/schema";

const emptyRegionForm = () => ({
    countries: [],
    name: "",
    regionCode: "",
    sortOrder: 0,
});
const emptyData = { items: [], total: 0 };
const globalRegionCode = "GLOBAL";

export function useHostRegionsPage() {
    const abilities = useRegionAbilities();
    const { showToast } = useToast();
    const [query, setQuery] = useState("");
    const [status, setStatus] = useState("");
    const [regionForm, setRegionFormState] = useState(emptyRegionForm);
    const [editingRegion, setEditingRegion] = useState(null);
    const [loadingAction, setLoadingAction] = useState("");
    const [activeAction, setActiveAction] = useState("");
    const queryFn = useCallback(() => listRegions(), []);
    const {
        data = emptyData,
        error,
        loading,
        reload,
    } = useAdminQuery(queryFn, {
        errorMessage: "加载区域列表失败",
        initialData: emptyData,
        keepPreviousData: true,
        queryKey: ["host-org", "regions"],
    });
    const countryQueryFn = useCallback(() => listCountries(), []);
    const { data: countriesData = emptyData, loading: loadingCountries } = useAdminQuery(countryQueryFn, {
        errorMessage: "加载国家列表失败",
        initialData: emptyData,
        queryKey: ["host-org", "countries", "region-options"],
        staleTime: 5 * 60 * 1000,
    });
    const items = useMemo(() => filterRegions(data?.items || [], query, status), [data?.items, query, status]);
    const assignedCountries = useMemo(() => {
        const currentRegionId = editingRegion?.regionId;
        const assigned = new Set();
        (data?.items || []).forEach((region) => {
            if (
                region.status !== "active" ||
                region.regionId === currentRegionId ||
                isGlobalRegionCode(region.regionCode)
            ) {
                return;
            }
            (region.countries || []).forEach((country) => assigned.add(country));
        });
        return assigned;
    }, [data?.items, editingRegion?.regionId]);
    const countryOptions = useMemo(() => {
        return [...new Set((countriesData?.items || []).map((country) => country.countryCode).filter(Boolean))]
            .filter((countryCode) => !assignedCountries.has(countryCode))
            .sort();
    }, [assignedCountries, countriesData?.items]);
    const countryLabels = useMemo(() => {
        return (countriesData?.items || []).reduce((labels, country) => {
            if (country.countryCode) {
                labels[country.countryCode] = [country.countryCode, country.countryDisplayName || country.countryName]
                    .filter(Boolean)
                    .join(" · ");
            }
            return labels;
        }, {});
    }, [countriesData?.items]);
    const isGlobalRegionForm = isGlobalRegionCode(regionForm.regionCode);

    const setRegionForm = (nextForm) => {
        const normalized = isGlobalRegionCode(nextForm.regionCode) ? { ...nextForm, countries: [] } : nextForm;
        setRegionFormState(normalized);
    };

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

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

    const resetFilters = () => {
        setQuery("");
        setStatus("");
    };

    const openCreateRegion = () => {
        setEditingRegion(null);
        setRegionFormState(emptyRegionForm());
        setActiveAction("create");
    };

    const openEditRegion = (region) => {
        setEditingRegion(region);
        setRegionFormState({
            countries: region.countries || [],
            name: region.name || "",
            regionCode: region.regionCode || "",
            sortOrder: region.sortOrder || 0,
        });
        setActiveAction("edit");
    };

    const submitRegion = async (event) => {
        event.preventDefault();
        const isEdit = activeAction === "edit";
        await runAction(isEdit ? "region-edit" : "region-create", isEdit ? "区域已更新" : "区域已创建", async () => {
            const payload = parseForm(isEdit ? regionUpdateSchema : regionCreateSchema, regionForm);
            const data = isEdit ? await updateExistingRegion(editingRegion, payload) : await createRegion(payload);
            setRegionFormState(emptyRegionForm());
            setEditingRegion(null);
            setActiveAction("");
            await reload();
            return data;
        });
    };

    const toggleRegion = async (region, nextActive = region.status !== "active") => {
        if (
            isGlobalRegionCode(region.regionCode) ||
            !abilities.canStatus ||
            (region.status === "active") === nextActive
        ) {
            return;
        }
        await runAction(`region-status-${region.regionId}`, nextActive ? "区域已启用" : "区域已停用", async () => {
            const data = nextActive ? await enableRegion(region.regionId) : await disableRegion(region.regionId);
            await reload();
            return data;
        });
    };

    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,
        changeStatus,
        closeAction: () => setActiveAction(""),
        countryLabels,
        countryOptions,
        data: { ...data, items, total: items.length },
        editingRegion,
        error,
        loading,
        loadingAction,
        loadingCountries,
        isGlobalRegionForm,
        openCreateRegion,
        openEditRegion,
        query,
        regionForm,
        reload,
        resetFilters,
        setRegionForm,
        status,
        submitRegion,
        toggleRegion,
    };
}

async function updateExistingRegion(region, payload) {
    const { countries, ...regionPayload } = payload;
    const updatedRegion = await updateRegion(region.regionId, regionPayload);
    if (hasCountryChanges(region.countries || [], countries || [])) {
        return replaceRegionCountries(region.regionId, { countries });
    }
    return updatedRegion;
}

function hasCountryChanges(previousCountries, nextCountries) {
    const previous = [...previousCountries].sort();
    const next = [...nextCountries].sort();
    return previous.length !== next.length || previous.some((country, index) => country !== next[index]);
}

function filterRegions(items, query, status) {
    const keyword = query.trim().toLowerCase();
    return items.filter((item) => {
        if (status && item.status !== status) {
            return false;
        }
        if (!keyword) {
            return true;
        }
        return [item.regionCode, item.name, ...(item.countries || [])]
            .filter(Boolean)
            .some((value) => String(value).toLowerCase().includes(keyword));
    });
}

function isGlobalRegionCode(regionCode) {
    return (
        String(regionCode || "")
            .trim()
            .toUpperCase() === globalRegionCode
    );
}
