import { Checkbox } from "@/features/shared/components/ui/checkbox";
import { cn } from "@/features/shared/lib/utils";
import type { Permission } from "@/features/shared/types";

type PermissionGroupSelectorProps = {
    permissions: Permission[];
    processing?: boolean;
    error?: string;
    errors?: Record<string, string | string[] | undefined>;
    groupLabels?: Record<string, string>;
    selectedPermissionNames: string[];
    onTogglePermission: (permissionName: string, checked: boolean) => void;
};

export default function PermissionGroupSelector({
    permissions,
    processing = false,
    error,
    errors,
    groupLabels = {},
    selectedPermissionNames,
    onTogglePermission,
}: PermissionGroupSelectorProps) {
    const groupedPermissions = permissions.reduce<Record<string, Permission[]>>((groups, permission) => {
        const [groupKey] = permission.name.split(".");

        if (!groups[groupKey]) {
            groups[groupKey] = [];
        }

        groups[groupKey].push(permission);

        return groups;
    }, {});

    const sortedGroupEntries = Object.entries(groupedPermissions).sort(([first], [second]) => first.localeCompare(second));

    const formatActionLabel = (permissionName: string): string => {
        const [, action = permissionName] = permissionName.split(".");

        return action
            .replaceAll("_", " ")
            .replaceAll("-", " ")
            .replace(/\b\w/g, (char) => char.toUpperCase());
    };

    const normalizedPermissionError = (() => {
        if (error) {
            return error;
        }

        if (!errors) {
            return undefined;
        }

        const directError = errors.permissions;

        if (typeof directError === "string") {
            return directError;
        }

        if (Array.isArray(directError)) {
            return directError[0];
        }

        const nestedEntry = Object.entries(errors).find(([key]) => key.startsWith("permissions."));

        if (!nestedEntry) {
            return undefined;
        }

        const [, nestedValue] = nestedEntry;

        if (typeof nestedValue === "string") {
            return nestedValue;
        }

        if (Array.isArray(nestedValue)) {
            return nestedValue[0];
        }

        return undefined;
    })();

    return (
        <div className="flex flex-col gap-4">
            {normalizedPermissionError && (
                <p className="text-sm text-red-600">{normalizedPermissionError}</p>
            )}
            {sortedGroupEntries.map(([groupKey, groupPermissions]) => (
                <div key={groupKey} className="p-4">
                    <div className="mb-2 flex items-baseline gap-2">
                        <p className="text-lg font-semibold uppercase text-gray-700">{groupKey}</p>
                        {groupLabels[groupKey] && (
                            <p className=" text-gray-500">{groupLabels[groupKey]}</p>
                        )}
                    </div>

                    <div className="grid gap-3 md:grid-cols-2 lg:grid-cols-4">
                        {groupPermissions.map((permission) => (
                            <label
                                key={permission.id}
                                className={cn(
                                    "flex cursor-pointer items-center gap-2 rounded-md border border-gray-200 px-3 py-2 hover:bg-gray-50",
                                    processing && "cursor-not-allowed opacity-50",
                                    error && "border-red-600",
                                )}
                            >
                                <Checkbox
                                    id={`permission-${permission.id}`}
                                    disabled={processing}
                                    checked={selectedPermissionNames.includes(permission.name)}
                                    onCheckedChange={(checked) => onTogglePermission(permission.name, checked === true)}
                                />
                                <div className="flex flex-col">
                                    <p className="text-sm font-medium text-gray-800">
                                        {formatActionLabel(permission.name)}
                                    </p>
                                    <p className="text-xs text-gray-500">{permission.name}</p>
                                </div>
                            </label>
                        ))}
                    </div>
                </div>
            ))}
        </div>
    );
}
