import { Label } from '@/components/ui/label';
import { cn } from '@/lib/utils';
import type { UserRole } from '@/types';
import { getRoleOption, USER_ROLE_OPTIONS } from './constants';

type Props = {
    id?: string;
    name: string;
    value: string;
    roles?: UserRole[];
    error?: string;
    onChange: (value: string) => void;
};

export function RoleSelector({
    id = 'role',
    name,
    value,
    roles,
    error,
    onChange,
}: Props) {
    const roleOptions = roles?.length
        ? roles.map((role) => {
              const fallback = getRoleOption(role.name);

              return {
                  value: role.name,
                  label: role.label ?? fallback?.label ?? role.name,
                  description:
                      role.description ??
                      fallback?.description ??
                      'Rol del sistema',
                  icon: fallback?.icon ?? USER_ROLE_OPTIONS[0].icon,
              };
          })
        : USER_ROLE_OPTIONS;

    return (
        <div className="flex flex-col gap-3">
            <Label htmlFor={id}>Rol asignado</Label>
            <div className="grid grid-cols-2 gap-3 md:grid-cols-3">
                {roleOptions.map((option) => {
                    const Icon = option.icon;
                    const isSelected = option.value === value;

                    return (
                        <label
                            key={option.value}
                            htmlFor={`${id}-${option.value}`}
                            className={cn(
                                'group flex min-h-32 cursor-pointer flex-col items-center justify-center gap-3 rounded-2xl border bg-muted/35 p-4 text-center transition-all',
                                isSelected
                                    ? 'border-primary bg-primary/6 shadow-sm'
                                    : 'border-border hover:border-primary/40 hover:bg-accent/50',
                            )}
                        >
                            <input
                                id={`${id}-${option.value}`}
                                type="radio"
                                name={name}
                                value={option.value}
                                className="sr-only"
                                checked={isSelected}
                                onChange={() => onChange(option.value)}
                            />
                            <span
                                className={cn(
                                    'flex size-10 items-center justify-center rounded-xl border bg-background/80 text-muted-foreground transition-colors',
                                    isSelected && 'border-primary text-primary',
                                )}
                            >
                                <Icon className="size-4" />
                            </span>
                            <span className="text-sm leading-tight font-medium">
                                {option.label}
                            </span>
                            <span className="text-xs leading-tight text-muted-foreground">
                                {option.description}
                            </span>
                        </label>
                    );
                })}
            </div>
            {error && (
                <p className="text-sm text-red-600 dark:text-red-400">
                    {error}
                </p>
            )}
        </div>
    );
}
