'use client';

import { useState, useCallback } from 'react';
import { captureCaught } from '@/lib/observability';

const STORAGE_KEY = 'md:guest_addresses';

export interface GuestAddress {
  localId: string;
  recipientName: string;
  recipientPhone: string;
  cityCode: string;
  cityName: string;
  streetCode: string;
  streetName: string;
  houseNumber: string;
  apt?: string;
  entrance?: string;
  floor?: string;
  zip: string;
  notes?: string;
  isDefault: boolean;
}

function readStorage(): GuestAddress[] {
  if (typeof window === 'undefined') return [];
  try {
    return JSON.parse(localStorage.getItem(STORAGE_KEY) ?? '[]') as GuestAddress[];
  } catch (err) {
    captureCaught(err, {
      scope: 'checkout-modal.useGuestAddresses.readStorage',
      severity: 'warning',
    });
    return [];
  }
}

function writeStorage(addresses: GuestAddress[]) {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(addresses));
}

export function useGuestAddresses() {
  const [addresses, setAddresses] = useState<GuestAddress[]>(readStorage);

  const add = useCallback((input: Omit<GuestAddress, 'localId' | 'isDefault'>): GuestAddress => {
    const next: GuestAddress = { ...input, localId: crypto.randomUUID(), isDefault: false };
    setAddresses((prev) => {
      const updated = [...prev, next];
      writeStorage(updated);
      return updated;
    });
    return next;
  }, []);

  const setDefault = useCallback((localId: string) => {
    setAddresses((prev) => {
      const updated = prev.map((a) => ({ ...a, isDefault: a.localId === localId }));
      writeStorage(updated);
      return updated;
    });
  }, []);

  const update = useCallback(
    (localId: string, input: Omit<GuestAddress, 'localId' | 'isDefault'>) => {
      setAddresses((prev) => {
        const updated = prev.map((a) =>
          a.localId === localId ? { ...a, ...input, localId, isDefault: a.isDefault } : a,
        );
        writeStorage(updated);
        return updated;
      });
    },
    [],
  );

  const remove = useCallback((localId: string) => {
    setAddresses((prev) => {
      const updated = prev.filter((a) => a.localId !== localId);
      writeStorage(updated);
      return updated;
    });
  }, []);

  const syncToDb = useCallback(
    async (csrfToken: string): Promise<Array<{ localId: string; dbId: string }>> => {
      const current = readStorage();
      const mapping: Array<{ localId: string; dbId: string }> = [];
      const failed: GuestAddress[] = [];
      for (const a of current) {
        try {
          const res = await fetch('/api/shipping-addresses', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'x-csrf-token': csrfToken },
            body: JSON.stringify({
              recipientName: a.recipientName,
              recipientPhone: a.recipientPhone,
              cityCode: a.cityCode,
              cityName: a.cityName,
              streetCode: a.streetCode,
              streetName: a.streetName,
              houseNumber: a.houseNumber,
              apt: a.apt,
              entrance: a.entrance,
              floor: a.floor,
              zip: a.zip,
              notes: a.notes,
              isDefault: a.isDefault,
            }),
          });
          const json = (await res.json()) as { ok: boolean; address?: { id: string } };
          if (res.ok && json.ok && json.address?.id)
            mapping.push({ localId: a.localId, dbId: json.address.id });
          else failed.push(a);
        } catch (err) {
          captureCaught(err, {
            scope: 'checkout-modal.useGuestAddresses.syncToDb',
            severity: 'warning',
          });
          failed.push(a);
        }
      }
      writeStorage(failed);
      setAddresses(failed);
      return mapping;
    },
    [],
  );

  return { addresses, add, update, remove, setDefault, syncToDb };
}
