import AddOutlined from "@mui/icons-material/AddOutlined";
import ContentCopyOutlined from "@mui/icons-material/ContentCopyOutlined";
import EditOutlined from "@mui/icons-material/EditOutlined";
import Alert from "@mui/material/Alert";
import Button from "@mui/material/Button";
import Dialog from "@mui/material/Dialog";
import DialogActions from "@mui/material/DialogActions";
import DialogContent from "@mui/material/DialogContent";
import DialogTitle from "@mui/material/DialogTitle";
import LinearProgress from "@mui/material/LinearProgress";
import MenuItem from "@mui/material/MenuItem";
import TextField from "@mui/material/TextField";
import { useEffect, useMemo, useState } from "react";
import { AppIdentity } from "@/shared/ui/AppIdentity.jsx";
import { formatTime } from "../format.js";

const EMPTY_DATA = { appCode: "", items: [] };
const ADDRESS_CHAINS = ["TRON", "BSC"];

export function FinanceUSDTAddressDialog({ apps, canUpdate = false, initialAppCode, open, onClose, onLoad, onSave }) {
    const [appCode, setAppCode] = useState("");
    const [data, setData] = useState(EMPTY_DATA);
    const [error, setError] = useState("");
    const [loading, setLoading] = useState(false);
    const [copiedChain, setCopiedChain] = useState("");
    const [editingChain, setEditingChain] = useState("");
    const [addressDraft, setAddressDraft] = useState("");
    const [saving, setSaving] = useState(false);

    useEffect(() => {
        if (!open) {
            return;
        }
        setAppCode(initialAppCode || apps[0]?.appCode || "");
        setCopiedChain("");
        setEditingChain("");
        setAddressDraft("");
        setError("");
    }, [apps, initialAppCode, open]);

    useEffect(() => {
        if (!open || !appCode) {
            setData(EMPTY_DATA);
            return undefined;
        }
        // App 切换会并发触发新请求；旧请求完成后必须被 active 门禁丢弃，不能把上一账套地址覆盖到当前选择。
        let active = true;
        setLoading(true);
        setError("");
        setCopiedChain("");
        setEditingChain("");
        setAddressDraft("");
        onLoad(appCode)
            .then((result) => {
                if (active) {
                    setData({ appCode, items: result?.items || [] });
                }
            })
            .catch((loadError) => {
                if (active) {
                    setData({ appCode, items: [] });
                    setError(loadError.message || "加载 USDT 收款地址失败");
                }
            })
            .finally(() => {
                if (active) {
                    setLoading(false);
                }
            });
        return () => {
            active = false;
        };
    }, [appCode, onLoad, open]);

    const itemsByChain = useMemo(
        () => new Map((data.items || []).map((item) => [item.chain, item])),
        [data.items],
    );
    // 有写权限时始终展示 TRON/BSC 两个可维护槽位，未配置项直接提供“添加”；只读账号仍只看到真实配置。
    const visibleChains = canUpdate ? ADDRESS_CHAINS : ADDRESS_CHAINS.filter((chain) => itemsByChain.has(chain));

    const copyAddress = async (item) => {
        try {
            if (!navigator.clipboard?.writeText) {
                throw new Error("clipboard unavailable");
            }
            // 复制值直接使用 API 返回的完整地址，不经过缩写或格式化，避免运营粘贴后链上校验失败。
            await navigator.clipboard.writeText(item.address);
            setCopiedChain(item.chain);
            setError("");
        } catch {
            setCopiedChain("");
            setError("复制失败，请手动选择地址复制");
        }
    };

    const beginEdit = (chain) => {
        setEditingChain(chain);
        setAddressDraft(itemsByChain.get(chain)?.address || "");
        setCopiedChain("");
        setError("");
    };

    const saveAddress = async () => {
        const address = addressDraft.trim();
        if (!validUSDTAddress(editingChain, address)) {
            setError(`${chainLabel(editingChain)} 收款地址格式不正确`);
            return;
        }
        if (!onSave) {
            setError("收款地址保存接口未配置");
            return;
        }
        setSaving(true);
        setError("");
        try {
            const saved = await onSave(appCode, editingChain, { address });
            const savedItem = {
                address: saved?.address || address,
                chain: saved?.chain || editingChain,
                updatedAtMs: Number(saved?.updatedAtMs || Date.now()),
            };
            // 保存成功后直接用服务端回包更新当前行；下一次校验也会由 admin-server 重新读同一 SQL 行。
            setData((current) => ({
                ...current,
                items: [...current.items.filter((item) => item.chain !== savedItem.chain), savedItem],
            }));
            setEditingChain("");
            setAddressDraft("");
        } catch (saveError) {
            setError(saveError.message || "保存 USDT 收款地址失败");
        } finally {
            setSaving(false);
        }
    };

    return (
        <Dialog fullWidth maxWidth="sm" open={open} onClose={loading || saving ? undefined : onClose}>
            <DialogTitle>USDT 收款地址</DialogTitle>
            <DialogContent className="finance-usdt-address-dialog">
                {error ? <Alert severity="error">{error}</Alert> : null}
                <TextField
                    disabled={loading || saving || !apps.length}
                    label="APP"
                    select
                    value={appCode}
                    onChange={(event) => setAppCode(event.target.value)}
                >
                    {apps.map((app) => (
                        <MenuItem key={app.appCode} value={app.appCode}>
                            <AppIdentity app={app} size="small" />
                        </MenuItem>
                    ))}
                </TextField>
                {loading ? <LinearProgress aria-label="加载 USDT 收款地址" /> : null}
                {!loading && visibleChains.length ? (
                    <div className="finance-usdt-address-list">
                        {visibleChains.map((chain) => {
                            const item = itemsByChain.get(chain);
                            const editing = editingChain === chain;
                            return (
                                <section className="finance-usdt-address-item" key={chain}>
                                    <div className="finance-usdt-address-item__meta">
                                        <strong>{chainLabel(chain)}</strong>
                                        <small>{item?.updatedAtMs ? `更新于 ${formatTime(item.updatedAtMs)}` : "未配置"}</small>
                                    </div>
                                    {editing ? (
                                        <div className="finance-usdt-address-item__editor">
                                            <TextField
                                                autoFocus
                                                fullWidth
                                                label={`${chainLabel(chain)} 收款地址`}
                                                size="small"
                                                value={addressDraft}
                                                onChange={(event) => setAddressDraft(event.target.value)}
                                            />
                                            <div className="finance-usdt-address-item__actions">
                                                <Button disabled={saving} size="small" variant="outlined" onClick={() => setEditingChain("")}>
                                                    取消
                                                </Button>
                                                <Button
                                                    aria-label={`保存 ${chain} 地址`}
                                                    disabled={saving}
                                                    size="small"
                                                    variant="contained"
                                                    onClick={saveAddress}
                                                >
                                                    {saving ? "保存中" : "保存"}
                                                </Button>
                                            </div>
                                        </div>
                                    ) : (
                                        <div className="finance-usdt-address-item__value">
                                            {item ? <code>{item.address}</code> : <span className="finance-usdt-address-item__missing">尚未添加</span>}
                                            <div className="finance-usdt-address-item__actions">
                                                {item ? (
                                                    <Button
                                                        aria-label={`复制 ${chain} 地址`}
                                                        size="small"
                                                        startIcon={<ContentCopyOutlined fontSize="small" />}
                                                        variant="outlined"
                                                        onClick={() => copyAddress(item)}
                                                    >
                                                        {copiedChain === chain ? "已复制" : "复制"}
                                                    </Button>
                                                ) : null}
                                                {canUpdate ? (
                                                    <Button
                                                        aria-label={`${item ? "修改" : "添加"} ${chain} 地址`}
                                                        size="small"
                                                        startIcon={item ? <EditOutlined fontSize="small" /> : <AddOutlined fontSize="small" />}
                                                        variant="outlined"
                                                        onClick={() => beginEdit(chain)}
                                                    >
                                                        {item ? "修改" : "添加"}
                                                    </Button>
                                                ) : null}
                                            </div>
                                        </div>
                                    )}
                                </section>
                            );
                        })}
                    </div>
                ) : null}
                {!loading && appCode && !visibleChains.length && !error ? (
                    <div className="finance-usdt-address-empty">当前 APP 未配置 USDT 收款地址</div>
                ) : null}
            </DialogContent>
            <DialogActions>
                <Button disabled={loading || saving} variant="outlined" onClick={onClose}>
                    关闭
                </Button>
            </DialogActions>
        </Dialog>
    );
}

function chainLabel(chain) {
    if (chain === "TRON") {
        return "TRON · TRC20";
    }
    if (chain === "BSC") {
        return "BSC · BEP20";
    }
    return chain;
}

function validUSDTAddress(chain, address) {
    if (chain === "TRON") {
        return /^T[1-9A-HJ-NP-Za-km-z]{33}$/.test(address);
    }
    if (chain === "BSC") {
        return /^0x[0-9a-fA-F]{40}$/.test(address);
    }
    return false;
}
