'use client';

import { useState } from 'react';
import { Check, ChevronsUpDown } from 'lucide-react';
import { useQuery } from '@tanstack/react-query';

import { Button } from '@/components/ui/button';
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from '@/components/ui/command';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { useDebounce } from '@/hooks/use-debounce';
import { apiFetch } from '@/lib/api/client';
import { cn } from '@/lib/utils';

export type OwnerRef = { type: 'client' | 'company'; id: string };

interface OwnerOption {
  id: string;
  name?: string | null;
  fullName?: string | null;
}

interface OwnerPickerProps {
  value: OwnerRef | null;
  onChange: (value: OwnerRef | null) => void;
  /** Optional placeholder when empty */
  placeholder?: string;
  /** Disable the component */
  disabled?: boolean;
}

export function OwnerPicker({
  value,
  onChange,
  placeholder = 'Select owner...',
  disabled,
}: OwnerPickerProps) {
  const [open, setOpen] = useState(false);
  // `type` is derived: when an owner is selected the prop wins; with no
  // selection the user's local tab pick is the source of truth. Render-
  // phase derivation replaces the prior useEffect(setType, [value?.type])
  // that the Compiler flagged as set-state-in-effect.
  const [localType, setLocalType] = useState<'client' | 'company'>(value?.type ?? 'client');
  const type: 'client' | 'company' = value?.type ?? localType;
  const setType = setLocalType;
  const [search, setSearch] = useState('');
  const debounced = useDebounce(search, 300);

  const endpoint =
    type === 'client'
      ? `/api/v1/clients/options?search=${encodeURIComponent(debounced)}`
      : `/api/v1/companies/autocomplete?q=${encodeURIComponent(debounced)}`;

  const { data } = useQuery<{ data: OwnerOption[] }>({
    queryKey: ['owner-picker', type, debounced],
    queryFn: () => apiFetch(endpoint),
    enabled: open,
  });

  const options = data?.data ?? [];

  // Resolve the current value's display name even before the picker is opened.
  // Without this primer query the trigger button rendered "Client <8-char-id>"
  // on first paint and only filled in the real name after the user opened the
  // dropdown (which kicked the list query). The lookup hits a per-id endpoint
  // when possible and falls back to scanning the cached options array.
  const valueLookupEndpoint = value
    ? value.type === 'client'
      ? `/api/v1/clients/${value.id}`
      : `/api/v1/companies/${value.id}`
    : null;

  const { data: valueDetail } = useQuery<{
    data: { id: string; name?: string | null; fullName?: string | null };
  }>({
    queryKey: ['owner-picker-resolve', value?.type, value?.id],
    queryFn: () => apiFetch(valueLookupEndpoint!),
    enabled: !!value && !!valueLookupEndpoint,
    staleTime: 60_000,
  });

  // Selected display label - prefer the resolved entity name; fall back to a
  // truncated id only when both the primer query and the options list miss.
  const selectedLabel = (() => {
    if (!value) return placeholder;
    if (valueDetail?.data) {
      const name = value.type === 'client' ? valueDetail.data.fullName : valueDetail.data.name;
      if (name) return name;
    }
    const match = options.find((o) => o.id === value.id);
    if (match) {
      return type === 'client'
        ? (match.fullName ?? '(unnamed client)')
        : (match.name ?? '(unnamed company)');
    }
    return value.type === 'client'
      ? `Client ${value.id.slice(0, 8)}`
      : `Company ${value.id.slice(0, 8)}`;
  })();

  return (
    <Popover open={open} onOpenChange={setOpen} modal>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          disabled={disabled}
          className={cn('w-full justify-between', !value && 'text-muted-foreground')}
        >
          <span className="truncate flex items-center gap-2">
            {/* A20: surface the dual-mode (Client/Company) hint even when
             *  no value is picked yet, so users know the trigger opens a
             *  two-tab picker - pre-fix the toggle was hidden until the
             *  popover was open, making the form read as client-only. */}
            {value ? (
              <span className="text-xs opacity-60">
                {value.type === 'client' ? 'Client:' : 'Company:'}
              </span>
            ) : (
              <span className="rounded-sm border border-border bg-muted px-1.5 py-px text-xs uppercase tracking-wide text-muted-foreground">
                Client / Company
              </span>
            )}
            <span className="truncate">{selectedLabel}</span>
          </span>
          <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" aria-hidden />
        </Button>
      </PopoverTrigger>
      <PopoverContent className="w-[320px] p-0" align="start">
        {/* Type toggle */}
        <div className="flex border-b">
          <button
            type="button"
            onClick={() => {
              setType('client');
              setSearch('');
            }}
            className={cn(
              'flex-1 px-3 py-2 text-xs',
              type === 'client' ? 'bg-accent font-medium' : 'hover:bg-accent/50',
            )}
          >
            Client
          </button>
          <button
            type="button"
            onClick={() => {
              setType('company');
              setSearch('');
            }}
            className={cn(
              'flex-1 px-3 py-2 text-xs',
              type === 'company' ? 'bg-accent font-medium' : 'hover:bg-accent/50',
            )}
          >
            Company
          </button>
        </div>

        <Command shouldFilter={false}>
          <CommandInput placeholder={`Search ${type}s…`} value={search} onValueChange={setSearch} />
          <CommandList>
            <CommandEmpty>No results.</CommandEmpty>
            <CommandGroup>
              {options.map((opt) => {
                const label =
                  type === 'client' ? (opt.fullName ?? '(unnamed)') : (opt.name ?? '(unnamed)');
                const isSelected = value?.id === opt.id && value?.type === type;
                return (
                  <CommandItem
                    key={opt.id}
                    value={opt.id}
                    onSelect={() => {
                      onChange({ type, id: opt.id });
                      setOpen(false);
                    }}
                  >
                    <Check
                      className={cn('mr-2 h-4 w-4', isSelected ? 'opacity-100' : 'opacity-0')}
                    />
                    {label}
                  </CommandItem>
                );
              })}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}
