'use client';
import { useState } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { useSnackbar } from 'notistack';
import { Box, Skeleton, Stack, Typography } from '@mui/material';
import { AppButton, ConfirmDialog, EmptyState, ErrorState, FormDialogShell } from '@/components';
import { AddressCard, AddressForm } from '@/components/geography';
import {
  useAddresses,
  useCreateAddress,
  useUpdateAddress,
  useDeleteAddress,
  useSetPrimaryAddress,
} from '@/services/addresses';
import type { CreateAddressInput, CustomerAddress } from '@/services/addresses/types';

/**
 * The customer address book — a cached, invalidate-on-mutation list of the customer's saved
 * addresses with add/edit (the cascading dropdowns + map pin in a full-screen-on-mobile dialog),
 * soft-delete (confirm), and set-primary (exactly one badge). Loading skeleton, error (with
 * retry), and empty states are all handled. The chosen address later feeds the f7 booking request.
 */
export default function AddressesPage() {
  const t = useTranslations('address');
  const tc = useTranslations('common');
  const locale = useLocale();
  const { enqueueSnackbar } = useSnackbar();

  const { data, isLoading, isError, refetch } = useAddresses();
  const createAddress = useCreateAddress();
  const updateAddress = useUpdateAddress();
  const deleteAddress = useDeleteAddress();
  const setPrimary = useSetPrimaryAddress();

  const [formOpen, setFormOpen] = useState(false);
  const [formDirty, setFormDirty] = useState(false);
  const [editing, setEditing] = useState<CustomerAddress | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<CustomerAddress | null>(null);

  const openAdd = () => {
    setEditing(null);
    setFormOpen(true);
  };
  const openEdit = (address: CustomerAddress) => {
    setEditing(address);
    setFormOpen(true);
  };
  const closeForm = () => setFormOpen(false);

  // Address district is optional granularity: show "city · district" when set, else just the city.
  const regionLabel = (address: CustomerAddress) => {
    const city = locale === 'en' ? address.cityNameEn : address.cityNameFa;
    if (address.districtId == null) return city;
    const district = locale === 'en' ? address.districtNameEn : address.districtNameFa;
    return `${city} · ${district}`;
  };

  const handleSubmit = (input: CreateAddressInput) => {
    const onSuccess = () => {
      closeForm();
      enqueueSnackbar(t('saved'), { variant: 'success' });
    };
    const onError = () => enqueueSnackbar(t('save_error'), { variant: 'error' });
    if (editing) {
      updateAddress.mutate({ id: editing.id, input }, { onSuccess, onError });
    } else {
      createAddress.mutate(input, { onSuccess, onError });
    }
  };

  const confirmDelete = () => {
    if (!deleteTarget) return;
    const id = deleteTarget.id;
    setDeleteTarget(null);
    deleteAddress.mutate(id, {
      onSuccess: () => enqueueSnackbar(t('deleted'), { variant: 'success' }),
      onError: () => enqueueSnackbar(t('unavailable'), { variant: 'error' }),
    });
  };

  const addresses = data?.items ?? [];
  const isEmpty = !isLoading && !isError && addresses.length === 0;

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
      <Stack direction="row" sx={{ alignItems: 'flex-start', justifyContent: 'space-between', gap: 2 }}>
        <Box>
          <Typography variant="h5" component="h1">
            {t('title')}
          </Typography>
          <Typography variant="body2" sx={{ color: 'text.secondary' }}>
            {t('subtitle')}
          </Typography>
        </Box>
        {!isEmpty && !isError ? (
          <AppButton color="primary" variant="contained" startIcon="add" onClick={openAdd} sx={{ flexShrink: 0 }}>
            {t('add')}
          </AppButton>
        ) : null}
      </Stack>

      {isLoading ? (
        <Stack sx={{ gap: 1.5 }}>
          {[0, 1].map((key) => (
            <Skeleton key={key} variant="rounded" height={104} />
          ))}
        </Stack>
      ) : isError ? (
        <ErrorState message={t('load_error')} retryLabel={tc('retry')} onRetry={() => refetch()} />
      ) : isEmpty ? (
        <EmptyState
          icon="location"
          title={t('empty_title')}
          body={t('empty_body')}
          action={
            <AppButton color="primary" variant="contained" startIcon="add" onClick={openAdd} sx={{ mt: 1 }}>
              {t('add')}
            </AppButton>
          }
        />
      ) : (
        <Stack sx={{ gap: 1.5 }}>
          {addresses.map((address) => (
            <AddressCard
              key={address.id}
              title={address.title}
              regionLabel={regionLabel(address)}
              addressLine={address.addressLine}
              isPrimary={address.isPrimary}
              primaryLabel={t('primary')}
              hasPin={address.latitude != null && address.longitude != null}
              pinSetLabel={t('pin_set')}
              pinMissingLabel={t('pin_missing')}
              onEdit={() => openEdit(address)}
              onDelete={() => setDeleteTarget(address)}
              onSetPrimary={() =>
                setPrimary.mutate(address.id, {
                  onSuccess: () => enqueueSnackbar(t('primary_set'), { variant: 'success' }),
                  onError: () => enqueueSnackbar(t('unavailable'), { variant: 'error' }),
                })
              }
              settingPrimary={setPrimary.isPending}
              editLabel={t('edit')}
              deleteLabel={t('delete')}
              setPrimaryLabel={t('set_primary')}
            />
          ))}
        </Stack>
      )}

      <FormDialogShell
        open={formOpen}
        title={editing ? t('edit_title') : t('add_title')}
        dirty={formDirty}
        onClose={closeForm}
        closeLabel={tc('close')}
        discardTitle={tc('discard_title')}
        discardBody={tc('discard_body')}
        discardConfirmLabel={tc('discard_confirm')}
        discardCancelLabel={tc('cancel')}
      >
        <AddressForm
          key={editing?.id ?? 'new'}
          initial={
            editing
              ? {
                  title: editing.title,
                  provinceId: editing.provinceId,
                  cityId: editing.cityId,
                  districtId: editing.districtId,
                  addressLine: editing.addressLine,
                  latitude: editing.latitude,
                  longitude: editing.longitude,
                  isPrimary: editing.isPrimary,
                }
              : undefined
          }
          submitting={createAddress.isPending || updateAddress.isPending}
          onSubmit={handleSubmit}
          onCancel={closeForm}
          onDirtyChange={setFormDirty}
        />
      </FormDialogShell>

      <ConfirmDialog
        open={Boolean(deleteTarget)}
        title={t('delete_title')}
        body={t('delete_body')}
        confirmLabel={t('delete_confirm')}
        cancelLabel={tc('cancel')}
        confirmColor="error"
        onClose={() => setDeleteTarget(null)}
        onConfirm={confirmDelete}
      />
    </Box>
  );
}
