/**
 * Profile - user profile screen (FDS §4.11).
 *
 * Sections:
 * - Avatar (avatarUrl → img, else initials; tap opens upload)
 * - Display name (editable inline)
 * - Phone (read-only, masked)
 * - Purchase count badge
 * - Addresses list (max 3) with AddressCard
 * - Email (editable, triggers re-verification flow)
 * - Payment methods with PaymentMethodChip + isDefault indicator
 * - Freeze account + delete account actions (AlertDialog / Drawer)
 */

'use client';

import { useState, useEffect, useRef } from 'react';
import { useT } from '@/lib/i18n/react';
import { captureCaught } from '@/lib/observability';
import { AppShell } from '@/components/ui/layout/AppShell';
import { BottomNav, useCustomerNavItems } from '@/components/ui/layout/BottomNav';
import { SiteNav } from '@/components/ui/layout/SiteNav';
import { Container } from '@/components/ui/layout/Container';
import { Breadcrumb } from '@/components/ui/layout/Breadcrumb';
import { GlassCard } from '@/components/ui/layout/GlassCard';
import { Section } from '@/components/ui/layout/Section';
import { Button } from '@/components/ui/primitives/Button';
import { Input } from '@/components/ui/primitives/Input';
import { FormField } from '@/components/ui/primitives/FormField';
import { Switch } from '@/components/ui/primitives/Switch';
import { Label } from '@/components/ui/primitives/Label';
import { Badge } from '@/components/ui/primitives/Badge';
import { Image } from '@/components/ui/primitives/Image';
import { AddressCard } from '@/components/ui/domain/AddressCard';
import { PaymentMethodChip } from '@/components/ui/domain/PaymentMethodChip';
import {
  AlertDialog,
  AlertDialogTrigger,
  AlertDialogContent,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogAction,
  AlertDialogCancel,
} from '@/components/ui/overlays/AlertDialog';
import {
  Drawer,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerDescription,
  DrawerFooter,
  DrawerClose,
} from '@/components/ui/overlays/Drawer';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import { Spinner } from '@/components/ui/feedback/Spinner';
import { ProfileSkeleton, SkeletonGuard } from '@/components/ui/feedback/Skeleton';
import { ErrorState } from '@/components/ui/feedback/ErrorState';
import { Icon } from '@/components/ui/icons/Icon';
import { IconButton } from '@/components/ui/primitives/IconButton';
import { GlobalCartDrawer } from '@/components/ui/domain/cart/GlobalCartDrawer';
import { AvatarUploadButton } from '@/components/ui/domain/AvatarUploadButton';
import { LogoutButton } from '@/components/ui/primitives/LogoutButton';
import {
  useProfile,
  useUpdateDisplayName,
  useUpdatePrefs,
  useUpdateAddress,
  useDeleteAddress,
  useRemovePaymentMethod,
  useFreezeAccount,
  useRequestAccountDeletion,
  useAddAddress,
  useAddPaymentMethod,
  useUpdateAvatar,
  useSelectGravatar,
  useRemoveAvatar,
  useGravatarCheck,
  type UserPaymentMethod,
} from './useProfile';
import { PaymentForm } from '@/features/checkout/PaymentForm';
import type { ClientConfig } from '@/server/payments/provider';
import { useQueryClient } from '@tanstack/react-query';
import { qk } from '@/lib/query/keys';
import { fetchWithRefresh } from '@/lib/api/refresh-on-401';
import {
  IsraeliAddressField,
  type IsraeliAddressValue,
} from '@/components/ui/domain/IsraeliAddressField/IsraeliAddressField';
import { initialsOf } from '@/lib/string';
import { formatPhoneDisplay } from '@/lib/phone.js';

// ─── Helpers ──────────────────────────────────────────────────────────────────

function buildFullAddress(v: IsraeliAddressValue): string {
  const street = [v.streetName, v.houseNumber, v.apt ? `/${v.apt}` : ''].filter(Boolean).join(' ');
  return [street, v.cityName].filter(Boolean).join(', ');
}

// ─── Profile ──────────────────────────────────────────────────────────────────

/**
 * ProfileInner - main user profile screen (needs QueryClientProvider above).
 */
function ProfileInner({
  isAdmin = false,
  isVendor = false,
  userName,
}: {
  isAdmin?: boolean;
  isVendor?: boolean;
  userName?: string;
}) {
  const t = useT('profile');
  const tPm = useT('domain_payment_method');
  const tCommon = useT('common');
  const tNav = useT('nav');
  const tError = useT('error');
  const { data, isLoading, isError, refetch } = useProfile();
  const { mutate: updateName, isPending: savingName } = useUpdateDisplayName();
  const { mutate: removeMethod, isPending: removingMethod } = useRemovePaymentMethod();
  const { mutate: freeze } = useFreezeAccount();
  const { mutate: requestDeletion } = useRequestAccountDeletion();
  const { mutate: addAddress, isPending: addingAddress } = useAddAddress();
  const { mutate: updateAddressMut, isPending: savingAddress } = useUpdateAddress();
  const { mutate: deleteAddressMut } = useDeleteAddress();
  const { mutate: addPaymentMethod, isPending: savingCard } = useAddPaymentMethod();
  const { mutate: updatePrefs } = useUpdatePrefs();
  const { mutate: updateAvatar } = useUpdateAvatar();
  const { mutate: selectGravatar } = useSelectGravatar();
  const { mutate: removeAvatar } = useRemoveAvatar();
  const gravatarCheck = useGravatarCheck(true); // avatar section always visible on profile page
  const queryClient = useQueryClient();

  const [editingName, setEditingName] = useState(false);
  const [nameValue, setNameValue] = useState('');
  const [deleteDrawerOpen, setDeleteDrawerOpen] = useState(false);
  const [addAddressOpen, setAddAddressOpen] = useState(false);
  const [pendingAddress, setPendingAddress] = useState<IsraeliAddressValue | null>(null);
  const [pendingLabel, setPendingLabel] = useState('');
  const [editAddressId, setEditAddressId] = useState<string | null>(null);
  const [editAddressLabel, setEditAddressLabel] = useState('');
  const [editAddressFull, setEditAddressFull] = useState('');
  const [addPaymentOpen, setAddPaymentOpen] = useState(false);
  const [addPaymentError, setAddPaymentError] = useState<string | null>(null);
  const [removeTarget, setRemoveTarget] = useState<UserPaymentMethod | null>(null);
  const [removeMethodError, setRemoveMethodError] = useState<string | null>(null);
  const [paymentConfig, setPaymentConfig] = useState<ClientConfig | null>(null);
  const hasScrolledToTab = useRef(false);

  useEffect(() => {
    if (!addPaymentOpen || paymentConfig) return;
    void fetchWithRefresh('/api/payments/client-config')
      .then((r) => r.json())
      .then((raw) => {
        const d = raw as { ok: boolean } & Partial<ClientConfig>;
        if (d.ok && (d.provider === 'stripe' || d.provider === 'mock')) {
          const { ok: _ok, ...config } = d;
          setPaymentConfig(config as ClientConfig);
        } else {
          setPaymentConfig(null);
          setAddPaymentError(t('load_payment_error'));
        }
      })
      .catch((err: unknown) => {
        captureCaught(err, { scope: 'payments/client-config' });
        setPaymentConfig(null);
        setAddPaymentError(t('load_payment_error'));
      });
  }, [addPaymentOpen, paymentConfig, t]);

  useEffect(() => {
    if (isLoading || !data) return;
    if (hasScrolledToTab.current) return;
    const tab = new URLSearchParams(window.location.search).get('tab');
    if (tab === 'payment-methods' || tab === 'addresses') {
      const el = [...document.querySelectorAll(`#${CSS.escape(tab)}`)].find(
        (e) => e instanceof HTMLElement && e.offsetParent !== null,
      );
      if (el) {
        el.scrollIntoView({ behavior: 'smooth', block: 'start' });
        hasScrolledToTab.current = true;
      }
    }
  }, [isLoading, data]);

  const navItems = useCustomerNavItems('/profile');

  const desktopTopBar = (
    <SiteNav
      variant="desktop"
      currentPath="/profile"
      isGuest={false}
      isAdmin={isAdmin}
      isVendor={isVendor}
      userName={userName}
    />
  );

  if (isLoading) {
    return (
      <AppShell
        mode="customer"
        desktopTopBar={desktopTopBar}
        topBar={
          <SiteNav
            variant="mobile"
            title={t('display_name')}
            currentPath="/profile"
            isGuest={false}
            isAdmin={isAdmin}
            isVendor={isVendor}
          />
        }
        bottomNav={<BottomNav mode="customer" items={navItems} />}
        pageOverlays={<GlobalCartDrawer />}
      >
        <main id="main" className="px-4 py-6">
          <div aria-busy="true" role="status">
            <span className="sr-only">{tCommon('loading')}</span>
            <SkeletonGuard delay={0}>
              <ProfileSkeleton />
            </SkeletonGuard>
          </div>
        </main>
      </AppShell>
    );
  }

  if (isError || !data) {
    return (
      <AppShell
        mode="customer"
        desktopTopBar={desktopTopBar}
        topBar={
          <SiteNav
            variant="mobile"
            title={t('display_name')}
            currentPath="/profile"
            isGuest={false}
            isAdmin={isAdmin}
            isVendor={isVendor}
          />
        }
        bottomNav={<BottomNav mode="customer" items={navItems} />}
        pageOverlays={<GlobalCartDrawer />}
      >
        <main id="main" className="px-4 py-8">
          <ErrorState
            title={tError('title')}
            description={tError('description')}
            action={
              <Button variant="primary" size="sm" onClick={() => void refetch()}>
                {tCommon('retry')}
              </Button>
            }
          />
        </main>
      </AppShell>
    );
  }

  const profile = data;

  function handleSaveName() {
    if (!nameValue.trim()) return;
    updateName(nameValue.trim());
    setEditingName(false);
  }

  function handleToggleTwoFa(checked: boolean) {
    updatePrefs({ twoFa: checked });
  }

  function handleAddressEdit(addr: { id: string; label: string; address: string }) {
    // F8: open edit drawer only; PATCH fires when user saves from drawer.
    setEditAddressId(addr.id);
    setEditAddressLabel(addr.label);
    setEditAddressFull(addr.address);
  }

  function handleAddressDelete(addressId: string) {
    deleteAddressMut(addressId);
  }

  function handleAddressSaveEdit() {
    if (!editAddressId) return;
    updateAddressMut(
      {
        id: editAddressId,
        label: editAddressLabel.trim() || undefined,
        fullAddress: editAddressFull.trim() || undefined,
      },
      {
        onSuccess: () => {
          setEditAddressId(null);
          setEditAddressLabel('');
          setEditAddressFull('');
        },
      },
    );
  }

  /** Reusable sections JSX - rendered in both mobile flat layout and desktop right column. */
  const profileSections = (
    <>
      {/* ── Quick links ──────────────────────────────────────────────── */}
      <Section px="4" py="3" className="flex flex-col gap-1">
        <a
          href="/favorites"
          className="text-text-primary hover:bg-surface-hover flex h-10 items-center gap-2 rounded-md px-2 text-sm font-medium no-underline transition-colors"
        >
          <Icon name="Heart" size="sm" aria-hidden />
          {tNav('favorites')}
        </a>
      </Section>

      {/* ── Addresses ────────────────────────────────────────────────── */}
      <Section
        id="addresses"
        heading={t('addresses_title')}
        px="4"
        py="4"
        uppercase
        className="flex scroll-mt-20 flex-col gap-3"
      >
        {profile.addresses.map((addr) => (
          <AddressCard
            key={addr.id}
            label={addr.label}
            address={addr.address}
            onEdit={() => handleAddressEdit(addr)}
            onDelete={() => handleAddressDelete(addr.id)}
          />
        ))}

        {profile.addresses.length < 3 && (
          <Button
            variant="ghost"
            size="sm"
            iconStart={<Icon name="MapPin" size="sm" />}
            onClick={() => setAddAddressOpen(true)}
          >
            {t('add_address')}
          </Button>
        )}
      </Section>

      {/* ── Email + 2FA ───────────────────────────────────────────────── */}
      <Section heading={t('email_title')} px="4" py="4" uppercase className="flex flex-col gap-3">
        <div className="flex items-end gap-2">
          <FormField label={t('email_title')} htmlFor="profile-email" className="flex-1">
            <Input
              id="profile-email"
              type="email"
              value={profile.email ?? ''}
              readOnly
              className="bg-surface-inset"
            />
          </FormField>
        </div>

        <div className="flex items-center justify-between gap-3 py-1">
          <Label htmlFor="profile-2fa" className="text-text-primary text-sm">
            {t('email_2fa')}
          </Label>
          <Switch
            id="profile-2fa"
            checked={profile.prefs?.twoFa ?? profile.twoFaEnabled}
            onCheckedChange={handleToggleTwoFa}
          />
        </div>
      </Section>

      {/* ── Payment Methods ───────────────────────────────────────────── */}
      <Section
        id="payment-methods"
        heading={t('payment_methods_title')}
        px="4"
        py="4"
        uppercase
        className="flex scroll-mt-20 flex-col gap-3"
      >
        {removeMethodError && <InlineNotice tone="danger" description={removeMethodError} />}

        {profile.paymentMethods.length === 0 ? (
          <p className="text-text-muted text-sm">{t('payment_methods_empty')}</p>
        ) : (
          profile.paymentMethods.map((pm) => (
            <div key={pm.id} className="flex flex-col gap-1">
              <PaymentMethodChip
                brandName={pm.brandName}
                last4={pm.last4}
                brandLogoUrl={pm.brandLogoUrl}
                onRemove={() => {
                  setRemoveMethodError(null);
                  setRemoveTarget(pm);
                }}
              />
              {pm.isDefault && (
                <Badge tone="neutral" size="sm" className="ms-1 self-start">
                  {t('payment_default')}
                </Badge>
              )}
            </div>
          ))
        )}

        <Button
          variant="ghost"
          size="sm"
          iconStart={<Icon name="CreditCard" size="sm" />}
          onClick={() => setAddPaymentOpen(true)}
        >
          {t('add_payment')}
        </Button>
      </Section>

      {/* ── Account Actions ───────────────────────────────────────────── */}
      <Section
        heading={t('account_actions_title')}
        px="4"
        py="4"
        uppercase
        className="flex flex-col gap-3"
      >
        {/* Logout */}
        <LogoutButton className="w-full justify-start" />

        {/* Freeze account */}
        <AlertDialog>
          <AlertDialogTrigger asChild>
            <Button
              variant="ghost"
              size="md"
              className="text-warning-600 w-full justify-start"
              iconStart={<Icon name="Lock" size="sm" />}
            >
              <span className="ms-2">{t('freeze_account')}</span>
            </Button>
          </AlertDialogTrigger>
          <AlertDialogContent>
            <AlertDialogHeader>
              <AlertDialogTitle>{t('freeze_account')}</AlertDialogTitle>
              <AlertDialogDescription>{t('freeze_confirm')}</AlertDialogDescription>
            </AlertDialogHeader>
            <AlertDialogFooter>
              <AlertDialogAction onClick={() => freeze()}>{t('freeze_account')}</AlertDialogAction>
              <AlertDialogCancel>{tCommon('cancel')}</AlertDialogCancel>
            </AlertDialogFooter>
          </AlertDialogContent>
        </AlertDialog>

        {/* Request account deletion — drawer hoisted outside profileSections to avoid double-render */}
        <Button
          variant="ghost"
          size="md"
          className="text-danger-600 w-full justify-start"
          iconStart={<Icon name="Trash2" size="sm" />}
          onClick={() => setDeleteDrawerOpen(true)}
        >
          <span className="ms-2">{t('delete_account')}</span>
        </Button>
      </Section>
    </>
  );

  const avatarRes = profile.avatar;
  const avatarSrc = avatarRes?.kind === 'image' ? avatarRes.url : undefined;
  const avatarExternal = avatarRes?.kind === 'image' && avatarRes.pipeline === 'external';
  const avatarPending = profile.avatarStatus === 'PENDING';
  const avatarRejected = profile.avatarStatus === 'REJECTED';
  const rejectReasonKey = (():
    | 'avatar_rejected_reason_nudity'
    | 'avatar_rejected_reason_violence'
    | 'avatar_rejected_reason_other' => {
    switch (profile.avatarRejectReasonCode) {
      case 'nudity':
        return 'avatar_rejected_reason_nudity';
      case 'violence':
        return 'avatar_rejected_reason_violence';
      default:
        return 'avatar_rejected_reason_other';
    }
  })();

  /** Avatar + identity panel - rendered in the mobile header section or the desktop sidebar. */
  const avatarPanel = (
    <div className="flex flex-col gap-4">
      {/* Avatar - tap to upload */}
      <div className="flex items-center gap-4">
        <div className="relative">
          <AvatarUploadButton
            src={avatarSrc}
            external={avatarExternal}
            alt={profile.displayName || t('display_name')}
            onChange={(file) => updateAvatar(file)}
            size={64}
          />
          {avatarPending && (
            <span className="bg-surface-overlay text-text-inverse absolute start-0 -bottom-1 rounded-full px-2 py-0.5 text-xs">
              {t('avatar_under_review')}
            </span>
          )}
        </div>

        {/* Display name */}
        <div className="flex flex-1 flex-col gap-1">
          {editingName ? (
            <div className="flex items-center gap-1">
              <Input
                type="text"
                value={nameValue}
                onChange={(e) => setNameValue(e.target.value)}
                aria-label={t('display_name')}
                className="min-w-0 flex-1"
              />
              <IconButton
                variant="default"
                size="sm"
                shape="square"
                aria-label={tCommon('save')}
                disabled={savingName}
                onClick={handleSaveName}
              >
                <Icon name="Check" size="sm" />
              </IconButton>
              <IconButton
                variant="ghost"
                size="sm"
                shape="square"
                aria-label={tCommon('cancel')}
                onClick={() => setEditingName(false)}
              >
                <Icon name="X" size="sm" />
              </IconButton>
            </div>
          ) : (
            <div className="flex items-center gap-2">
              <p
                data-user-displayname
                data-user-content
                className="text-text-primary flex-1 text-base font-semibold"
              >
                {profile.displayName || t('display_name')}
              </p>
              <Button
                variant="ghost"
                size="sm"
                iconStart={<Icon name="Pencil" size="sm" />}
                onClick={() => {
                  setNameValue(profile.displayName);
                  setEditingName(true);
                }}
                aria-label={tCommon('edit')}
              />
            </div>
          )}

          {/* Purchase count badge */}
          <Badge tone="neutral" size="sm">
            {profile.purchaseCount} {t('purchases_label')}
          </Badge>
        </div>
      </div>
      {/* Avatar actions: gravatar (conditional) + remove */}
      <div className="flex flex-wrap gap-3">
        {gravatarCheck.data?.available && (
          <Button variant="secondary" size="sm" onClick={() => selectGravatar()}>
            {t('avatar_use_gravatar')}
          </Button>
        )}
        {avatarRes && avatarRes.kind !== 'icon' && (
          <Button variant="ghost" size="sm" onClick={() => removeAvatar()}>
            {t('avatar_use_default')}
          </Button>
        )}
      </div>
      {avatarRejected && (
        <p className="text-text-danger text-sm">
          {t('avatar_rejected')}: {t(rejectReasonKey)} — {t('avatar_reupload')}
        </p>
      )}

      {/* Phone (read-only, masked) */}
      <div>
        <p className="text-text-secondary text-xs">{t('phone_label')}</p>
        <p data-user-content className="text-text-primary text-sm font-medium" dir="ltr">
          {formatPhoneDisplay(profile.phone)}
        </p>
        <p className="text-text-muted text-xs">{t('phone_immutable')}</p>
      </div>
    </div>
  );

  return (
    <AppShell
      mode="customer"
      desktopTopBar={desktopTopBar}
      topBar={
        <SiteNav
          variant="mobile"
          title={t('display_name')}
          currentPath="/profile"
          isGuest={false}
          isAdmin={isAdmin}
          isVendor={isVendor}
        />
      }
      bottomNav={<BottomNav mode="customer" items={navItems} />}
      pageOverlays={<GlobalCartDrawer />}
    >
      {/* Desktop hero banner */}
      <div className="hidden lg:block">
        <div className="bg-surface-raised rounded-xl shadow-md">
          <Container maxWidth="4xl" px="8" className="py-8">
            <div className="flex items-end gap-6">
              <div
                className="border-border-default size-[5.5rem] shrink-0 overflow-hidden rounded-full border-2 shadow-md"
                aria-hidden="true"
              >
                {avatarSrc ? (
                  avatarExternal ? (
                    <img
                      src={avatarSrc}
                      alt=""
                      width={88}
                      height={88}
                      loading="lazy"
                      className="h-full w-full object-cover"
                    />
                  ) : (
                    <Image
                      src={avatarSrc}
                      alt=""
                      decorative
                      width={88}
                      height={88}
                      className="h-full w-full object-cover"
                    />
                  )
                ) : (
                  <div className="bg-surface-inset flex h-full w-full items-center justify-center">
                    <span
                      data-user-displayname
                      data-user-content
                      className="text-text-secondary text-3xl font-[var(--font-weight-extrabold)] select-none"
                    >
                      {initialsOf(profile.displayName || t('display_name'))}
                    </span>
                  </div>
                )}
              </div>

              <div className="flex flex-col gap-2">
                <h1
                  data-user-displayname
                  data-user-content
                  className="text-text-primary text-[length:var(--font-size-display)] leading-tight font-[var(--font-weight-extrabold)]"
                >
                  {profile.displayName || t('display_name')}
                </h1>
                <div className="flex flex-wrap items-center gap-3">
                  <Badge tone="solid-dark" size="sm">
                    {profile.purchaseCount} {t('purchases_label')}
                  </Badge>
                  {profile.phone && (
                    <span className="text-text-secondary text-sm" dir="ltr">
                      {formatPhoneDisplay(profile.phone)}
                    </span>
                  )}
                </div>
              </div>
            </div>
          </Container>
        </div>
      </div>

      <main id="main">
        <Breadcrumb items={[{ label: tNav('home'), href: '/' }, { label: tNav('profile') }]} />
        {/* Mobile: flat sections. Desktop: avatar sidebar + sections column.
            profileSections renders once — a second copy duplicates its section ids. */}
        <div className="lg:mx-auto lg:flex lg:max-w-4xl lg:items-start lg:gap-10 lg:px-8 lg:py-8">
          <div className="sticky-below-topnav sticky hidden w-80 shrink-0 lg:block">
            <GlassCard tone="surface" padding="lg" align="start">
              {avatarPanel}
            </GlassCard>
          </div>

          <div className="divide-border-subtle lg:divide-border-default min-w-0 divide-y lg:flex-1">
            <Section heading={t('avatar_title')} px="4" py="4" uppercase className="lg:hidden">
              {avatarPanel}
            </Section>
            {profileSections}
          </div>
        </div>
      </main>

      {/* Remove payment method confirmation */}
      <AlertDialog
        open={removeTarget !== null}
        onOpenChange={(open) => {
          if (!open) setRemoveTarget(null);
        }}
      >
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>{tPm('remove_confirm_title')}</AlertDialogTitle>
            <AlertDialogDescription>
              {tPm('remove_confirm_desc').replace('{{last4}}', removeTarget?.last4 ?? '')}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={removingMethod}>{tCommon('cancel')}</AlertDialogCancel>
            <AlertDialogAction
              disabled={removingMethod}
              onClick={() => {
                if (!removeTarget) return;
                removeMethod(removeTarget.id, {
                  onSuccess: () => setRemoveTarget(null),
                  onError: () => {
                    setRemoveTarget(null);
                    setRemoveMethodError(t('remove_method_error'));
                  },
                });
              }}
            >
              {tPm('remove_confirm_action')}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* Delete account drawer — controlled, outside profileSections to avoid double-render */}
      <Drawer open={deleteDrawerOpen} onOpenChange={setDeleteDrawerOpen}>
        <DrawerContent side="bottom">
          <DrawerHeader>
            <DrawerTitle>{t('delete_account')}</DrawerTitle>
            <DrawerDescription className="sr-only">{t('delete_warning')}</DrawerDescription>
          </DrawerHeader>
          <DrawerClose asChild>
            <IconButton
              variant="ghost"
              size="sm"
              className="text-text-muted absolute end-4 top-4"
              aria-label={tCommon('close')}
            >
              <Icon name="X" size="sm" />
            </IconButton>
          </DrawerClose>
          <div className="px-6 pb-4">
            <p className="text-danger-700 mb-4 text-sm font-semibold">{t('delete_warning')}</p>
            <p className="text-text-secondary mb-6 text-sm">{t('delete_notice_48h')}</p>
          </div>
          <DrawerFooter>
            <Button
              variant="danger"
              size="lg"
              className="w-full"
              onClick={() => {
                requestDeletion();
                setDeleteDrawerOpen(false);
              }}
            >
              {t('delete_confirm')}
            </Button>
            <DrawerClose asChild>
              <Button variant="ghost" size="lg" className="w-full">
                {tCommon('cancel')}
              </Button>
            </DrawerClose>
          </DrawerFooter>
        </DrawerContent>
      </Drawer>

      {/* Add payment method drawer */}
      <Drawer
        open={addPaymentOpen}
        onOpenChange={(open) => {
          setAddPaymentOpen(open);
          if (!open) setAddPaymentError(null);
        }}
      >
        <DrawerContent side="bottom">
          <DrawerHeader>
            <DrawerTitle>{t('add_payment_drawer_title')}</DrawerTitle>
            <DrawerDescription className="sr-only">
              {t('add_payment_drawer_title')}
            </DrawerDescription>
          </DrawerHeader>
          <DrawerClose asChild>
            <IconButton
              variant="ghost"
              size="sm"
              className="text-text-muted absolute end-4 top-4"
              aria-label={tCommon('close')}
            >
              <Icon name="X" size="sm" />
            </IconButton>
          </DrawerClose>
          <div className="px-6 pb-2">
            {paymentConfig ? (
              <PaymentForm
                config={paymentConfig}
                submitLabel={t('save_card')}
                isProcessing={savingCard}
                externalError={addPaymentError}
                onToken={(singleUseToken, detectedBrand) => {
                  setAddPaymentError(null);
                  addPaymentMethod(
                    { singleUseToken, brand: detectedBrand },
                    {
                      onSuccess: () => {
                        void queryClient.invalidateQueries({ queryKey: qk.profile() });
                        setAddPaymentOpen(false);
                      },
                      onError: () => {
                        setAddPaymentError(t('add_payment_error'));
                      },
                    },
                  );
                }}
              />
            ) : (
              <div className="flex items-center justify-center py-8">
                <Spinner size="md" label={tCommon('loading')} />
              </div>
            )}
          </div>
        </DrawerContent>
      </Drawer>

      {/* Edit address drawer — controlled by editAddressId */}
      <Drawer
        open={editAddressId !== null}
        onOpenChange={(open) => {
          if (!open) {
            setEditAddressId(null);
            setEditAddressLabel('');
            setEditAddressFull('');
          }
        }}
      >
        <DrawerContent side="bottom">
          <DrawerHeader>
            <DrawerTitle>{t('add_address')}</DrawerTitle>
            <DrawerDescription className="sr-only">{t('address_label')}</DrawerDescription>
          </DrawerHeader>
          <DrawerClose asChild>
            <IconButton
              variant="ghost"
              size="sm"
              className="text-text-muted absolute end-4 top-4"
              aria-label={tCommon('close')}
            >
              <Icon name="X" size="sm" />
            </IconButton>
          </DrawerClose>
          <div className="flex flex-col gap-4 px-6 pb-4">
            <FormField label={t('address_label')} htmlFor="edit-address-label">
              <Input
                id="edit-address-label"
                value={editAddressLabel}
                onChange={(e) => setEditAddressLabel(e.target.value)}
              />
            </FormField>
            <FormField label={t('addresses_title')} htmlFor="edit-address-full">
              <Input
                id="edit-address-full"
                value={editAddressFull}
                onChange={(e) => setEditAddressFull(e.target.value)}
              />
            </FormField>
          </div>
          <DrawerFooter>
            <Button
              variant="primary"
              size="lg"
              className="w-full"
              loading={savingAddress}
              onClick={handleAddressSaveEdit}
            >
              {tCommon('save')}
            </Button>
            <DrawerClose asChild>
              <Button variant="ghost" size="lg" className="w-full">
                {tCommon('cancel')}
              </Button>
            </DrawerClose>
          </DrawerFooter>
        </DrawerContent>
      </Drawer>

      {/* Add address drawer — controlled, outside profileSections to avoid double-render */}
      <Drawer open={addAddressOpen} onOpenChange={setAddAddressOpen}>
        <DrawerContent side="bottom">
          <DrawerHeader>
            <DrawerTitle>{t('add_address')}</DrawerTitle>
            <DrawerDescription className="sr-only">{t('address_label')}</DrawerDescription>
          </DrawerHeader>
          <DrawerClose asChild>
            <IconButton
              variant="ghost"
              size="sm"
              className="text-text-muted absolute end-4 top-4"
              aria-label={tCommon('close')}
            >
              <Icon name="X" size="sm" />
            </IconButton>
          </DrawerClose>
          <div className="flex flex-col gap-4 px-6 pb-4">
            <FormField label={t('address_label')} htmlFor="new-address-label">
              <Input
                id="new-address-label"
                value={pendingLabel}
                onChange={(e) => setPendingLabel(e.target.value)}
                placeholder={t('address_label_placeholder')}
              />
            </FormField>
            <IsraeliAddressField value={pendingAddress} onChange={setPendingAddress} />
          </div>
          <DrawerFooter>
            <Button
              variant="primary"
              size="lg"
              className="w-full"
              loading={addingAddress}
              disabled={!pendingLabel.trim() && !pendingAddress?.cityName}
              onClick={() => {
                const built = pendingAddress ? buildFullAddress(pendingAddress) : '';
                const fullAddress = built || pendingLabel.trim();
                if (!fullAddress) return;
                addAddress(
                  {
                    fullAddress,
                    label: pendingLabel.trim() || undefined,
                    isDefault: profile.addresses.length === 0,
                  },
                  {
                    onSuccess: () => {
                      setAddAddressOpen(false);
                      setPendingAddress(null);
                      setPendingLabel('');
                    },
                  },
                );
              }}
            >
              {tCommon('save')}
            </Button>
            <DrawerClose asChild>
              <Button variant="ghost" size="lg" className="w-full">
                {tCommon('cancel')}
              </Button>
            </DrawerClose>
          </DrawerFooter>
        </DrawerContent>
      </Drawer>
    </AppShell>
  );
}

/**
 * Profile - exported island component.
 * QueryClient, LocaleProvider, ErrorBoundary provided by HydratedIsland upstream.
 * SSR data hydrates via qk.profile() key prefetched in profile.astro frontmatter.
 */
export function Profile({
  isAdmin = false,
  isVendor = false,
  userName,
}: { isAdmin?: boolean; isVendor?: boolean; userName?: string } = {}) {
  return <ProfileInner isAdmin={isAdmin} isVendor={isVendor} userName={userName} />;
}
