'use client';

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

import { PhoneInput, type PhoneInputValue } from '@/components/shared/phone-input';
import { parsePhone } from '@/lib/i18n/phone';
import type { CountryCode } from '@/lib/i18n/countries';
import { cn } from '@/lib/utils';

interface InlinePhoneFieldProps {
  /** E.164 form ('+442079460958'), null when unset. */
  e164: string | null | undefined;
  /** ISO-3166-1 alpha-2 the number was parsed against. */
  country: string | null | undefined;
  /** Falls back to this country if `country` isn't set. */
  defaultCountry?: CountryCode;
  onSave: (next: { e164: string | null; country: CountryCode }) => Promise<void>;
  /**
   * Notifies the parent when the field enters/exits edit mode. Lets the row
   * dim or hide noise (tag chips, action buttons) while the user is focused
   * on the editor.
   */
  onEditingChange?: (editing: boolean) => void;
  emptyText?: string;
  disabled?: boolean;
  className?: string;
  'data-testid'?: string;
}

export function InlinePhoneField({
  e164,
  country,
  defaultCountry,
  onSave,
  onEditingChange,
  emptyText = '—',
  disabled,
  className,
  'data-testid': testId,
}: InlinePhoneFieldProps) {
  const [editing, setEditingRaw] = useState(false);
  const [draft, setDraft] = useState<PhoneInputValue | null>(() => {
    if (!e164 && !country) return null;
    return {
      e164: e164 ?? null,
      country: (country as CountryCode | null) ?? defaultCountry ?? 'US',
    };
  });
  const [saving, setSaving] = useState(false);

  function setEditing(next: boolean) {
    setEditingRaw(next);
    onEditingChange?.(next);
  }

  async function commit() {
    const next = draft ?? { e164: null, country: defaultCountry ?? 'US' };
    if (next.e164 === (e164 ?? null) && next.country === (country ?? 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 (
      // Two clean lines: country picker + number on top, action pair below.
      <div className={cn('flex w-full flex-col gap-2.5', className)}>
        <PhoneInput
          value={draft}
          onChange={(v) => setDraft(v)}
          defaultCountry={defaultCountry}
          data-testid={testId}
        />
        <div className="flex items-center justify-end gap-1.5">
          <button
            type="button"
            onClick={() => {
              setDraft(
                e164 || country
                  ? {
                      e164: e164 ?? null,
                      country: (country as CountryCode | null) ?? defaultCountry ?? 'US',
                    }
                  : null,
              );
              setEditing(false);
            }}
            disabled={saving}
            className={cn(
              'inline-flex h-8 items-center rounded-md px-3 text-xs font-medium',
              'text-muted-foreground transition-colors hover:bg-muted hover:text-foreground',
              'disabled:opacity-50',
            )}
          >
            Cancel
          </button>
          <button
            type="button"
            onClick={() => void commit()}
            disabled={saving}
            className={cn(
              'inline-flex h-8 min-w-[64px] items-center justify-center rounded-md px-3',
              'bg-primary text-xs font-semibold text-primary-foreground shadow-sm',
              'transition-colors hover:bg-primary/90 disabled:opacity-50',
            )}
          >
            {saving ? <Loader2 className="size-3.5 animate-spin" /> : 'Save'}
          </button>
        </div>
      </div>
    );
  }

  // Display: prefer the parsed national format (more readable than raw E.164).
  let display: string | null = null;
  if (e164) {
    const parsed = parsePhone(e164, (country as CountryCode | undefined) ?? defaultCountry);
    display = parsed.national ?? e164;
  }

  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>
  );
}
