import AddOutlined from "@mui/icons-material/AddOutlined";
import DeleteOutlineOutlined from "@mui/icons-material/DeleteOutlineOutlined";
import InputAdornment from "@mui/material/InputAdornment";
import MenuItem from "@mui/material/MenuItem";
import TextField from "@mui/material/TextField";
import { useEffect, useMemo, useRef, useState } from "react";
import {
    adapterCatalogRows,
    adapterCommonFields,
    adapterConfigFieldValue,
    adapterDefinition,
    formatAdapterConfigJson,
    readAdapterConfig,
    updateAdapterCatalog,
    updateAdapterConfigField,
} from "@/features/games/adapterConfigModel.js";
import { Button } from "@/shared/ui/Button.jsx";
import { JsonEditorField } from "@/shared/ui/JsonEditorField.jsx";
import styles from "@/features/games/components/AdapterConfigFields.module.css";

export function AdapterConfigFields({ adapterType, disabled = false, value, onChange }) {
    const definition = adapterDefinition(adapterType);
    const configValid = Boolean(readAdapterConfig(value));
    const visualFieldsDisabled = disabled || !configValid;

    return (
        <div className={styles.root}>
            {!configValid ? <div className={styles.invalid}>请先在高级配置中修正 JSON 格式</div> : null}
            <ConfigFieldGroup
                disabled={visualFieldsDisabled}
                fields={adapterCommonFields()}
                title="会话参数"
                value={value}
                onChange={onChange}
            />
            {(definition.fields || []).length > 0 ? (
                <ConfigFieldGroup
                    disabled={visualFieldsDisabled}
                    fields={definition.fields}
                    title="厂商参数"
                    value={value}
                    onChange={onChange}
                />
            ) : null}
            {definition.catalog ? (
                <GameCatalogEditor
                    adapterType={adapterType}
                    disabled={visualFieldsDisabled}
                    value={value}
                    onChange={onChange}
                />
            ) : null}
            {(definition.advancedFields || []).length > 0 ? (
                <details className={styles.details}>
                    <summary>可选厂商参数</summary>
                    <ConfigFieldGrid
                        disabled={visualFieldsDisabled}
                        fields={definition.advancedFields}
                        value={value}
                        onChange={onChange}
                    />
                </details>
            ) : null}
            <details className={styles.details} open={configValid ? undefined : true}>
                <summary>高级配置 · 完整 JSON</summary>
                <div className={styles.advancedEditor}>
                    <JsonEditorField
                        disabled={disabled}
                        formatter={formatAdapterConfigJson}
                        label="完整配置 JSON"
                        minRows={5}
                        value={value}
                        onChange={onChange}
                    />
                </div>
            </details>
        </div>
    );
}

function ConfigFieldGroup({ disabled, fields, title, value, onChange }) {
    return (
        <section className={styles.group}>
            <div className={styles.groupTitle}>{title}</div>
            <ConfigFieldGrid disabled={disabled} fields={fields} value={value} onChange={onChange} />
        </section>
    );
}

function ConfigFieldGrid({ disabled, fields, value, onChange }) {
    return (
        <div className={styles.fieldGrid}>
            {fields.map((field) => (
                <AdapterField
                    disabled={disabled}
                    field={field}
                    key={field.key}
                    value={adapterConfigFieldValue(value, field)}
                    onChange={(inputValue) => onChange(updateAdapterConfigField(value, field, inputValue))}
                />
            ))}
        </div>
    );
}

function AdapterField({ disabled, field, value, onChange }) {
    const className = field.className === "wide" ? styles.wideField : undefined;
    const commonProps = {
        className,
        disabled,
        label: field.label,
        placeholder: field.placeholder,
        required: field.required,
        value,
        onChange: (event) => onChange(event.target.value),
    };

    if (field.type === "select" || field.type === "selectNumber" || field.type === "selectBoolean") {
        return (
            <TextField {...commonProps} select>
                {(field.options || []).map(([optionValue, optionLabel]) => (
                    <MenuItem key={`${field.key}-${optionValue}`} value={optionValue}>
                        {optionLabel}
                    </MenuItem>
                ))}
            </TextField>
        );
    }

    return (
        <TextField
            {...commonProps}
            slotProps={{
                htmlInput: {
                    min: field.min,
                    step: field.type === "integer" ? 1 : undefined,
                },
                input: field.unit
                    ? { endAdornment: <InputAdornment position="end">{field.unit}</InputAdornment> }
                    : undefined,
            }}
            type={field.type === "integer" ? "number" : "text"}
        />
    );
}

function GameCatalogEditor({ adapterType, disabled, value, onChange }) {
    const definition = adapterDefinition(adapterType);
    const externalRows = useMemo(() => adapterCatalogRows(value), [value]);
    const externalSignature = useMemo(() => catalogSignature(externalRows), [externalRows]);
    const lastEmittedSignature = useRef(externalSignature);
    const adapterTypeRef = useRef(adapterType);
    const rowSequence = useRef(externalRows.length);
    const [rows, setRows] = useState(() => withRowKeys(externalRows, "initial"));

    useEffect(() => {
        const adapterChanged = adapterTypeRef.current !== adapterType;
        if (adapterChanged || externalSignature !== lastEmittedSignature.current) {
            rowSequence.current += externalRows.length;
            setRows(withRowKeys(externalRows, `sync-${rowSequence.current}`));
        }
        adapterTypeRef.current = adapterType;
        lastEmittedSignature.current = externalSignature;
    }, [adapterType, externalRows, externalSignature]);

    const emitRows = (nextRows) => {
        setRows(nextRows);
        const nextValue = updateAdapterCatalog(value, nextRows);
        lastEmittedSignature.current = catalogSignature(adapterCatalogRows(nextValue));
        onChange(nextValue);
    };

    const addRow = () => {
        rowSequence.current += 1;
        setRows((current) => [
            ...current,
            {
                rowKey: `draft-${rowSequence.current}`,
                providerGameId: "",
                gameName: "",
                gameUrl: "",
                iconUrl: "",
                coverUrl: "",
                gameLevelUid: "",
            },
        ]);
    };

    const changeRow = (rowKey, patch) => {
        emitRows(rows.map((row) => (row.rowKey === rowKey ? { ...row, ...patch } : row)));
    };

    const removeRow = (rowKey) => {
        emitRows(rows.filter((row) => row.rowKey !== rowKey));
    };

    return (
        <section className={styles.catalog}>
            <div className={styles.catalogHeader}>
                <div className={styles.groupTitle}>游戏目录 · {rows.length}</div>
                <Button disabled={disabled} onClick={addRow}>
                    <AddOutlined fontSize="small" />
                    添加游戏
                </Button>
            </div>
            {rows.length > 0 ? (
                <div className={styles.catalogRows}>
                    {rows.map((row, index) => {
                        const duplicate =
                            row.providerGameId.trim() !== "" &&
                            rows.some(
                                (candidate, candidateIndex) =>
                                    candidateIndex !== index &&
                                    candidate.providerGameId.trim() === row.providerGameId.trim(),
                            );
                        return (
                            <div className={styles.catalogRow} key={row.rowKey}>
                                <div className={styles.catalogMain}>
                                    <TextField
                                        disabled={disabled}
                                        error={duplicate}
                                        helperText={duplicate ? "游戏 ID 重复" : undefined}
                                        label={definition.numericGameID ? "游戏 ID（正整数）" : "游戏 ID"}
                                        required
                                        slotProps={{
                                            // 重复 ID 无法同时写进 JSON 对象；用原生 pattern 阻止提交，并保留当前行供用户修正。
                                            htmlInput: {
                                                inputMode: definition.numericGameID ? "numeric" : undefined,
                                                pattern: duplicate
                                                    ? "a^"
                                                    : definition.numericGameID
                                                      ? "[1-9][0-9]*"
                                                      : undefined,
                                            },
                                        }}
                                        value={row.providerGameId}
                                        onChange={(event) =>
                                            changeRow(row.rowKey, { providerGameId: event.target.value })
                                        }
                                    />
                                    <TextField
                                        disabled={disabled}
                                        label="游戏名称"
                                        required={definition.catalogPrimary === "name"}
                                        value={row.gameName}
                                        onChange={(event) => changeRow(row.rowKey, { gameName: event.target.value })}
                                    />
                                    <TextField
                                        disabled={disabled}
                                        label="H5 URL"
                                        required={definition.catalogPrimary !== "name"}
                                        value={row.gameUrl}
                                        onChange={(event) => changeRow(row.rowKey, { gameUrl: event.target.value })}
                                    />
                                    <Button
                                        aria-label={`删除第 ${index + 1} 个游戏`}
                                        disabled={disabled}
                                        onClick={() => removeRow(row.rowKey)}
                                    >
                                        <DeleteOutlineOutlined fontSize="small" />
                                    </Button>
                                </div>
                                <details className={styles.rowDetails}>
                                    <summary>素材与游戏参数</summary>
                                    <div className={styles.rowExtra}>
                                        <TextField
                                            disabled={disabled}
                                            label="图标 URL"
                                            value={row.iconUrl}
                                            onChange={(event) => changeRow(row.rowKey, { iconUrl: event.target.value })}
                                        />
                                        <TextField
                                            disabled={disabled}
                                            label="封面 URL"
                                            value={row.coverUrl}
                                            onChange={(event) =>
                                                changeRow(row.rowKey, { coverUrl: event.target.value })
                                            }
                                        />
                                        {adapterType === "yomi_v4" ? (
                                            <TextField
                                                disabled={disabled}
                                                label="场次 ID"
                                                slotProps={{ htmlInput: { min: 1, step: 1 } }}
                                                type="number"
                                                value={row.gameLevelUid}
                                                onChange={(event) =>
                                                    changeRow(row.rowKey, { gameLevelUid: event.target.value })
                                                }
                                            />
                                        ) : null}
                                    </div>
                                </details>
                            </div>
                        );
                    })}
                </div>
            ) : (
                <div className={styles.empty}>当前无游戏目录</div>
            )}
        </section>
    );
}

function withRowKeys(rows, prefix) {
    return rows.map((row, index) => ({ ...row, rowKey: `${prefix}-${index}` }));
}

function catalogSignature(rows) {
    return JSON.stringify(
        (rows || []).map(({ providerGameId, gameName, gameUrl, iconUrl, coverUrl, gameLevelUid }) => ({
            providerGameId,
            gameName,
            gameUrl,
            iconUrl,
            coverUrl,
            gameLevelUid,
        })),
    );
}
