'use client';

import { useCallback, useEffect, useRef, useState, type SubmitEvent } from 'react';
import { ShippingAddressPicker } from '@/features/checkout/ShippingAddressPicker';
import { Icon } from '@/components/ui/icons/Icon';
import { Card } from '@/components/ui/layout/Card';
import { Button } from '@/components/ui/primitives/Button';
import { IconButton } from '@/components/ui/primitives/IconButton';
import { Input } from '@/components/ui/primitives/Input';
import { RadioGroup, RadioItem } from '@/components/ui/primitives/RadioGroup';
import {
  AlertDialog,
  AlertDialogContent,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogCancel,
  AlertDialogAction,
} from '@/components/ui/overlays/AlertDialog';
import { getCsrfToken } from '@/lib/csrf';
import { useT } from '@/lib/i18n/react';
import { normalizeIlPhone } from '@/lib/validation/shipping';
import { useCheckoutModalStore } from './checkoutModalStore';
import { useGuestAddresses, type GuestAddress } from './useGuestAddresses';
import { formatIsraeliAddress } from '@/lib/address';

export interface GuestShippingAddressPickerProps {
  isGuest: boolean;
  onAddressSelected: (addressId: string | null) => void;
}

type GuestAddressFormInput = Omit<GuestAddress, 'localId' | 'isDefault'>;

interface GuestAddressFormProps {
  initial?: GuestAddressFormInput;
  onSave: (input: GuestAddressFormInput) => void;
}

const EMPTY_GUEST_FORM: GuestAddressFormInput = {
  recipientName: '',
  recipientPhone: '',
  cityCode: '',
  cityName: '',
  streetCode: '',
  streetName: '',
  houseNumber: '',
  zip: '',
};

function GuestAddressForm({ initial = EMPTY_GUEST_FORM, onSave }: GuestAddressFormProps) {
  const t = useT('checkout_shipping');
  const [form, setForm] = useState(initial);
  const [error, setError] = useState<string | null>(null);

  function setField(field: keyof typeof EMPTY_GUEST_FORM) {
    return (e: React.ChangeEvent<HTMLInputElement>) => {
      setForm((prev) => ({ ...prev, [field]: e.target.value }));
      setError(null);
    };
  }

  function handleSubmit(e: SubmitEvent<HTMLFormElement>) {
    e.preventDefault();
    const recipientName = form.recipientName.trim();
    const recipientPhone = form.recipientPhone.trim();
    const cityName = form.cityName.trim();
    const streetName = form.streetName.trim();
    const houseNumber = form.houseNumber.trim();
    const zip = form.zip.trim();

    if (!recipientName || !recipientPhone || !cityName || !streetName || !houseNumber || !zip) {
      setError(t('error_save'));
      return;
    }

    onSave({
      recipientName,
      recipientPhone: normalizeIlPhone(recipientPhone),
      cityCode: form.cityCode,
      cityName,
      streetCode: form.streetCode,
      streetName,
      houseNumber,
      zip,
    });
    setForm(EMPTY_GUEST_FORM);
    setError(null);
  }

  return (
    <form onSubmit={handleSubmit} className="mt-4 flex flex-col gap-3">
      <Input
        value={form.recipientName}
        onChange={setField('recipientName')}
        placeholder={t('recipient_name')}
        required
        autoComplete="name"
      />
      <Input
        value={form.recipientPhone}
        onChange={setField('recipientPhone')}
        placeholder={t('recipient_phone')}
        required
        type="tel"
        autoComplete="tel"
        dir="ltr"
      />
      <Input
        value={form.cityName}
        onChange={setField('cityName')}
        placeholder={t('city')}
        required
        autoComplete="address-level2"
      />
      <Input
        value={form.streetName}
        onChange={setField('streetName')}
        placeholder={t('street')}
        required
        autoComplete="address-line1"
      />
      <Input
        value={form.houseNumber}
        onChange={setField('houseNumber')}
        placeholder={t('house_number')}
        required
        dir="ltr"
      />
      <Input
        value={form.zip}
        onChange={(e) => setForm((prev) => ({ ...prev, zip: e.target.value.replace(/\D/g, '') }))}
        placeholder={t('zip')}
        required
        dir="ltr"
        maxLength={7}
        minLength={7}
        inputMode="numeric"
        autoComplete="postal-code"
      />
      {error && <p className="text-danger text-sm">{error}</p>}
      <Button type="submit" variant="secondary" size="sm" className="self-start">
        {t('save_address')}
      </Button>
    </form>
  );
}

interface GuestAddressListProps {
  addresses: GuestAddress[];
  add: (input: GuestAddressFormInput) => GuestAddress;
  update: (localId: string, input: GuestAddressFormInput) => void;
  remove: (localId: string) => void;
  setDefault: (localId: string) => void;
  selectedLocalId: string | null;
  onSelectLocal: (localId: string) => void;
  onClearSelection: () => void;
}

function GuestAddressList({
  addresses,
  add,
  update,
  remove,
  setDefault,
  selectedLocalId,
  onSelectLocal,
  onClearSelection,
}: GuestAddressListProps) {
  const tModal = useT('checkout_modal');
  const tShipping = useT('checkout_shipping');
  const tCommon = useT('common');
  const [expandList, setExpandList] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [deleteConfirmId, setDeleteConfirmId] = useState<string | null>(null);
  const initializedRef = useRef(false);

  const fallbackId = addresses.find((a) => a.isDefault)?.localId ?? addresses[0]?.localId ?? null;
  const activeId = selectedLocalId ?? fallbackId;

  const selectAddress = useCallback(
    (localId: string, collapse = false) => {
      onSelectLocal(localId);
      if (collapse) {
        setExpandList(false);
      }
    },
    [onSelectLocal],
  );

  useEffect(() => {
    if (initializedRef.current || !fallbackId) return;
    initializedRef.current = true;
    onSelectLocal(fallbackId);
  }, [fallbackId, onSelectLocal]);

  const handleSave = useCallback(
    (input: GuestAddressFormInput) => {
      if (editingId) {
        update(editingId, input);
        setEditingId(null);
        setExpandList(false);
        return;
      }

      const isFirst = addresses.length === 0;
      const created = add(input);
      if (isFirst) {
        setDefault(created.localId);
      }
      selectAddress(created.localId);
      setExpandList(false);
    },
    [add, addresses.length, editingId, selectAddress, setDefault, update],
  );

  const handleRemoveConfirm = useCallback(() => {
    if (!deleteConfirmId) return;
    const removedId = deleteConfirmId;
    setDeleteConfirmId(null);
    if (editingId === removedId) {
      setEditingId(null);
    }
    remove(removedId);
    if (removedId === activeId) {
      onClearSelection();
    }
  }, [activeId, deleteConfirmId, editingId, onClearSelection, remove]);

  const editingInitial = editingId ? addresses.find((a) => a.localId === editingId) : undefined;

  const formInitial: GuestAddressFormInput = editingInitial
    ? {
        recipientName: editingInitial.recipientName,
        recipientPhone: editingInitial.recipientPhone,
        cityCode: editingInitial.cityCode,
        cityName: editingInitial.cityName,
        streetCode: editingInitial.streetCode,
        streetName: editingInitial.streetName,
        houseNumber: editingInitial.houseNumber,
        zip: editingInitial.zip,
      }
    : EMPTY_GUEST_FORM;

  const selectedAddress = addresses.find((a) => a.localId === activeId);
  const showExpanded = expandList || addresses.length === 0;

  return (
    <div>
      <h3 className="text-text-primary mb-3 text-sm font-semibold">
        {tModal('address_section_title')}
      </h3>

      {!showExpanded && selectedAddress && (
        <div className="flex flex-col gap-2">
          <Card padding="sm">
            <div className="flex items-start gap-3">
              <Icon name="MapPin" size="sm" className="text-text-secondary mt-0.5 shrink-0" />
              <div className="min-w-0 flex-1">
                <p className="text-text-primary text-sm">
                  {formatIsraeliAddress({
                    streetName: selectedAddress.streetName,
                    houseNumber: selectedAddress.houseNumber,
                    cityName: selectedAddress.cityName,
                  })}
                </p>
              </div>
            </div>
          </Card>
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className="self-start"
            onClick={() => setExpandList(true)}
          >
            {tModal('address_change')}
          </Button>
        </div>
      )}

      {showExpanded && (
        <>
          {addresses.length > 0 && (
            <RadioGroup
              value={activeId ?? ''}
              onValueChange={(localId) => selectAddress(localId, true)}
              aria-label={tShipping('address_group_aria')}
              className="mb-3"
            >
              {addresses.map((addr) => (
                <div key={addr.localId} className="flex items-center justify-between gap-2">
                  <RadioItem
                    value={addr.localId}
                    id={`guest-addr-${addr.localId}`}
                    className="min-w-0 flex-1"
                    label={
                      <span className="text-sm">
                        {addr.recipientName},{' '}
                        {formatIsraeliAddress({
                          streetName: addr.streetName,
                          houseNumber: addr.houseNumber,
                          cityName: addr.cityName,
                        })}
                      </span>
                    }
                  />
                  <div className="flex shrink-0 items-center gap-1">
                    <IconButton
                      variant="ghost"
                      size="sm"
                      type="button"
                      aria-label={tShipping('address_edit')}
                      className="text-text-secondary"
                      onClick={() => {
                        setEditingId(addr.localId);
                        setExpandList(true);
                      }}
                    >
                      <Icon name="Pencil" size="sm" aria-hidden />
                    </IconButton>
                    <IconButton
                      variant="ghost"
                      size="sm"
                      type="button"
                      aria-label={tShipping('address_remove')}
                      className="text-text-secondary"
                      onClick={() => setDeleteConfirmId(addr.localId)}
                    >
                      <Icon name="Trash2" size="sm" aria-hidden />
                    </IconButton>
                  </div>
                </div>
              ))}
            </RadioGroup>
          )}

          <GuestAddressForm key={editingId ?? 'new'} initial={formInitial} onSave={handleSave} />

          <AlertDialog
            open={deleteConfirmId !== null}
            onOpenChange={(open) => {
              if (!open) setDeleteConfirmId(null);
            }}
          >
            <AlertDialogContent>
              <AlertDialogHeader>
                <AlertDialogTitle>{tShipping('address_remove')}</AlertDialogTitle>
                <AlertDialogDescription>
                  {tShipping('address_remove_confirm')}
                </AlertDialogDescription>
              </AlertDialogHeader>
              <AlertDialogFooter>
                <AlertDialogCancel>{tCommon('cancel')}</AlertDialogCancel>
                <AlertDialogAction onClick={handleRemoveConfirm}>
                  {tShipping('address_remove')}
                </AlertDialogAction>
              </AlertDialogFooter>
            </AlertDialogContent>
          </AlertDialog>
        </>
      )}
    </div>
  );
}

export function GuestShippingAddressPicker({
  isGuest,
  onAddressSelected,
}: GuestShippingAddressPickerProps) {
  const payload = useCheckoutModalStore((s) => s.payload);
  const { addresses, add, update, remove, setDefault, syncToDb } = useGuestAddresses();
  const [selectedLocalId, setSelectedLocalId] = useState<string | null>(null);
  const syncedRef = useRef(false);
  const prevGuestRef = useRef(isGuest);

  const onSelectLocal = useCallback(
    (localId: string) => {
      setSelectedLocalId(localId);
      onAddressSelected(localId);
    },
    [onAddressSelected],
  );

  const onClearSelection = useCallback(() => {
    setSelectedLocalId(null);
    onAddressSelected('');
  }, [onAddressSelected]);

  useEffect(() => {
    const wasGuest = prevGuestRef.current;
    prevGuestRef.current = isGuest;
    if (wasGuest && !isGuest && !syncedRef.current && addresses.length > 0) {
      syncedRef.current = true;
      void (async () => {
        const mapping = await syncToDb(getCsrfToken());
        const remapped = selectedLocalId
          ? mapping.find((m) => m.localId === selectedLocalId)?.dbId
          : undefined;
        const next = remapped ?? mapping[0]?.dbId;
        onAddressSelected(next ?? '');
      })();
    }
  }, [isGuest, addresses.length, selectedLocalId, onAddressSelected, syncToDb]);

  if (!isGuest) {
    if (!payload) {
      return null;
    }

    return (
      <ShippingAddressPicker
        dealId={payload.dealId}
        dealSkuId={payload.skuId}
        csrfToken={getCsrfToken()}
        onSelect={onAddressSelected}
      />
    );
  }

  return (
    <GuestAddressList
      addresses={addresses}
      add={add}
      update={update}
      remove={remove}
      setDefault={setDefault}
      selectedLocalId={selectedLocalId}
      onSelectLocal={onSelectLocal}
      onClearSelection={onClearSelection}
    />
  );
}
