'use client';

import { useRef, useState } from 'react';
import { Loader2, Pencil } from 'lucide-react';
import { toast } from 'sonner';

import { CountryCombobox } from '@/components/shared/country-combobox';
import { getCountryName, type CountryCode } from '@/lib/i18n/countries';
import { cn } from '@/lib/utils';

interface InlineCountryFieldProps {
  value: string | null | undefined;
  onSave: (next: CountryCode | null) => Promise<void>;
  emptyText?: string;
  disabled?: boolean;
  className?: string;
  'data-testid'?: string;
}

/**
 * Click-to-edit country picker. Renders the localized country name with a
 * regional-indicator flag glyph; opens a CountryCombobox on click.
 */
export function InlineCountryField({
  value,
  onSave,
  emptyText = '—',
  disabled,
  className,
  'data-testid': testId,
}: InlineCountryFieldProps) {
  const [editing, setEditing] = useState(false);
  const [saving, setSaving] = useState(false);
  // Set true when the user picks a value from the dropdown, so the
  // popover-close handler knows commit() will exit edit mode itself.
  const pickedRef = useRef(false);

  async function commit(next: CountryCode | null) {
    pickedRef.current = true;
    if (next === (value ?? null)) {
      setEditing(false);
      return;
    }
    setSaving(true);
    try {
      await onSave(next);
      setEditing(false);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to save');
    } finally {
      setSaving(false);
    }
  }

  if (editing) {
    return (
      <div className={cn('flex items-center gap-1', className)}>
        <CountryCombobox
          value={value}
          onChange={(iso) => void commit(iso)}
          data-testid={testId}
          defaultOpen
          onOpenChange={(open) => {
            // When the dropdown closes without a selection, leave edit mode
            // so the user isn't stuck staring at the trigger button. If a
            // pick happened, commit() handles the exit (and may need to keep
            // edit mode briefly to show the saving spinner).
            if (!open && !pickedRef.current) {
              setEditing(false);
            }
            // Reset for the next open cycle.
            if (open) pickedRef.current = false;
          }}
        />
        {saving && <Loader2 className="h-3 w-3 animate-spin text-muted-foreground" />}
      </div>
    );
  }

  const display = value
    ? `${flagEmoji(value)} ${getCountryName(value, typeof navigator !== 'undefined' ? navigator.language : 'en')}`
    : null;

  return (
    <button
      type="button"
      disabled={disabled}
      onClick={() => setEditing(true)}
      data-testid={testId}
      className={cn(
        'group inline-flex items-center gap-1.5 rounded px-1 -mx-1 py-0.5 text-left text-sm',
        'hover:bg-muted/60 focus-visible:bg-muted/60 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring',
        disabled && 'cursor-not-allowed opacity-60 hover:bg-transparent',
        className,
      )}
    >
      <span className={cn('flex-1', !display && 'text-muted-foreground')}>
        {display ?? emptyText}
      </span>
      {!disabled && (
        <Pencil className="h-3 w-3 opacity-0 transition-opacity group-hover:opacity-50" />
      )}
    </button>
  );
}

function flagEmoji(code: string): string {
  if (code.length !== 2) return '';
  const A = 0x1f1e6;
  const a = 'A'.charCodeAt(0);
  return String.fromCodePoint(A + code.charCodeAt(0) - a, A + code.charCodeAt(1) - a);
}
