import Add from "@mui/icons-material/Add";
import CalendarMonthOutlined from "@mui/icons-material/CalendarMonthOutlined";
import CardGiftcardOutlined from "@mui/icons-material/CardGiftcardOutlined";
import ChevronLeftOutlined from "@mui/icons-material/ChevronLeftOutlined";
import ChevronRightOutlined from "@mui/icons-material/ChevronRightOutlined";
import EditOutlined from "@mui/icons-material/EditOutlined";
import SettingsOutlined from "@mui/icons-material/SettingsOutlined";
import IconButton from "@mui/material/IconButton";
import InputAdornment from "@mui/material/InputAdornment";
import MenuItem from "@mui/material/MenuItem";
import Popover from "@mui/material/Popover";
import { AdminSwitch } from "@/shared/ui/AdminSwitch.jsx";
import TextField from "@mui/material/TextField";
import { useMemo, useState } from "react";
import {
    AdminFormDialog,
    AdminFormFieldGrid,
    AdminFormSection,
    AdminFormSwitchField,
} from "@/shared/ui/AdminFormDialog.jsx";
import { Button } from "@/shared/ui/Button.jsx";
import { DataState } from "@/shared/ui/DataState.jsx";
import { DataTable } from "@/shared/ui/DataTable.jsx";
import { InlineEditableCell } from "@/shared/ui/InlineEditableCell.jsx";
import { MultiValueAutocomplete } from "@/shared/ui/MultiValueAutocomplete.jsx";
import {
    AdminActionIconButton,
    AdminListBody,
    AdminListPage,
    AdminRowActions,
    AdminListToolbar,
} from "@/shared/ui/AdminListLayout.jsx";
import { createRegionColumnFilter } from "@/shared/ui/RegionFilterControl.jsx";
import { createOptionsColumnFilter, createTextColumnFilter } from "@/shared/ui/tableFilters.js";
import { formatMillis } from "@/shared/utils/time.js";
import { defaultGiftTypeOptions, resourceStatusFilters } from "@/features/resources/constants.js";
import { GiftTypeConfigDialog } from "@/features/resources/components/GiftTypeConfigDialog.jsx";
import { ResourceSelectField } from "@/features/resources/components/ResourceSelectDrawer.jsx";
import { useGiftListPage } from "@/features/resources/hooks/useResourcePages.js";
import styles from "@/features/resources/resources.module.css";

const effectOptions = [
    ["animation", "动画"],
    ["music", "音乐"],
    ["global_broadcast", "全局广播"],
];
const effectLabels = Object.fromEntries(effectOptions);
const weekLabels = ["一", "二", "三", "四", "五", "六", "日"];

const baseColumns = (giftTypeOptions) => [
    {
        key: "id",
        label: "ID",
        width: "minmax(88px, 0.4fr)",
        render: (gift) => gift.giftId || "-",
    },
    {
        key: "gift",
        label: "礼物",
        width: "minmax(260px, 1.4fr)",
        render: (gift) => <GiftIdentity gift={gift} />,
    },
    {
        key: "type",
        label: "类型",
        width: "minmax(130px, 0.6fr)",
        render: (gift) => giftTypeLabel(gift.giftTypeCode, giftTypeOptions),
    },
    {
        key: "price",
        label: "价格",
        width: "minmax(130px, 0.6fr)",
        render: (gift) => giftPriceLabel(gift),
    },
    {
        key: "regions",
        label: "区域",
        width: "minmax(160px, 0.8fr)",
    },
    {
        key: "sortOrder",
        label: "排序",
        width: "minmax(96px, 0.45fr)",
    },
    {
        key: "effects",
        label: "有效期 / 特效",
        width: "minmax(210px, 1.1fr)",
        render: (gift) => (
            <div className={styles.stack}>
                {giftEffectDetails(gift).map((item, index) => (
                    <span className={index > 0 ? styles.meta : undefined} key={item}>
                        {item}
                    </span>
                ))}
            </div>
        ),
    },
    {
        key: "status",
        label: "状态",
        width: "minmax(92px, 0.55fr)",
    },
    {
        key: "time",
        label: "更新时间",
        width: "minmax(170px, 0.9fr)",
        render: (gift) => formatMillis(gift.updatedAtMs || gift.createdAtMs),
    },
    {
        key: "actions",
        label: "操作",
        width: "minmax(76px, 0.4fr)",
    },
];

export function GiftListPage() {
    const page = useGiftListPage();
    const items = page.data.items || [];
    const total = page.data.total || 0;
    const isEditing = page.activeAction === "edit";
    const giftRegionOptions = [{ label: "全局 · 0", value: "0" }, ...page.regionOptions];
    const regionLabelById = buildRegionLabelMap(giftRegionOptions);
    const giftTypeOptions = page.giftTypeOptions?.length ? page.giftTypeOptions : defaultGiftTypeOptions;
    const tableColumns = baseColumns(giftTypeOptions).map((column) => {
        if (column.key === "regions") {
            return {
                ...column,
                filter: createRegionColumnFilter({
                    loading: page.loadingRegions,
                    options: giftRegionOptions,
                    value: page.regionId,
                    onChange: page.changeRegionId,
                }),
                render: (gift) => <RegionTags regionIds={gift.regionIds} regionLabelById={regionLabelById} />,
            };
        }
        if (column.key === "status") {
            return {
                ...column,
                filter: createOptionsColumnFilter({
                    options: resourceStatusFilters,
                    placeholder: "搜索状态",
                    value: page.status,
                    onChange: page.changeStatus,
                }),
                render: (gift) => <GiftStatusSwitch gift={gift} page={page} />,
            };
        }
        if (column.key === "type") {
            return {
                ...column,
                filter: createOptionsColumnFilter({
                    emptyLabel: "全部类型",
                    loading: page.giftTypesLoading,
                    options: giftTypeOptions.map((item) => ({
                        label: item.displayName || item.tabName || item.tabKey,
                        value: item.tabKey,
                    })),
                    placeholder: "搜索类型",
                    value: page.giftTypeCode,
                    onChange: page.changeGiftTypeCode,
                }),
            };
        }
        if (column.key === "sortOrder") {
            return {
                ...column,
                render: (gift) => <GiftSortOrderCell gift={gift} page={page} />,
            };
        }
        if (column.key === "gift") {
            return {
                ...column,
                filter: createTextColumnFilter({
                    placeholder: "搜索礼物名称、礼物 ID",
                    value: page.query,
                    onChange: page.changeQuery,
                }),
            };
        }
        if (column.key === "actions") {
            return {
                ...column,
                render: (gift) => <GiftRowActions gift={gift} page={page} />,
            };
        }
        return column;
    });

    return (
        <AdminListPage>
            <AdminListToolbar
                actions={
                    <>
                        {page.abilities.canUpdateGift ? (
                            <AdminActionIconButton label="礼物类型" onClick={page.openGiftTypeDialog}>
                                <SettingsOutlined fontSize="small" />
                            </AdminActionIconButton>
                        ) : null}
                        {page.abilities.canCreateGift ? (
                            <AdminActionIconButton label="添加礼物" primary onClick={page.openCreateGift}>
                                <Add fontSize="small" />
                            </AdminActionIconButton>
                        ) : null}
                    </>
                }
            />
            <DataState error={page.error} loading={page.loading} onRetry={page.reload}>
                <AdminListBody>
                    <DataTable
                        columns={tableColumns}
                        items={items}
                        minWidth="1440px"
                        pagination={
                            total > 0
                                ? {
                                      page: page.page,
                                      pageSize: page.data.pageSize || 50,
                                      total,
                                      onPageChange: page.setPage,
                                  }
                                : undefined
                        }
                        rowKey={(gift) => gift.giftId}
                    />
                </AdminListBody>
            </DataState>
            <GiftFormDialog
                disabled={isEditing ? !page.abilities.canUpdateGift : !page.abilities.canCreateGift}
                form={page.form}
                loading={isEditing ? page.loadingAction === "gift-edit" : page.loadingAction === "gift-create"}
                mode={isEditing ? "edit" : "create"}
                open={page.activeAction === "create" || page.activeAction === "edit"}
                page={page}
                regionOptions={giftRegionOptions}
                onClose={page.closeAction}
                onSubmit={page.submitGift}
            />
            <GiftTypeConfigDialog
                disabled={!page.abilities.canUpdateGift}
                form={page.giftTypeForm}
                loading={page.loadingAction === "gift-types"}
                open={page.giftTypeDialogOpen}
                optionsLoading={page.giftTypesLoading}
                onChangeItem={page.updateGiftTypeFormItem}
                onClose={page.closeGiftTypeDialog}
                onSubmit={page.submitGiftTypes}
            />
        </AdminListPage>
    );
}

function GiftRowActions({ gift, page }) {
    return (
        <AdminRowActions>
            <AdminActionIconButton
                disabled={!page.abilities.canUpdateGift}
                label="编辑礼物"
                onClick={() => page.openEditGift(gift)}
            >
                <EditOutlined fontSize="small" />
            </AdminActionIconButton>
        </AdminRowActions>
    );
}

function GiftStatusSwitch({ gift, page }) {
    const checked = gift.status === "active";
    return (
        <AdminSwitch
            checked={checked}
            disabled={!page.abilities.canStatusGift || page.loadingAction === `gift-status-${gift.giftId}`}
            inputProps={{ "aria-label": checked ? "禁用礼物" : "启用礼物" }}
            onChange={(event) => page.toggleGift(gift, event.target.checked)}
        />
    );
}

function GiftSortOrderCell({ gift, page }) {
    const originalValue = String(gift.sortOrder ?? 0);
    const saving = Boolean(page.giftSortSavingIds?.[gift.giftId]);
    return (
        <InlineEditableCell
            buttonTitle="点击编辑排序"
            editable={page.abilities.canUpdateGift}
            inputProps={{ min: 0, step: 1 }}
            maxWidth="76px"
            normalizeValue={(value) => String(value || "0").trim() || "0"}
            saving={saving}
            type="number"
            value={originalValue}
            width="76px"
            onSave={(nextValue) => page.saveGiftSortOrder(gift, nextValue)}
        />
    );
}

function GiftFormDialog({ disabled, form, loading, mode, onClose, onSubmit, open, page, regionOptions }) {
    const submitDisabled =
        disabled || loading || page.resourceOptionsLoading || page.loadingRegions || page.giftTypesLoading;
    const showGiftIdentityFields = mode === "edit" || Boolean(form.resourceId);
    return (
        <AdminFormDialog
            loading={loading}
            open={open}
            size="large"
            submitDisabled={submitDisabled}
            title={mode === "edit" ? "编辑礼物" : "添加礼物"}
            onClose={onClose}
            onSubmit={onSubmit}
        >
            <AdminFormSection title="资源信息">
                <AdminFormFieldGrid columns="repeat(2, minmax(0, 1fr))">
                    <ResourceSelectField
                        disabled={disabled || page.resourceOptionsLoading}
                        drawerTitle="选择礼物资源"
                        label="礼物资源"
                        loading={page.resourceOptionsLoading}
                        resources={page.resourceOptions}
                        value={form.resourceId}
                        onChange={(resourceId) => page.selectGiftResource(resourceId)}
                    />
                    {showGiftIdentityFields ? (
                        <>
                            <TextField
                                disabled={disabled}
                                label="礼物名称"
                                required
                                value={form.name}
                                onChange={(event) => page.setForm({ ...form, name: event.target.value })}
                            />
                            <TextField
                                disabled={disabled || mode === "edit"}
                                label="礼物 ID"
                                required
                                value={form.giftId}
                                onChange={(event) => page.setForm({ ...form, giftId: event.target.value })}
                            />
                        </>
                    ) : null}
                    <TextField
                        disabled={disabled || page.giftTypesLoading}
                        label="礼物类型"
                        required
                        select
                        value={form.giftTypeCode}
                        onChange={(event) => page.setForm({ ...form, giftTypeCode: event.target.value })}
                    >
                        {page.giftTypeOptions.map((item) => (
                            <MenuItem key={item.tabKey} value={item.tabKey}>
                                {item.displayName || item.tabKey}
                            </MenuItem>
                        ))}
                    </TextField>
                </AdminFormFieldGrid>
            </AdminFormSection>
            <AdminFormSection title="价格与排序">
                <AdminFormFieldGrid columns="repeat(2, minmax(0, 1fr))">
                    <TextField disabled label="价格" required type="number" value={form.coinPrice} />
                    <TextField
                        disabled={disabled}
                        label="排序"
                        type="number"
                        value={form.sortOrder}
                        onChange={(event) => page.setForm({ ...form, sortOrder: event.target.value })}
                    />
                    <AdminFormSwitchField
                        checked={form.enabled}
                        checkedLabel="启用"
                        className={styles.giftSwitch}
                        disabled={disabled}
                        label="礼物状态"
                        uncheckedLabel="禁用"
                        onChange={(checked) => page.setForm({ ...form, enabled: checked })}
                    />
                </AdminFormFieldGrid>
            </AdminFormSection>
            <AdminFormSection title="投放与时间">
                <AdminFormFieldGrid columns="repeat(2, minmax(0, 1fr))">
                    <GiftRegionSelect
                        disabled={disabled || page.loadingRegions}
                        labels={buildRegionLabelMap(regionOptions)}
                        options={regionOptions}
                        value={form.regionIds}
                        onChange={(regionIds) => page.setForm({ ...form, regionIds })}
                    />
                    <DateTimeField
                        disabled={disabled}
                        label="有效开始时间"
                        value={form.effectiveFrom}
                        onChange={(effectiveFrom) => page.setForm({ ...form, effectiveFrom })}
                    />
                    <DateTimeField
                        disabled={disabled}
                        label="有效结束时间"
                        value={form.effectiveTo}
                        onChange={(effectiveTo) => page.setForm({ ...form, effectiveTo })}
                    />
                    <GiftEffectSelect
                        disabled={disabled}
                        value={form.effectTypes}
                        onChange={(effectTypes) => page.setForm({ ...form, effectTypes })}
                    />
                </AdminFormFieldGrid>
            </AdminFormSection>
        </AdminFormDialog>
    );
}

function DateTimeField({ disabled, label, onChange, value }) {
    const parsedValue = parseLocalDateTime(value);
    const [anchorEl, setAnchorEl] = useState(null);
    const [draftDate, setDraftDate] = useState(parsedValue || new Date());
    const [viewDate, setViewDate] = useState(parsedValue || new Date());
    const days = useMemo(() => calendarDays(viewDate), [viewDate]);
    const open = Boolean(anchorEl);

    const openPicker = (event) => {
        if (disabled) {
            return;
        }
        const baseDate = parseLocalDateTime(value) || new Date();
        setDraftDate(baseDate);
        setViewDate(new Date(baseDate.getFullYear(), baseDate.getMonth(), 1));
        setAnchorEl(event.currentTarget);
    };

    const closePicker = () => setAnchorEl(null);
    const changeMonth = (offset) => {
        setViewDate((current) => new Date(current.getFullYear(), current.getMonth() + offset, 1));
    };
    const changeDay = (day) => {
        setDraftDate(
            (current) =>
                new Date(day.getFullYear(), day.getMonth(), day.getDate(), current.getHours(), current.getMinutes()),
        );
        setViewDate(new Date(day.getFullYear(), day.getMonth(), 1));
    };
    const changeTime = (unit, nextValue) => {
        setDraftDate((current) => {
            const nextDate = new Date(current);
            if (unit === "hour") {
                nextDate.setHours(Number(nextValue));
            } else {
                nextDate.setMinutes(Number(nextValue));
            }
            return nextDate;
        });
    };

    return (
        <>
            <TextField
                className={styles.dateTimeField}
                disabled={disabled}
                inputProps={{ readOnly: true }}
                InputProps={{
                    endAdornment: (
                        <InputAdornment position="end">
                            <CalendarMonthOutlined fontSize="small" />
                        </InputAdornment>
                    ),
                }}
                label={label}
                placeholder="长期有效"
                value={formatDateTimeInputLabel(value)}
                onClick={openPicker}
            />
            <Popover
                anchorEl={anchorEl}
                anchorOrigin={{ horizontal: "left", vertical: "bottom" }}
                open={open}
                transformOrigin={{ horizontal: "left", vertical: "top" }}
                onClose={closePicker}
            >
                <div className={styles.datePopover}>
                    <div className={styles.calendarHeader}>
                        <IconButton aria-label="上个月" size="small" onClick={() => changeMonth(-1)}>
                            <ChevronLeftOutlined fontSize="small" />
                        </IconButton>
                        <span className={styles.calendarTitle}>{monthTitle(viewDate)}</span>
                        <IconButton aria-label="下个月" size="small" onClick={() => changeMonth(1)}>
                            <ChevronRightOutlined fontSize="small" />
                        </IconButton>
                    </div>
                    <div className={styles.calendarGrid}>
                        {weekLabels.map((weekday) => (
                            <span className={styles.weekday} key={weekday}>
                                {weekday}
                            </span>
                        ))}
                        {days.map((day) => {
                            const isOutside = day.getMonth() !== viewDate.getMonth();
                            const isSelected = sameDay(day, draftDate);
                            return (
                                <button
                                    className={[
                                        styles.dayButton,
                                        isOutside ? styles.dayOutside : "",
                                        isSelected ? styles.daySelected : "",
                                    ]
                                        .filter(Boolean)
                                        .join(" ")}
                                    key={day.toISOString()}
                                    type="button"
                                    onClick={() => changeDay(day)}
                                >
                                    {day.getDate()}
                                </button>
                            );
                        })}
                    </div>
                    <div className={styles.timeGrid}>
                        <TextField
                            label="时"
                            select
                            size="small"
                            value={String(draftDate.getHours())}
                            onChange={(event) => changeTime("hour", event.target.value)}
                        >
                            {Array.from({ length: 24 }, (_, hour) => (
                                <MenuItem key={hour} value={String(hour)}>
                                    {twoDigits(hour)}
                                </MenuItem>
                            ))}
                        </TextField>
                        <TextField
                            label="分"
                            select
                            size="small"
                            value={String(draftDate.getMinutes())}
                            onChange={(event) => changeTime("minute", event.target.value)}
                        >
                            {Array.from({ length: 60 }, (_, minute) => (
                                <MenuItem key={minute} value={String(minute)}>
                                    {twoDigits(minute)}
                                </MenuItem>
                            ))}
                        </TextField>
                    </div>
                    <div className={styles.popoverActions}>
                        <Button
                            onClick={() => {
                                onChange("");
                                closePicker();
                            }}
                        >
                            清空
                        </Button>
                        <Button
                            variant="primary"
                            onClick={() => {
                                onChange(toDatetimeLocalValue(draftDate));
                                closePicker();
                            }}
                        >
                            确定
                        </Button>
                    </div>
                </div>
            </Popover>
        </>
    );
}

function GiftRegionSelect({ disabled, labels, onChange, options, value }) {
    const selected = value || [];
    const mergedOptions = [...new Set([...options.map((option) => option.value), ...selected])].sort(
        (left, right) => Number(left) - Number(right),
    );
    return (
        <MultiValueAutocomplete
            disabled={disabled}
            label="区域"
            labels={labels}
            options={mergedOptions}
            required
            value={selected}
            onChange={onChange}
        />
    );
}

function GiftEffectSelect({ disabled, onChange, value }) {
    const selected = value || [];
    return (
        <MultiValueAutocomplete
            disabled={disabled}
            label="特效"
            labels={effectLabels}
            options={effectOptions.map(([optionValue]) => optionValue)}
            value={selected}
            onChange={onChange}
        />
    );
}

function RegionTags({ regionIds = [], regionLabelById }) {
    const items = [...new Set(regionIds)].sort((left, right) => Number(left) - Number(right));
    if (!items.length) {
        return "-";
    }
    return (
        <div className="admin-tag-list">
            {items.map((regionId) => (
                <span className="admin-tag" key={regionId}>
                    {regionLabelById[String(regionId)] || regionId}
                </span>
            ))}
        </div>
    );
}

function GiftIdentity({ gift }) {
    const preview = imageURL(gift.resource?.previewUrl || gift.resource?.assetUrl);
    const resourceCode = String(gift.resource?.resourceCode || "").trim();
    const title = `${gift.name || "-"}${resourceCode ? `（${resourceCode}）` : ""}`;
    return (
        <div className={styles.identity}>
            <span className={styles.thumb}>
                {preview ? <img src={preview} alt="" /> : <CardGiftcardOutlined fontSize="small" />}
            </span>
            <div className={styles.identityText}>
                <span className={styles.name}>{title}</span>
            </div>
        </div>
    );
}

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

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

function giftTypeLabel(value, options = defaultGiftTypeOptions) {
    return options.find((option) => option.tabKey === value)?.displayName || value || "普通礼物";
}

function giftPriceLabel(gift) {
    return `金币 · ${formatNumber(gift.coinPrice)}`;
}

function effectTypeLabel(value) {
    return effectOptions.find(([optionValue]) => optionValue === value)?.[1] || value;
}

function effectTypesLabel(values) {
    const list = values || [];
    return list.length ? list.map(effectTypeLabel).join("、") : "无特效";
}

function giftEffectDetails(gift) {
    const details = [];
    const effective = effectiveRangeLabel(gift);
    if (effective) {
        details.push(effective);
    }
    const effects = effectTypesLabel(gift.effectTypes);
    if (effects !== "无特效") {
        details.push(effects);
    }
    return details.length ? details : ["-"];
}

function parseLocalDateTime(value) {
    const normalizedValue = String(value || "").trim();
    if (!normalizedValue) {
        return null;
    }
    const [datePart, timePart = "00:00"] = normalizedValue.split("T");
    const [year, month, day] = datePart.split("-").map(Number);
    const [hour = 0, minute = 0] = timePart.split(":").map(Number);
    if (![year, month, day, hour, minute].every(Number.isFinite)) {
        return null;
    }
    const date = new Date(year, month - 1, day, hour, minute);
    return Number.isNaN(date.getTime()) ? null : date;
}

function toDatetimeLocalValue(date) {
    return `${date.getFullYear()}-${twoDigits(date.getMonth() + 1)}-${twoDigits(date.getDate())}T${twoDigits(date.getHours())}:${twoDigits(date.getMinutes())}`;
}

function formatDateTimeInputLabel(value) {
    const date = parseLocalDateTime(value);
    if (!date) {
        return "";
    }
    return `${date.getFullYear()}-${twoDigits(date.getMonth() + 1)}-${twoDigits(date.getDate())} ${twoDigits(date.getHours())}:${twoDigits(date.getMinutes())}`;
}

function calendarDays(viewDate) {
    const firstDay = new Date(viewDate.getFullYear(), viewDate.getMonth(), 1);
    const offset = (firstDay.getDay() + 6) % 7;
    const startDate = new Date(firstDay);
    startDate.setDate(firstDay.getDate() - offset);
    return Array.from({ length: 42 }, (_, index) => {
        const day = new Date(startDate);
        day.setDate(startDate.getDate() + index);
        return day;
    });
}

function sameDay(left, right) {
    return (
        left.getFullYear() === right.getFullYear() &&
        left.getMonth() === right.getMonth() &&
        left.getDate() === right.getDate()
    );
}

function monthTitle(date) {
    return `${date.getFullYear()}年 ${date.getMonth() + 1}月`;
}

function twoDigits(value) {
    return String(value).padStart(2, "0");
}

function effectiveRangeLabel(gift) {
    if (!gift.effectiveFromMs && !gift.effectiveToMs) {
        return "";
    }
    return `${shortDateTime(gift.effectiveFromMs) || "不限"} - ${shortDateTime(gift.effectiveToMs) || "不限"}`;
}

function shortDateTime(value) {
    if (!value) {
        return "";
    }
    return new Intl.DateTimeFormat("zh-CN", {
        month: "2-digit",
        day: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
    }).format(new Date(Number(value)));
}

function buildRegionLabelMap(options = []) {
    return options.reduce((acc, option) => {
        acc[option.value] = shortRegionLabel(option.label);
        return acc;
    }, {});
}

function shortRegionLabel(label) {
    return String(label || "").split(" · ")[0] || String(label || "");
}
