// @design-system: domain/PickupAddressSelector

'use client';

import { useState, useEffect } from 'react';
import { AddressCard } from '@/components/ui/domain/AddressCard';
import { Button } from '@/components/ui/primitives/Button';
import { FormField } from '@/components/ui/primitives/FormField';
import { Input } from '@/components/ui/primitives/Input';
import {
  IsraeliAddressField,
  type IsraeliAddressValue,
} from '@/components/ui/domain/IsraeliAddressField/IsraeliAddressField';
import {
  Drawer,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerFooter,
} from '@/components/ui/overlays/Drawer';
import { useT } from '@/lib/i18n/react';
import { getCsrfToken } from '@/lib/csrf';
import { captureCaught } from '@/lib/observability';
import { formatIsraeliAddress } from '@/lib/address';

interface VendorAddress {
  id: string;
  label: string;
  fullAddress: string;
  city: string;
  isPublic: boolean;
}

export interface PickupAddressSelectorProps {
  value: string;
  onChange: (fullAddress: string) => void;
  /** Render-only gallery mode; keeps the demo deterministic and unauthenticated. */
  demo?: boolean;
  /** Called with address id + fullAddress when selection changes. Used by item-deal FK wiring. */
  onChangeWithId?: (id: string, fullAddress: string) => void;
}

export function PickupAddressSelector({
  value,
  onChange,
  onChangeWithId,
  demo = false,
}: PickupAddressSelectorProps) {
  const t = useT('vendor_add_deal');
  const [addresses, setAddresses] = useState<VendorAddress[]>([]);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [showNewForm, setShowNewForm] = useState(false);
  const [newAddress, setNewAddress] = useState<IsraeliAddressValue | null>(null);
  const [newLabel, setNewLabel] = useState('');
  const [saving, setSaving] = useState(false);
  const [saveError, setSaveError] = useState<string | null>(null);

  useEffect(() => {
    if (demo) return;
    fetch('/api/vendor/addresses', { credentials: 'same-origin' })
      .then((response) => {
        if (!response.ok) throw new Error(`vendor addresses request failed: ${response.status}`);
        return response.json() as Promise<{ ok: boolean; addresses?: VendorAddress[] }>;
      })
      .then((data) => {
        if (!data.ok) return;
        const list = data.addresses ?? [];
        setAddresses(list);
        if (!value) {
          const def = list.find((a) => a.isPublic) ?? list[0];
          if (def) onChange(def.fullAddress);
        }
      })
      .catch((err) => {
        captureCaught(err, { scope: 'PickupAddressSelector.fetch', severity: 'info' });
      });
  }, [demo, onChange, value]);

  const handleSelect = (addr: VendorAddress) => {
    onChange(addr.fullAddress);
    onChangeWithId?.(addr.id, addr.fullAddress);
    setDrawerOpen(false);
    setShowNewForm(false);
  };

  const handleSaveNew = async () => {
    if (!newAddress?.cityName || !newAddress?.streetName || !newAddress?.houseNumber) return;
    setSaving(true);
    setSaveError(null);
    const fullAddress = formatIsraeliAddress({
      streetName: newAddress.streetName,
      houseNumber: newAddress.houseNumber,
      apt: newAddress.apt,
      cityName: newAddress.cityName,
      aptLabel: t('pickup_address_apt_label'),
    });
    try {
      const res = await fetch('/api/vendor/addresses', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'x-csrf-token': getCsrfToken() },
        credentials: 'same-origin',
        body: JSON.stringify({
          label: newLabel || newAddress.cityName,
          cityCode: newAddress.cityCode,
          cityName: newAddress.cityName,
          streetCode: newAddress.streetCode,
          streetName: newAddress.streetName,
          houseNumber: newAddress.houseNumber,
          apt: newAddress.apt,
          lat: newAddress.lat,
          lng: newAddress.lng,
        }),
      });
      if (!res.ok) {
        setSaveError(t('pickup_address_error'));
        return;
      }
      const data = (await res.json()) as { ok: boolean; address?: VendorAddress; error?: string };
      if (!data.ok || !data.address) {
        setSaveError(t('pickup_address_error'));
        return;
      }
      setAddresses((prev) => [...prev, data.address!]);
      onChange(fullAddress);
      onChangeWithId?.(data.address!.id, fullAddress);
      setDrawerOpen(false);
      setShowNewForm(false);
      setNewAddress(null);
      setNewLabel('');
    } catch (err) {
      captureCaught(err, { scope: 'PickupAddressSelector.save', severity: 'warning' });
      setSaveError(t('pickup_address_error'));
    } finally {
      setSaving(false);
    }
  };

  const currentLabel = addresses.find((a) => a.fullAddress === value)?.label;

  return (
    <>
      {value ? (
        <AddressCard
          label={currentLabel ?? t('pickup_address_drawer_title')}
          address={value}
          onEdit={() => setDrawerOpen(true)}
        />
      ) : (
        <Button type="button" variant="secondary" size="sm" onClick={() => setDrawerOpen(true)}>
          {t('pickup_address_add')}
        </Button>
      )}

      <Drawer open={drawerOpen} onOpenChange={setDrawerOpen}>
        <DrawerContent>
          <DrawerHeader>
            <DrawerTitle>{t('pickup_address_drawer_title')}</DrawerTitle>
          </DrawerHeader>

          <div className="flex flex-col gap-3 px-4 py-3">
            {addresses.map((addr) => (
              <button
                key={addr.id}
                type="button"
                onClick={() => handleSelect(addr)}
                className={[
                  'w-full rounded-xl text-start',
                  'focus-visible:ring-2 focus-visible:ring-[var(--color-mode-vendor-500)] focus-visible:outline-none',
                  addr.fullAddress === value ? 'ring-mode-vendor-500 ring-2' : '',
                ].join(' ')}
              >
                <AddressCard label={addr.label} address={addr.fullAddress} />
              </button>
            ))}

            {!showNewForm && (
              <Button
                type="button"
                variant="secondary"
                size="sm"
                onClick={() => setShowNewForm(true)}
              >
                {t('pickup_address_add_new')}
              </Button>
            )}

            {showNewForm && (
              <div className="flex flex-col gap-3">
                <FormField label={t('pickup_address_label_placeholder')} htmlFor="new-addr-label">
                  <Input
                    id="new-addr-label"
                    type="text"
                    value={newLabel}
                    onChange={(e) => setNewLabel(e.target.value)}
                    placeholder={t('pickup_address_label_placeholder')}
                  />
                </FormField>
                <IsraeliAddressField value={newAddress} onChange={setNewAddress} />
                {saveError && (
                  <p role="alert" className="text-danger-600 text-sm">
                    {saveError}
                  </p>
                )}
              </div>
            )}
          </div>

          {showNewForm && (
            <DrawerFooter>
              <Button
                type="button"
                variant="primary"
                loading={saving}
                disabled={
                  saving ||
                  !newAddress?.cityName ||
                  !newAddress?.streetName ||
                  !newAddress?.houseNumber
                }
                onClick={() => void handleSaveNew()}
              >
                {saving ? t('pickup_address_saving') : t('pickup_address_save')}
              </Button>
            </DrawerFooter>
          )}
        </DrawerContent>
      </Drawer>
    </>
  );
}
