import Checkbox from "@mui/material/Checkbox";
import CircularProgress from "@mui/material/CircularProgress";
import { useMemo } from "react";
import { Button } from "@/shared/ui/Button.jsx";
import styles from "@/features/external-admin-users/external-admin-users.module.css";
import {
    updatePermissionGroup,
    updatePermissionSelection,
} from "@/features/external-admin-users/permissionSelection.js";

export { updatePermissionSelection } from "@/features/external-admin-users/permissionSelection.js";

export function ExternalAdminPermissionSelector({
    catalog = [],
    disabled = false,
    error = "",
    loading = false,
    onChange,
    onRetry,
    value = [],
}) {
    const groups = useMemo(() => groupCatalog(catalog), [catalog]);
    const knownCodes = useMemo(() => catalog.map((permission) => permission.code), [catalog]);
    const selected = useMemo(() => new Set(value), [value]);
    const selectedCount = knownCodes.filter((code) => selected.has(code)).length;

    if (loading) {
        return (
            <div className={styles.permissionState} role="status">
                <CircularProgress size={22} />
                <span>加载权限目录</span>
            </div>
        );
    }

    if (error) {
        return (
            <div className={styles.permissionState} role="alert">
                <span>{error}</span>
                {onRetry ? <Button onClick={onRetry}>重新加载</Button> : null}
            </div>
        );
    }

    return (
        <div className={styles.permissionSelector}>
            <div className={styles.permissionToolbar}>
                <strong>
                    已选 {selectedCount} / {knownCodes.length} 项
                </strong>
                <div className={styles.permissionToolbarActions}>
                    <Button
                        disabled={disabled || selectedCount === knownCodes.length}
                        onClick={() => onChange?.(knownCodes)}
                    >
                        全选
                    </Button>
                    <Button disabled={disabled || selectedCount === 0} onClick={() => onChange?.([])}>
                        清空
                    </Button>
                </div>
            </div>

            {groups.length ? (
                <div className={styles.permissionGroups}>
                    {groups.map((group) => {
                        const groupCodes = group.items.map((permission) => permission.code);
                        const groupSelectedCount = groupCodes.filter((code) => selected.has(code)).length;
                        return (
                            <section className={styles.permissionGroup} key={group.name}>
                                <header className={styles.permissionGroupHeader}>
                                    <strong>{group.name}</strong>
                                    <label>
                                        <Checkbox
                                            checked={groupSelectedCount === groupCodes.length}
                                            disabled={disabled}
                                            indeterminate={groupSelectedCount > 0 && groupSelectedCount < groupCodes.length}
                                            slotProps={{ input: { "aria-label": `${group.name}全选` } }}
                                            size="small"
                                            onChange={(event) =>
                                                onChange?.(
                                                    updatePermissionGroup(
                                                        catalog,
                                                        value,
                                                        groupCodes,
                                                        event.target.checked,
                                                    ),
                                                )
                                            }
                                        />
                                        <span>
                                            {groupSelectedCount}/{groupCodes.length}
                                        </span>
                                    </label>
                                </header>
                                <div className={styles.permissionOptions}>
                                    {group.items.map((permission) => {
                                        return (
                                            <label className={styles.permissionOption} key={permission.code}>
                                                <Checkbox
                                                    checked={selected.has(permission.code)}
                                                    disabled={disabled}
                                                    slotProps={{ input: { "aria-label": permission.label } }}
                                                    size="small"
                                                    onChange={(event) =>
                                                        onChange?.(
                                                            updatePermissionSelection(
                                                                catalog,
                                                                value,
                                                                permission.code,
                                                                event.target.checked,
                                                            ),
                                                        )
                                                    }
                                                />
                                                <span>
                                                    <strong>{permission.label}</strong>
                                                </span>
                                            </label>
                                        );
                                    })}
                                </div>
                            </section>
                        );
                    })}
                </div>
            ) : (
                <div className={styles.permissionState}>当前无可配置权限</div>
            )}
        </div>
    );
}

function groupCatalog(catalog) {
    const groups = new Map();
    catalog.forEach((permission) => {
        const groupName = permission.group || "其他";
        if (!groups.has(groupName)) {
            groups.set(groupName, []);
        }
        groups.get(groupName).push(permission);
    });
    return [...groups].map(([name, items]) => ({ items, name }));
}
