'use client';

import { lazy, Suspense, useEffect, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { ErrorBoundary } from '@/components/ui/feedback/ErrorBoundary';
import { RetryPanel } from '@/components/ui/feedback/RetryPanel';
import { Spinner } from '@/components/ui/feedback/Spinner';
import { Stack } from '@/components/ui/layout/Stack';
import { getCsrfToken } from '@/lib/csrf';
import { LocaleProvider, useLocale, useT } from '@/lib/i18n/react';
import { captureCaught } from '@/lib/observability';
import { qk } from '@/lib/query/keys';
import { VendorDetailActions } from './VendorDetailActions';
import { VendorDetailAddressesSection } from './VendorDetailAddressesSection';
import { VendorDetailAuditSection } from './VendorDetailAuditSection';
import { VendorDetailBusinessInfoSection } from './VendorDetailBusinessInfoSection';
import { VendorDetailClubSection } from './VendorDetailClubSection';
import { VendorDetailDealsSection } from './VendorDetailDealsSection';
import { VendorDetailHeader } from './VendorDetailHeader';
import { VendorDetailHoursSection } from './VendorDetailHoursSection';
import { VendorDetailLtvSection } from './VendorDetailLtvSection';
import { VendorDetailPaymentsSection } from './VendorDetailPaymentsSection';
import { VendorDetailReviewsSection } from './VendorDetailReviewsSection';
import {
  EMPTY_LTV,
  type AuditEntry,
  type FormAction,
  type VendorAction,
  type VendorDetailLtvData,
  type VendorDetailProps,
} from './VendorDetail.types';

export type {
  VendorAddressData,
  VendorBusinessHoursData,
  VendorDealData,
  VendorDetailData,
  VendorDetailLtvData,
  VendorDetailProps,
  VendorReviewData,
} from './VendorDetail.types';

const importEditActionPanel = () => import('./EditActionPanel');
const EditActionPanel = lazy(importEditActionPanel);
const importApproveAnywayDialog = () => import('./ApproveAnywayDialog');
const ApproveAnywayDialog = lazy(importApproveAnywayDialog);

export function VendorDetail({ initialLocale, ...props }: VendorDetailProps) {
  return (
    <LocaleProvider locale={initialLocale}>
      <VendorDetailInner {...props} />
    </LocaleProvider>
  );
}

function VendorDetailInner({
  vendor: initialVendor,
  ltv: ltvProp,
}: Omit<VendorDetailProps, 'initialLocale'>) {
  const t = useT('admin_vendor_detail') as (key: string) => string;
  const tAdmin = useT('admin') as (key: string) => string;
  const tCommon = useT('common') as (key: string) => string;
  const tHours = useT('domain_hours') as (key: string) => string;
  const { locale } = useLocale();
  const [approveAnywayDialogOpen, setApproveAnywayDialogOpen] = useState(false);
  const [approveAnywayMounted, setApproveAnywayMounted] = useState(false);
  const [vendor, setVendor] = useState(initialVendor);
  const [fetchedLtv, setFetchedLtv] = useState<VendorDetailLtvData | undefined>(undefined);
  const [ltvLoading, setLtvLoading] = useState(ltvProp === undefined);
  const [loading, setLoading] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [messageDialogOpen, setMessageDialogOpen] = useState(false);
  const [freezeDialogOpen, setFreezeDialogOpen] = useState(false);
  const [banDialogOpen, setBanDialogOpen] = useState(false);
  const [editPanelMounted, setEditPanelMounted] = useState(false);
  const ltv = ltvProp ?? fetchedLtv ?? EMPTY_LTV;

  useEffect(() => {
    if (ltvProp !== undefined) return;
    let cancelled = false;

    void (async () => {
      try {
        const res = await fetch(`/api/admin/vendors/${vendor.id}`);
        if (!res.ok) return;
        const json = (await res.json().catch((err) => {
          captureCaught(err, {
            scope: 'features.admin-vendor-detail.VendorDetail.ltv',
            severity: 'info',
          });
          return {};
        })) as { data?: { ltv?: VendorDetailLtvData } };
        if (!cancelled && json.data?.ltv) setFetchedLtv(json.data.ltv);
      } catch (err) {
        captureCaught(err, {
          scope: 'features.admin-vendor-detail.VendorDetail.ltv',
          severity: 'warning',
        });
      } finally {
        if (!cancelled) setLtvLoading(false);
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [ltvProp, vendor.id]);

  const auditQuery = useQuery<AuditEntry[]>({
    queryKey: qk.adminVendorAudit(vendor.id),
    queryFn: async () => {
      const res = await fetch(`/api/admin/vendors/${vendor.id}/audit?limit=50`);
      if (!res.ok) throw new Error('Failed to load audit log');
      const json = (await res.json()) as { ok: boolean; entries: AuditEntry[] };
      return json.entries;
    },
    staleTime: 60_000,
  });

  function applyLocalChange(action: VendorAction, extra?: Record<string, unknown>) {
    setVendor((prev) => {
      if (action === 'activate') return { ...prev, accountState: 'ACTIVE' };
      if (action === 'set_tier') {
        const tier = extra?.tier as 'NEW' | 'VETERAN';
        return { ...prev, tier, accountState: tier === 'VETERAN' ? 'VETERAN' : 'ACTIVE' };
      }
      if (action === 'freeze') return { ...prev, accountState: 'FROZEN' };
      if (action === 'unfreeze')
        return { ...prev, accountState: prev.tier === 'VETERAN' ? 'VETERAN' : 'ACTIVE' };
      if (action === 'ban') return { ...prev, accountState: 'BANNED' };
      if (action === 'approve_anyway') {
        return {
          ...prev,
          accountState: 'PENDING_PROCESSOR',
          flagReason: null,
          rejectReason: null,
          llmDecision: 'APPROVE',
        };
      }
      return prev;
    });
  }

  async function performAction(action: VendorAction, extra?: Record<string, unknown>) {
    const endpointMap: Record<VendorAction, string> = {
      activate: 'activate',
      set_tier: 'upgrade',
      freeze: 'freeze',
      unfreeze: 'unfreeze',
      ban: 'ban',
      send_message: 'message',
      approve_anyway: 'approve-anyway',
    };

    setLoading(action);
    setError(null);
    try {
      const res = await fetch(`/api/admin/vendors/${vendor.id}/${endpointMap[action]}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'x-csrf-token': getCsrfToken() },
        body: JSON.stringify(extra ?? {}),
      });
      if (!res.ok) throw new Error(await res.text());
      applyLocalChange(action, extra);
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setLoading(null);
    }
  }

  function openFormDialog(which: FormAction) {
    setEditPanelMounted(true);
    if (which === 'send_message') setMessageDialogOpen(true);
    if (which === 'freeze') setFreezeDialogOpen(true);
    if (which === 'ban') setBanDialogOpen(true);
  }

  const showApproveAnyway =
    (vendor.accountState === 'PENDING_FIRST_APPROVAL' && !!vendor.flagReason) ||
    vendor.accountState === 'REJECTED';

  return (
    <ErrorBoundary>
      <Stack gap="6" as="section" aria-label={t('page_title')}>
        <VendorDetailHeader vendor={vendor} logoAlt={t('logo_alt')} />

        {error && (
          <p role="alert" className="text-danger-600 text-sm">
            {error}
          </p>
        )}

        <VendorDetailActions
          vendor={vendor}
          loading={loading}
          showApproveAnyway={showApproveAnyway}
          onActivate={() => void performAction('activate')}
          onApproveAnywayOpen={() => {
            setApproveAnywayMounted(true);
            setApproveAnywayDialogOpen(true);
          }}
          onFreezeOpen={() => openFormDialog('freeze')}
          onUnfreeze={() => void performAction('unfreeze')}
          onBanOpen={() => openFormDialog('ban')}
          onMessageOpen={() => openFormDialog('send_message')}
          preloadApproveAnyway={() => {
            void importApproveAnywayDialog();
          }}
          preloadEditActionPanel={() => {
            void importEditActionPanel();
          }}
          t={t}
          tAdmin={tAdmin}
          tCommon={tCommon}
        />

        <VendorDetailLtvSection ltv={ltv} locale={locale} loading={ltvLoading} t={t} />
        <VendorDetailBusinessInfoSection
          vendor={vendor}
          locale={locale}
          loading={loading !== null}
          t={t}
          tAdmin={tAdmin}
          onTierChange={(tier) => void performAction('set_tier', { tier })}
        />
        <VendorDetailPaymentsSection vendor={vendor} t={t} />
        <VendorDetailDealsSection vendor={vendor} locale={locale} t={t} />
        <VendorDetailReviewsSection vendor={vendor} locale={locale} t={t} />
        <VendorDetailHoursSection vendor={vendor} t={t} tHours={tHours} />
        <VendorDetailAddressesSection vendor={vendor} t={t} />
        <VendorDetailClubSection clubMemberCount={vendor.clubMemberCount} t={t} />
        <VendorDetailAuditSection
          auditEntries={auditQuery.data}
          auditLoading={auditQuery.isLoading}
          auditError={auditQuery.isError}
          locale={locale}
          t={t}
          tAdmin={tAdmin}
        />

        {approveAnywayMounted && (
          <ErrorBoundary
            fallback={
              <RetryPanel variant="inline" onRetry={() => void importApproveAnywayDialog()} />
            }
          >
            <Suspense fallback={<Spinner />}>
              <ApproveAnywayDialog
                open={approveAnywayDialogOpen}
                onOpenChange={setApproveAnywayDialogOpen}
                onConfirm={() => {
                  void performAction('approve_anyway');
                }}
              />
            </Suspense>
          </ErrorBoundary>
        )}

        {editPanelMounted && (
          <ErrorBoundary
            fallback={<RetryPanel variant="inline" onRetry={() => void importEditActionPanel()} />}
          >
            <Suspense fallback={<Spinner />}>
              <EditActionPanel
                vendorId={vendor.id}
                messageOpen={messageDialogOpen}
                freezeOpen={freezeDialogOpen}
                banOpen={banDialogOpen}
                onMessageOpenChange={setMessageDialogOpen}
                onFreezeOpenChange={setFreezeDialogOpen}
                onBanOpenChange={setBanDialogOpen}
                onFreezeApplied={() => applyLocalChange('freeze')}
                onBanApplied={() => applyLocalChange('ban')}
                onLoadingChange={(action) => setLoading(action)}
                onError={setError}
                loading={loading as FormAction | null}
              />
            </Suspense>
          </ErrorBoundary>
        )}
      </Stack>
    </ErrorBoundary>
  );
}
