'use client';

import { AsyncCombobox, usePaginatedLookup } from '@/components/async-combobox';
import type { AsyncComboboxOption } from '@/components/async-combobox';
import { roleService } from '@/services/api';
import type { Role } from '@/types';

import { roleKeys } from '@/app/(modules)/roles/queries/roleKeys';
import type { RoleComboboxProps } from './RoleCombobox.types';

const ROLE_PAGE_SIZE = 20;

function parseRoleId(value: string) {
  const roleId = Number(value);
  return Number.isFinite(roleId) ? roleId : null;
}

function mapRoleOption(role: Role): AsyncComboboxOption {
  return {
    value: String(role.id),
    label: role.display_name || role.name,
  };
}

export function RoleCombobox({
  value,
  onValueChange,
  enabled = true,
  disabled = false,
  portalContainer,
}: RoleComboboxProps) {
  const lookup = usePaginatedLookup<Role>({
    enabled,
    selectedValue: value,
    pageSize: ROLE_PAGE_SIZE,
    queryKey: (searchTerm) =>
      [
        ...roleKeys.lists(),
        'async-lookup',
        searchTerm,
        ROLE_PAGE_SIZE,
      ] as const,
    queryFn: ({ searchTerm, skip, limit }) =>
      roleService.getRoles({
        search_term: searchTerm || undefined,
        skip,
        limit,
        effective_status: true,
        sort_by: 'display_name',
        sort_order: 'asc',
      }),
    mapOption: mapRoleOption,
    resolveSelected: (roleId) => {
      const numericRoleId = parseRoleId(roleId);
      return numericRoleId
        ? roleService.getRoleById(numericRoleId)
        : Promise.resolve(null);
    },
    resolveSelectedQueryKey: (roleId) => {
      const numericRoleId = parseRoleId(roleId);
      return numericRoleId
        ? roleKeys.detail(numericRoleId)
        : [...roleKeys.details(), 'invalid', roleId];
    },
  });

  return (
    <AsyncCombobox
      lookup={lookup}
      onValueChange={onValueChange}
      disabled={disabled}
      placeholder="Select role"
      searchPlaceholder="Search roles..."
      emptyMessage="No roles found."
      portalContainer={portalContainer}
    />
  );
}
