'use client';

/**
 * VendorOnboardingDone — post-Stripe-Connect-onboarding status page.
 *
 * POSTs /api/vendor/stripe/sync (live Stripe → DB), falls back to GET
 * /api/vendor/stripe/status on 429/5xx. Shows 3 distinct states:
 *   - chargesEnabled → success + auto-redirect to /vendor/earnings in 3s
 *   - detailsSubmitted but not chargesEnabled → KYC pending
 *   - neither → incomplete onboarding
 *
 * @example
 * <VendorOnboardingDone vendorId="uuid" />
 */

import { useEffect, useState, useRef } from 'react';
import { HydratedIsland } from '@/components/HydratedIsland';
import { useT } from '@/lib/i18n/react';
import type { StringBundle } from '@/lib/i18n';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import { ErrorState } from '@/components/ui/feedback/ErrorState';
import { Spinner } from '@/components/ui/feedback/Spinner';
import { Button } from '@/components/ui/primitives/Button';
import { captureCaught } from '@/lib/observability';
import { getCsrfToken } from '@/lib/csrf';

// ─── Types ──────────────────────────────────────────────────────────────────

export interface VendorOnboardingDoneProps {
  /** Kept for backwards compat with done.astro — not sent to server (sync uses session auth). */
  vendorId: string;
}

interface SyncResult {
  chargesEnabled: boolean;
  detailsSubmitted: boolean;
  onboardingState: string;
  requirementsCurrentlyDue: string[] | null;
}

type LoadState = 'loading' | 'loaded' | 'error';

type VendorPaymentsT = (key: keyof StringBundle['vendor_payments_page']) => string;

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

function requirementCodeLabel(code: string, t: VendorPaymentsT): string {
  const exactKeys: Record<string, keyof StringBundle['vendor_payments_page']> = {
    'individual.verification.document': 'requirement_individual_verification_document',
    'individual.verification.additional_document':
      'requirement_individual_verification_additional_document',
    external_account: 'requirement_external_account',
    'tos_acceptance.date': 'requirement_tos_acceptance_date',
    'individual.id_number': 'requirement_individual_id_number',
    'individual.phone': 'requirement_individual_phone',
    'business_profile.url': 'requirement_business_profile_url',
  };

  const exactKey = exactKeys[code];
  if (exactKey) {
    return t(exactKey);
  }
  if (code.startsWith('individual.dob.')) {
    return t('requirement_individual_dob');
  }
  if (code.startsWith('individual.address.')) {
    return t('requirement_individual_address');
  }
  return t('requirement_fallback');
}

// ─── Component ───────────────────────────────────────────────────────────────

function VendorOnboardingDoneInner({ vendorId }: VendorOnboardingDoneProps) {
  const t = useT('vendor_payments_page');
  const [loadState, setLoadState] = useState<LoadState>('loading');
  const [result, setResult] = useState<SyncResult | null>(null);

  const didFetch = useRef(false);
  const redirectTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

  useEffect(() => {
    if (didFetch.current) return;
    didFetch.current = true;

    async function run() {
      try {
        let data: SyncResult | null = null;

        // Primary: POST sync (live Stripe → DB)
        const syncRes = await fetch('/api/vendor/stripe/sync', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'x-csrf-token': getCsrfToken(),
          },
        });

        if (syncRes.ok) {
          const json = (await syncRes.json()) as SyncResult & { ok: boolean };
          data = json;
        } else if (syncRes.status === 429 || syncRes.status >= 500) {
          // Fallback: GET status (DB read, no Stripe call)
          const statusRes = await fetch(
            `/api/vendor/stripe/status?vendorId=${encodeURIComponent(vendorId)}`,
          );
          if (statusRes.ok) {
            const json = (await statusRes.json()) as {
              chargesEnabled?: boolean;
              onboardingState?: string;
              requirementsCurrentlyDue?: string[] | null;
              ok: boolean;
            };
            const state = json.onboardingState ?? 'account_created';
            data = {
              chargesEnabled: !!json.chargesEnabled,
              // /status endpoint does not return detailsSubmitted; derive from onboardingState
              detailsSubmitted: state === 'kyc_pending' || state === 'charges_enabled',
              onboardingState: state,
              requirementsCurrentlyDue: json.requirementsCurrentlyDue ?? null,
            };
          }
        }

        if (!data) {
          setLoadState('error');
          return;
        }

        setResult(data);
        setLoadState('loaded');

        if (data.chargesEnabled) {
          redirectTimer.current = setTimeout(() => {
            window.location.href = '/vendor/earnings';
          }, 3000);
        }
      } catch (err) {
        captureCaught(err, {
          scope: 'features.vendor-onboarding.Done',
          severity: 'warning',
          extra: { vendorId },
        });
        setLoadState('error');
      }
    }

    void run();

    return () => {
      if (redirectTimer.current) clearTimeout(redirectTimer.current);
    };
  }, [vendorId]);

  // ─── Loading ──────────────────────────────────────────────────────────────

  if (loadState === 'loading') {
    return (
      <div className="flex min-h-[var(--spacing-40)] items-center justify-center">
        <Spinner variant="dots" size="md" label={t('stripe_status_loading')} />
      </div>
    );
  }

  // ─── Error ────────────────────────────────────────────────────────────────

  if (loadState === 'error') {
    return (
      <ErrorState
        title={t('stripe_status_error_title')}
        description={t('stripe_status_error_body')}
        action={
          <Button variant="ghost" asChild>
            <a href="/vendor">{t('back_to_dashboard')}</a>
          </Button>
        }
      />
    );
  }

  // ─── Loaded ───────────────────────────────────────────────────────────────

  // chargesEnabled → success + auto-redirect
  if (result?.chargesEnabled) {
    return (
      <div className="flex flex-col gap-6 p-6" aria-live="polite">
        <InlineNotice
          tone="success"
          title={t('done_success_title')}
          description={t('done_success_redirect')}
        />
        <Button variant="secondary" asChild>
          <a href="/vendor/earnings">{t('done_success_cta')}</a>
        </Button>
      </div>
    );
  }

  // detailsSubmitted but not chargesEnabled → KYC pending
  if (result?.detailsSubmitted) {
    const due = result.requirementsCurrentlyDue ?? [];
    return (
      <div className="flex flex-col gap-6 p-6" aria-live="polite">
        <InlineNotice
          tone="warning"
          title={t('done_kyc_pending_title')}
          description={t('done_kyc_pending_body')}
        />
        {due.length > 0 && (
          <div className="flex flex-col gap-2">
            <p className="text-text-secondary text-sm font-medium">
              {t('stripe_requirements_title')}
            </p>
            <ul className="flex flex-col gap-1">
              {due.map((req) => (
                <li key={req} className="text-text-secondary text-sm">
                  {requirementCodeLabel(req, t)}
                </li>
              ))}
            </ul>
          </div>
        )}
        <Button variant="secondary" asChild>
          <a href="/vendor/settings/payments">{t('back_to_dashboard')}</a>
        </Button>
      </div>
    );
  }

  // neither chargesEnabled nor detailsSubmitted → incomplete
  return (
    <div className="flex flex-col gap-6 p-6" aria-live="polite">
      <InlineNotice
        tone="warning"
        title={t('done_details_incomplete_title')}
        description={t('done_details_incomplete_body')}
      />
      <Button variant="secondary" asChild>
        <a href="/vendor/settings/payments">{t('done_continue_cta')}</a>
      </Button>
    </div>
  );
}

export default function VendorOnboardingDone({ vendorId }: VendorOnboardingDoneProps) {
  return (
    <HydratedIsland>
      <VendorOnboardingDoneInner vendorId={vendorId} />
    </HydratedIsland>
  );
}
