import Add from "@mui/icons-material/Add";
import Inventory2Outlined from "@mui/icons-material/Inventory2Outlined";
import UndoOutlined from "@mui/icons-material/UndoOutlined";
import MenuItem from "@mui/material/MenuItem";
import TextField from "@mui/material/TextField";
import { AdminFormDialog, AdminFormFieldGrid, AdminFormSection } from "@/shared/ui/AdminFormDialog.jsx";
import { AdminUserIdentity } from "@/shared/ui/AdminUserIdentity.jsx";
import { DataState } from "@/shared/ui/DataState.jsx";
import { DataTable } from "@/shared/ui/DataTable.jsx";
import {
    AdminActionIconButton,
    AdminListBody,
    AdminListPage,
    AdminListToolbar,
    AdminRowActions,
} from "@/shared/ui/AdminListLayout.jsx";
import { createOptionsColumnFilter, createTextColumnFilter } from "@/shared/ui/tableFilters.js";
import { formatMillis } from "@/shared/utils/time.js";
import { GiftResourceSelectField } from "@/features/resources/components/GiftResourceSelectDrawer.jsx";
import {
    resourceGroupAssetLabels,
    resourceGrantStatusFilters,
    resourceGrantStatusLabels,
    resourceGrantSubjectLabels,
    resourceTypeLabels,
} from "@/features/resources/constants.js";
import { useResourceGrantListPage } from "@/features/resources/hooks/useResourcePages.js";
import styles from "@/features/resources/resources.module.css";

const grantColumns = [
    {
        key: "grant",
        label: "来源",
        width: "minmax(220px, 1fr)",
        render: (grant) => (
            <div className={styles.stack}>
                <span className={styles.name}>{grantSourceLabel(grant.grantSource)}</span>
            </div>
        ),
    },
    {
        key: "target",
        label: "用户信息",
        width: "minmax(240px, 1.1fr)",
        render: (grant) => <GrantTargetUser grant={grant} />,
    },
    {
        key: "operator",
        label: "操作人",
        width: "minmax(190px, 0.9fr)",
        render: (grant) => <GrantOperator grant={grant} />,
    },
    {
        key: "subject",
        label: "发放方式",
        width: "minmax(170px, 0.75fr)",
        render: (grant) => <GrantSubject grant={grant} />,
    },
    {
        key: "items",
        label: "发放内容",
        width: "minmax(320px, 1.5fr)",
        render: (grant) => <GrantItems grant={grant} />,
    },
    {
        key: "status",
        label: "状态",
        width: "minmax(100px, 0.55fr)",
        render: (grant) => (
            <span className={`status-badge status-badge--${grantStatusTone(grant.status)}`}>
                <span className="status-point" />
                {resourceGrantStatusLabels[grant.status] || grant.status || "-"}
            </span>
        ),
    },
    {
        key: "reason",
        label: "原因",
        width: "minmax(190px, 0.95fr)",
        render: (grant) => <GrantReason grant={grant} />,
    },
    {
        key: "time",
        label: "创建时间",
        width: "minmax(170px, 0.9fr)",
        render: (grant) => formatMillis(grant.createdAtMs),
    },
];

export function ResourceGrantListPage() {
    const page = useResourceGrantListPage();
    const items = page.data.items || [];
    const total = page.data.total || 0;
    const columns = [
        ...grantColumns.map((column) => {
            if (column.key === "target") {
                return {
                    ...column,
                    filter: createTextColumnFilter({
                        placeholder: "搜索用户 ID",
                        value: page.query,
                        onChange: page.changeQuery,
                    }),
                };
            }
            if (column.key === "status") {
                return {
                    ...column,
                    filter: createOptionsColumnFilter({
                        options: resourceGrantStatusFilters,
                        placeholder: "搜索状态",
                        value: page.status,
                        onChange: page.changeStatus,
                    }),
                };
            }
            return column;
        }),
        {
            key: "actions",
            label: "操作",
            width: "minmax(88px, 0.45fr)",
            render: (grant) => <ResourceGrantActions grant={grant} page={page} />,
        },
    ];

    return (
        <AdminListPage>
            <AdminListToolbar
                actions={
                    page.abilities.canCreateGrant ? (
                        <AdminActionIconButton label="资源赠送" primary onClick={page.openCreateGrant}>
                            <Add fontSize="small" />
                        </AdminActionIconButton>
                    ) : null
                }
            />
            <DataState error={page.error} loading={page.loading} onRetry={page.reload}>
                <AdminListBody>
                    <DataTable
                        columns={columns}
                        items={items}
                        minWidth="1560px"
                        pagination={
                            total > 0
                                ? {
                                      page: page.page,
                                      pageSize: page.data.pageSize || 50,
                                      total,
                                      onPageChange: page.setPage,
                                  }
                                : undefined
                        }
                        rowKey={(grant) => grant.grantId}
                    />
                </AdminListBody>
            </DataState>
            <ResourceGrantDialog
                disabled={!page.abilities.canCreateGrant}
                form={page.form}
                giftOptions={page.giftOptions}
                giftTypeOptions={page.giftTypeOptions}
                groupOptions={page.groupOptions}
                loading={page.loadingAction === "grant-create"}
                open={page.activeAction === "create"}
                optionsLoading={page.optionsLoading}
                resourceOptions={page.resourceOptions}
                setForm={page.setForm}
                onClose={page.closeAction}
                onSubmit={page.submitGrant}
            />
        </AdminListPage>
    );
}

function ResourceGrantActions({ grant, page }) {
    const canRevoke =
        page.abilities.canRevokeGrant && grant?.status === "succeeded" && grant?.grantSubjectType === "resource_group";
    if (!canRevoke) {
        return <span className={styles.meta}>-</span>;
    }
    return (
        <AdminRowActions>
            <AdminActionIconButton
                aria-label="撤销"
                disabled={page.loadingAction === `grant-revoke-${grant.grantId}`}
                label="撤销"
                sx={dangerActionSx}
                tooltip="撤销资源组赠送"
                onClick={() => page.revokeGrant(grant)}
            >
                <UndoOutlined fontSize="small" />
            </AdminActionIconButton>
        </AdminRowActions>
    );
}

function ResourceGrantDialog({
    disabled,
    form,
    giftOptions,
    giftTypeOptions,
    groupOptions,
    loading,
    onClose,
    onSubmit,
    open,
    optionsLoading,
    resourceOptions,
    setForm,
}) {
    const submitDisabled = disabled || loading || optionsLoading;
    return (
        <AdminFormDialog
            loading={loading}
            open={open}
            submitDisabled={submitDisabled}
            title="资源赠送"
            onClose={onClose}
            onSubmit={onSubmit}
        >
            <AdminFormSection title="赠送对象">
                <TextField
                    disabled={disabled}
                    inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
                    label="用户 ID / 短号"
                    required
                    value={form.targetUserId}
                    onChange={(event) => setForm({ ...form, targetUserId: event.target.value })}
                />
            </AdminFormSection>
            <AdminFormSection title="赠送内容">
                <AdminFormFieldGrid>
                    <TextField
                        disabled={disabled}
                        label="对象类型"
                        required
                        select
                        value={form.subjectType}
                        onChange={(event) =>
                            setForm({
                                ...form,
                                groupId: "",
                                resourceId: "",
                                resourceIds: [],
                                subjectType: event.target.value,
                            })
                        }
                    >
                        <MenuItem value="resource">资源</MenuItem>
                        <MenuItem value="resource_group">资源组</MenuItem>
                    </TextField>
                    {form.subjectType === "resource" ? (
                        <>
                            <GiftResourceSelectField
                                drawerTitle="选择资源"
                                disabled={disabled || optionsLoading}
                                giftTypes={giftTypeOptions}
                                gifts={giftOptions}
                                label="资源"
                                loading={optionsLoading}
                                required
                                resources={resourceOptions}
                                selectedResourceIds={form.resourceIds || []}
                                onChange={(resourceIds) =>
                                    setForm({ ...form, resourceId: resourceIds[0] || "", resourceIds })
                                }
                            />
                            <TextField
                                disabled={disabled}
                                label="数量"
                                required
                                type="number"
                                value={form.quantity}
                                onChange={(event) => setForm({ ...form, quantity: event.target.value })}
                            />
                            <TextField
                                disabled={disabled}
                                label="有效天数"
                                type="number"
                                value={form.durationDays}
                                onChange={(event) => setForm({ ...form, durationDays: event.target.value })}
                            />
                        </>
                    ) : (
                        <TextField
                            disabled={disabled || optionsLoading}
                            label="资源组"
                            required
                            select
                            value={form.groupId}
                            onChange={(event) => setForm({ ...form, groupId: event.target.value })}
                        >
                            {groupOptions.map((group) => (
                                <MenuItem key={group.groupId} value={String(group.groupId)}>
                                    {group.name || group.groupCode || group.groupId}
                                </MenuItem>
                            ))}
                        </TextField>
                    )}
                </AdminFormFieldGrid>
            </AdminFormSection>
            <AdminFormSection title="备注">
                <TextField
                    disabled={disabled}
                    label="原因"
                    multiline
                    minRows={2}
                    required
                    value={form.reason}
                    onChange={(event) => setForm({ ...form, reason: event.target.value })}
                />
            </AdminFormSection>
        </AdminFormDialog>
    );
}

function grantStatusTone(status) {
    if (status === "revoked") {
        return "stopped";
    }
    if (status === "failed") {
        return "danger";
    }
    if (status === "pending") {
        return "warning";
    }
    return status || "stopped";
}

const dangerActionSx = {
    borderColor: "var(--danger-border)",
    color: "var(--danger)",
    "&:hover": {
        borderColor: "var(--danger-border-strong)",
        backgroundColor: "var(--danger-surface)",
        color: "var(--danger)",
    },
};

function GrantItems({ grant }) {
    const items = grant.items || [];
    if (!items.length) {
        return "-";
    }
    return (
        <div className={styles.grantMediaScroller}>
            {items.map((item) => (
                <GrantItemMedia item={item} key={item.grantItemId || `${grant.grantId}-${item.resourceId}`} />
            ))}
        </div>
    );
}

function GrantItemMedia({ item }) {
    const snapshot = parseGrantItemSnapshot(item.resourceSnapshotJson);
    const walletAssetType = snapshotValue(snapshot, "walletAssetType", "wallet_asset_type", "WalletAssetType");
    if (walletAssetType) {
        const label = resourceGroupAssetLabels[walletAssetType] || walletAssetType;
        const amount = snapshotValue(snapshot, "walletAssetAmount", "wallet_asset_amount", "WalletAssetAmount", "quantity");
        return <span className={styles.grantAssetPill}>{`${label} ${formatNumber(amount || item.quantity)}`}</span>;
    }

    const label = grantItemLabel(item, snapshot);
    const imageUrl = grantItemImageUrl(snapshot);
    return (
        <span className={styles.grantMediaCard} title={label}>
            <span className={styles.grantMediaThumb}>
                {imageUrl ? <img alt="" src={imageUrl} /> : <Inventory2Outlined fontSize="small" />}
            </span>
            <span className={styles.grantMediaName}>{label}</span>
        </span>
    );
}

function GrantSubject({ grant }) {
    const subjectLabel = resourceGrantSubjectLabels[grant.grantSubjectType] || grant.grantSubjectType || "发放";
    const sourceLabel = grantSourceLabel(grant.grantSource);
    return (
        <div className={styles.stack}>
            <span className={styles.name}>{sourceLabel === "-" ? subjectLabel : `${subjectLabel} · ${sourceLabel}`}</span>
            <span className={styles.meta}>{subjectMeta(grant)}</span>
        </div>
    );
}

function GrantReason({ grant }) {
    const label = reasonLabel(grant.reason);
    const raw = String(grant.reason || "").trim();
    return (
        <div className={styles.stack}>
            <span className={styles.name}>{label}</span>
            {raw && raw !== label ? <span className={styles.meta}>{raw}</span> : null}
        </div>
    );
}

function GrantTargetUser({ grant }) {
    const user = grant.targetUser || grant.target_user || grant.user || {};
    const userId = user.userId || user.user_id || grant.targetUserId;
    return (
        <AdminUserIdentity
            openInAppUserDetail
            rows={[user.displayUserId || user.display_user_id, userId]}
            user={{ ...user, userId }}
        />
    );
}

function GrantOperator({ grant }) {
    const operator = grant.operator || {};
    const source = operator.source || grant.grantSource || "";
    const operatorUserId = operator.userId || grant.operatorUserId;
    if (source === "manager_center") {
        return (
            <AdminUserIdentity
                openInAppUserDetail
                name={operator.username || operator.name}
                user={{ ...operator, userId: operatorUserId }}
            />
        );
    }
    return "-";
}

const grantSourceLabels = {
    achievement: "成就奖励",
    admin: "后台发放",
    agency_opening: "Agency 开通",
    cp_weekly_rank: "CP 周榜奖励",
    cumulative_recharge_reward: "累充奖励",
    first_recharge_reward: "首充奖励",
    game_robot_init: "机器人初始化",
    growth_level: "成长等级奖励",
    manager_center: "经理中心",
    registration_reward: "注册奖励",
    resource_shop: "道具商店",
    room_rocket: "房间火箭",
    seven_day_checkin: "七日签到",
    weekly_star: "周星奖励",
    wheel_reward: "转盘奖励",
};

const grantReasonLabels = {
    ...grantSourceLabels,
    growth_level_registration_badge: "注册成长等级徽章",
    "resource shop purchase": "道具商店购买",
};

function grantSourceLabel(source) {
    const key = String(source || "").trim();
    return grantSourceLabels[key] || key || "-";
}

function reasonLabel(reason) {
    const key = String(reason || "").trim();
    return grantReasonLabels[key] || key || "-";
}

function subjectMeta(grant) {
    const subjectLabel = resourceGrantSubjectLabels[grant.grantSubjectType] || grant.grantSubjectType || "对象";
    return grant.grantSubjectId ? `${subjectLabel} ID ${grant.grantSubjectId}` : "-";
}

function grantItemLabel(item, snapshot = parseGrantItemSnapshot(item.resourceSnapshotJson)) {
    const walletAssetType = snapshotValue(snapshot, "walletAssetType", "wallet_asset_type", "WalletAssetType");
    if (walletAssetType) {
        const label = resourceGroupAssetLabels[walletAssetType] || walletAssetType;
        const amount = snapshotValue(snapshot, "walletAssetAmount", "wallet_asset_amount", "WalletAssetAmount", "quantity");
        return `${label} ${formatNumber(amount || item.quantity)}`;
    }

    const resourceName = snapshotValue(snapshot, "name", "Name", "resourceName", "resource_name") || `资源 ${item.resourceId || "-"}`;
    const resourceType = snapshotValue(snapshot, "resourceType", "resource_type", "ResourceType");
    const typeLabel = resourceTypeLabels[resourceType] || resourceType || "资源";
    const quantity = Number(item.quantity || 0);
    const parts = [`${resourceName} x${formatNumber(quantity)}`, typeLabel];
    if (item.durationMs) {
        parts.push(formatDuration(item.durationMs));
    }
    return parts.join(" · ");
}

function grantItemImageUrl(snapshot) {
    return imageURL(
        snapshotValue(
            snapshot,
            "previewUrl",
            "preview_url",
            "PreviewURL",
            "assetUrl",
            "asset_url",
            "AssetURL",
            "animationUrl",
            "animation_url",
            "AnimationURL",
        ),
    );
}

function parseGrantItemSnapshot(value) {
    if (!value || typeof value !== "string") {
        return {};
    }
    try {
        const parsed = JSON.parse(value);
        return parsed && typeof parsed === "object" ? parsed : {};
    } catch {
        return {};
    }
}

function snapshotValue(snapshot, ...keys) {
    for (const key of keys) {
        const value = snapshot?.[key];
        if (value !== undefined && value !== null && value !== "") {
            return value;
        }
    }
    return "";
}

function formatNumber(value) {
    return Number(value || 0).toLocaleString("zh-CN");
}

function imageURL(value) {
    const url = String(value || "").trim();
    return /\.(avif|gif|jpe?g|png|webp)(\?|#|$)/i.test(url) ? url : "";
}

function formatDuration(durationMs) {
    const days = Number(durationMs || 0) / (24 * 60 * 60 * 1000);
    return Number.isInteger(days) ? `${days}天` : `${days.toFixed(1)}天`;
}
