import AddModeratorOutlined from "@mui/icons-material/AddModeratorOutlined";
import Tooltip from "@mui/material/Tooltip";
import { useQueryClient } from "@tanstack/react-query";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useSearchParams } from "react-router-dom";
import { toPageQuery } from "@/shared/api/query";
import { FormValidationError, parseForm } from "@/shared/forms/validation";
import { AdminUserIdentity } from "@/shared/ui/AdminUserIdentity.jsx";
import { DataState } from "@/shared/ui/DataState.jsx";
import { DataTable } from "@/shared/ui/DataTable.jsx";
import { IconButton } from "@/shared/ui/IconButton.jsx";
import { useAdminQuery } from "@/shared/hooks/useAdminQuery.js";
import { mergePaginatedItems } from "@/shared/hooks/usePaginatedQuery.js";
import { useRegionOptions } from "@/shared/hooks/useRegionOptions.js";
import { useToast } from "@/shared/ui/ToastProvider.jsx";
import { createRegionColumnFilter } from "@/shared/ui/RegionFilterControl.jsx";
import { createOptionsColumnFilter, createTextColumnFilter, createUserIdentityColumnFilter } from "@/shared/ui/tableFilters.js";
import {
    emptyUserIdentityFilter,
    isUserIdentityFilterEmpty,
    normalizeUserIdentityFilter,
    userIdentityFilterParams,
} from "@/shared/ui/userIdentityFilter.js";
import { formatMillis } from "@/shared/utils/time.js";
import { listAppUserLoginLogs } from "@/features/app-users/api";
import { addRegionBlockWhitelistIP } from "@/features/region-blocks/api";
import { useRegionBlockAbilities } from "@/features/region-blocks/permissions.js";
import { regionBlockIPSchema } from "@/features/region-blocks/schema";
import styles from "@/features/app-users/app-users.module.css";

const pageSize = 50;
const emptyData = { items: [], page: 1, pageSize, total: 0 };
const resultOptions = [
    { label: "成功", value: "success" },
    { label: "失败", value: "failed" },
    { label: "已阻断", value: "blocked" },
];

export function AppUserLoginLogsPage() {
    const [searchParams, setSearchParams] = useSearchParams();
    const queryClient = useQueryClient();
    const { showToast } = useToast();
    const regionBlockAbilities = useRegionBlockAbilities();
    const [identityFilter, setIdentityFilter] = useState(emptyUserIdentityFilter);
    const [ip, setIp] = useState("");
    const [result, setResult] = useState("");
    const [regionId, setRegionId] = useState("");
    const [page, setPage] = useState(1);
    const [addingWhitelistIP, setAddingWhitelistIP] = useState("");
    const [mergedData, setMergedData] = useState(emptyData);
    const { loadingRegions, regionOptions } = useRegionOptions();
    const lockedUserId = searchParams.get("user_id") || "";
    const regionFilterOptions = useMemo(() => [{ label: "GLOBAL · 0", value: "0" }, ...regionOptions], [regionOptions]);

    const requestQuery = useMemo(
        () =>
            toPageQuery({
                ip,
                page,
                pageSize,
                region_id: regionId,
                ...userIdentityFilterParams(identityFilter),
                user_id: lockedUserId || identityFilter.userId,
                ...(result === "blocked" ? { blocked: "blocked" } : { result }),
            }),
        [identityFilter, ip, lockedUserId, page, regionId, result],
    );
    const loadLogs = useCallback(() => listAppUserLoginLogs(requestQuery), [requestQuery]);
    const {
        data,
        error,
        loading: queryLoading,
        reload,
    } = useAdminQuery(loadLogs, {
        errorMessage: "加载用户登录日志失败",
        initialData: emptyData,
        keepPreviousData: true,
        queryKey: ["app-users", "login-logs", requestQuery],
    });

    useEffect(() => {
        setMergedData(emptyData);
    }, [identityFilter, ip, lockedUserId, regionId, result]);

    useEffect(() => {
        const nextData = data || emptyData;
        const nextItems = Array.isArray(nextData.items) ? nextData.items : [];
        const nextPage = Number(nextData.page || page || 1);
        const nextPageSize = Number(nextData.pageSize || pageSize);
        const nextTotal = Number(nextData.total || 0);

        setMergedData((current) => {
            if (nextPage <= 1) {
                return { ...nextData, items: nextItems, page: nextPage, pageSize: nextPageSize, total: nextTotal };
            }

            return {
                ...nextData,
                items: mergePaginatedItems(current.items || [], nextItems),
                page: nextPage,
                pageSize: nextPageSize,
                total: nextTotal,
            };
        });
    }, [data, page]);

    const loading = queryLoading && (mergedData.items || []).length === 0;

    const changeUserFilter = useCallback((value) => {
        setIdentityFilter(normalizeUserIdentityFilter(value));
        setPage(1);
    }, []);

    const changeIp = useCallback((value) => {
        setIp(value);
        setPage(1);
    }, []);

    const changeResult = useCallback((value) => {
        setResult(value);
        setPage(1);
    }, []);

    const changeRegionId = useCallback((value) => {
        setRegionId(value);
        setPage(1);
    }, []);

    const showUserHistory = useCallback(
        (log) => {
            if (!log.userId) {
                return;
            }
            const nextSearchParams = new URLSearchParams(searchParams);
            nextSearchParams.set("user_id", log.userId);
            setSearchParams(nextSearchParams, { replace: true });
            setIdentityFilter(emptyUserIdentityFilter);
            setIp("");
            setResult("");
            setRegionId("");
            setPage(1);
        },
        [searchParams, setSearchParams],
    );

    const resetIdentityFilter = useCallback(() => {
        setIdentityFilter(emptyUserIdentityFilter);
        setSearchParams(new URLSearchParams(), { replace: true });
        setPage(1);
    }, [setSearchParams]);

    const changeIdentityFilter = useCallback(
        (value) => {
            if (lockedUserId) {
                setSearchParams(new URLSearchParams(), { replace: true });
            }
            changeUserFilter(value);
        },
        [changeUserFilter, lockedUserId, setSearchParams],
    );

    const addLoginIPToWhitelist = useCallback(
        async (log) => {
            if (!regionBlockAbilities.canUpdate || addingWhitelistIP) {
                return;
            }

            try {
                const ipAddress = parseForm(regionBlockIPSchema, log.loginIp);
                setAddingWhitelistIP(ipAddress);
                const result = await addRegionBlockWhitelistIP(ipAddress);
                await queryClient.invalidateQueries({ queryKey: ["region-blocks"] });
                showToast(result.added ? "IP 已添加到白名单" : "白名单 IP 已存在", result.added ? "success" : "warning");
            } catch (err) {
                showValidationError(err, showToast, "添加白名单 IP 失败");
            } finally {
                setAddingWhitelistIP("");
            }
        },
        [addingWhitelistIP, queryClient, regionBlockAbilities.canUpdate, showToast],
    );

    const selectedUserLabel = useMemo(() => {
        if (!lockedUserId) {
            return "";
        }
        const matchedLog = (mergedData.items || []).find((log) => String(log.userId || "") === String(lockedUserId));
        return matchedLog?.displayUserId || matchedLog?.username || lockedUserId;
    }, [lockedUserId, mergedData.items]);

    const columns = useMemo(
        () => [
            {
                key: "identity",
                label: "用户",
                width: "minmax(240px, 1.4fr)",
                filter: createUserIdentityColumnFilter({
                    activeLabel: lockedUserId ? selectedUserLabel || lockedUserId : undefined,
                    activeValue: isUserIdentityFilterEmpty(identityFilter) ? lockedUserId : "active",
                    onReset: resetIdentityFilter,
                    value: lockedUserId ? emptyUserIdentityFilter : identityFilter,
                    onChange: changeIdentityFilter,
                }),
                render: (log) => <AdminUserIdentity openInAppUserDetail user={log} />,
            },
            {
                key: "ip",
                label: "IP",
                width: "minmax(160px, 1fr)",
                filter: createTextColumnFilter({
                    placeholder: "搜索 IP",
                    value: ip,
                    onChange: changeIp,
                }),
                render: (log) => (
                    <div className={styles.stack}>
                        <span>{log.loginIp || "-"}</span>
                        <span className={styles.meta}>{log.ipCountryCode || "-"}</span>
                    </div>
                ),
            },
            {
                key: "region",
                label: "区域",
                width: "minmax(150px, 0.9fr)",
                filter: createRegionColumnFilter({
                    loading: loadingRegions,
                    options: regionFilterOptions,
                    value: regionId,
                    onChange: changeRegionId,
                }),
                render: (log) => (
                    <div className={styles.stack}>
                        <span>{log.country || "-"}</span>
                        <span className={styles.meta}>{formatRegion(log)}</span>
                    </div>
                ),
            },
            {
                key: "client",
                label: "客户端",
                width: "minmax(160px, 1fr)",
                render: (log) => (
                    <div className={styles.stack}>
                        <span>{log.platform || "-"}</span>
                        <span className={styles.meta}>{log.channel || "-"}</span>
                    </div>
                ),
            },
            {
                key: "method",
                label: "方式",
                width: "minmax(150px, 0.9fr)",
                render: (log) => (
                    <div className={styles.stack}>
                        <span>{log.loginType || "-"}</span>
                        <span className={styles.meta}>{log.provider || "-"}</span>
                    </div>
                ),
            },
            {
                key: "result",
                label: "状态",
                width: "minmax(130px, 0.7fr)",
                filter: createOptionsColumnFilter({
                    emptyLabel: "全部状态",
                    options: resultOptions,
                    placeholder: "搜索状态",
                    value: result,
                    onChange: changeResult,
                }),
                render: (log) => <ResultBadge log={log} />,
            },
            {
                key: "detail",
                label: "详情",
                width: "minmax(220px, 1.2fr)",
                render: (log) => (
                    <span className="muted">{log.blockReason || log.failureCode || log.requestId || "-"}</span>
                ),
            },
            {
                key: "createdAtMs",
                label: "时间",
                width: "180px",
                render: (log) => <span className="muted">{formatMillis(log.createdAtMs)}</span>,
            },
            {
                key: "actions",
                label: "操作",
                width: "120px",
                render: (log) => (
                    <LoginLogActions
                        canUpdateWhitelist={regionBlockAbilities.canUpdate}
                        addingWhitelistIP={addingWhitelistIP}
                        log={log}
                        onAddToWhitelist={addLoginIPToWhitelist}
                    />
                ),
            },
        ],
        [
            addLoginIPToWhitelist,
            addingWhitelistIP,
            changeIp,
            changeIdentityFilter,
            changeRegionId,
            changeResult,
            identityFilter,
            ip,
            lockedUserId,
            loadingRegions,
            regionFilterOptions,
            regionId,
            resetIdentityFilter,
            result,
            regionBlockAbilities.canUpdate,
            selectedUserLabel,
        ],
    );

    return (
        <section className={styles.root}>
            <div className={styles.contentPanel}>
                <DataState error={error} loading={loading} onRetry={reload}>
                    <div className={styles.listBlock}>
                        <DataTable
                            columns={columns}
                            emptyLabel="暂无登录日志"
                            items={mergedData.items || []}
                            minWidth="1500px"
                            getRowProps={(log) => loginLogRowProps(log, showUserHistory)}
                            rowKey={(log) => log.id}
                            pagination={
                                mergedData.total > 0
                                    ? {
                                          page,
                                          pageSize: mergedData.pageSize || pageSize,
                                          total: mergedData.total,
                                          onPageChange: setPage,
                                      }
                                    : undefined
                            }
                        />
                    </div>
                </DataState>
            </div>
        </section>
    );
}

function LoginLogActions({ addingWhitelistIP, canUpdateWhitelist, log, onAddToWhitelist }) {
    const ipAddress = String(log.loginIp || "").trim();
    const adding = Boolean(addingWhitelistIP) && addingWhitelistIP === ipAddress;
    const disabled = !canUpdateWhitelist || !ipAddress || Boolean(addingWhitelistIP);
    const title = !canUpdateWhitelist ? "无白名单更新权限" : ipAddress ? "添加IP到白名单" : "该日志没有IP";

    return (
        <div
            className={styles.rowActions}
            onClick={(event) => event.stopPropagation()}
            onKeyDown={(event) => event.stopPropagation()}
        >
            <Tooltip arrow title={title}>
                <span>
                    <IconButton
                        disabled={disabled}
                        label="添加IP到白名单"
                        onClick={() => onAddToWhitelist(log)}
                    >
                        <AddModeratorOutlined color={adding ? "primary" : "inherit"} fontSize="small" />
                    </IconButton>
                </span>
            </Tooltip>
        </div>
    );
}

function loginLogRowProps(log, onOpenHistory) {
    if (!log.userId) {
        return {};
    }
    return {
        "aria-label": `查看用户 ${log.displayUserId || log.userId} 的登录日志`,
        role: "button",
        tabIndex: 0,
        onClick: () => onOpenHistory(log),
        onKeyDown: (event) => {
            if (event.key === "Enter" || event.key === " ") {
                event.preventDefault();
                onOpenHistory(log);
            }
        },
    };
}

function showValidationError(err, showToast, fallback) {
    if (err instanceof FormValidationError) {
        showToast(err.message, "error");
        return;
    }
    showToast(err?.message || fallback, "error");
}

function ResultBadge({ log }) {
    const result = String(log.result || "").toLowerCase();
    const blocked = log.blocked || result === "blocked";
    const tone = result === "success" || result === "succeeded" ? "running" : blocked ? "danger" : "warning";
    const labels = {
        blocked: "已阻断",
        failed: "失败",
        success: "成功",
        succeeded: "成功",
    };
    return (
        <span className={`status-badge status-badge--${tone}`}>
            <span className="status-point" />
            {labels[result] || (blocked ? "已阻断" : result || "-")}
        </span>
    );
}

function formatRegion(log) {
    if (log.regionName) {
        return log.regionName;
    }
    if (log.regionId) {
        return `区域 ${log.regionId}`;
    }
    return "-";
}
