/**
 * AddDealShell — vendor deal creation/edit shell (FDS §5.4 + mockup #3 Version C).
 *
 * Layout: two-column on desktop (form on one side, live PhonePreview on the other).
 *         Single column on mobile (form first, preview via toggle).
 *
 * Step 1: TypePickerSection (4 cards).
 * Step 2: FieldsCommon + (FieldsCoupon | FieldsGroup) + FieldsFooter,
 *         each rendered conditionally on dealType discriminator.
 *
 * State + side-effects live in sibling hooks (`useAddDeal`, `useAddDealEffects`,
 * `useAddDealActions`). This file is JSX orchestration only.
 */

'use client';

import { lazy, useState } from 'react';
import { HydratedIsland } from '@/components/HydratedIsland';
import { VendorShell } from '@/components/ui/layout/VendorShell';
import { Icon } from '@/components/ui/icons/Icon';
import { Button } from '@/components/ui/primitives/Button';
import { Input } from '@/components/ui/primitives/Input';
import { FormField } from '@/components/ui/primitives/FormField';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import { RejectionBanner } from '@/components/ui/domain/RejectionBanner';
import { getCsrfToken } from '@/lib/csrf';
import { useT } from '@/lib/i18n/react';
import { captureCaught } from '@/lib/observability';
import { useAddDeal } from './useAddDeal';
import { useDraftAutosave } from './useDraftAutosave';
import { useAddDealEffects, buildAutosavePayload } from './useAddDealEffects';
import { useAddDealActions } from './useAddDealActions';
import type { AddDealFormValues } from './useAddDeal';
import { todayHoursDefault, type BusinessHoursSnapshot } from './types';
import { TypePickerSection } from './steps/TypePickerSection';
import { FieldsCommon } from './steps/FieldsCommon';
import { FieldsCoupon } from './steps/FieldsCoupon';
import { FieldsGroup } from './steps/FieldsGroup';
import { FieldsFooter } from './steps/FieldsFooter';
import { VariantsStep } from './steps/VariantsStep';
import { MobilePreviewSheet } from './steps/MobilePreviewSheet';
import { DesktopPreviewAside } from './steps/DesktopPreviewAside';

const importPhonePreview = () =>
  import('@/components/ui/domain/vendor/PhonePreview').then((m) => ({
    default: m.PhonePreview,
  }));
const PhonePreviewLazy = lazy(importPhonePreview);

export interface AddDealProps {
  /** If provided, the form is in edit mode. */
  dealId?: string;
  /** Vendor ID — enables draft autosave when provided. */
  vendorId?: string;
  /** Pre-filled values for edit mode. */
  defaultValues?: Partial<AddDealFormValues>;
  /** Whether the vendor is VETERAN tier (deals go live immediately). */
  isVeteran?: boolean;
  /** Current durable deal state for lifecycle controls in edit mode. */
  initialDealState?: string;
  /** Rejection info for rejected deals in edit mode. */
  rejection?: { reason: string; detail?: string };
  /** URL to redirect to after a successful save. Defaults to /vendor/dashboard. */
  successRedirect?: string;
  /** Vendor business hours for DealDurationPicker week-end preset + pickup hours default. */
  businessHours?: BusinessHoursSnapshot | null;
  /** Maximum number of images allowed per deal (from platform settings). */
  maxImagesPerDeal?: number;
  /** Maximum number of images allowed per SKU (from platform settings). */
  maxImagesPerSku?: number;
  /** VendorShell nav highlight path. Defaults to /vendor/deals/new. */
  currentPath?: string;
}

function AddDealInner({
  dealId,
  vendorId,
  defaultValues,
  isVeteran = false,
  initialDealState,
  rejection,
  successRedirect = '/vendor/dashboard',
  businessHours = null,
  maxImagesPerDeal,
  maxImagesPerSku,
  currentPath = '/vendor/deals/new',
}: AddDealProps) {
  const t = useT('vendor_add_deal');
  const tDrafts = useT('vendorDrafts');
  const isEditMode = !!dealId;

  // Read initial draftId from URL on mount.
  const [initialDraftId] = useState<string | null>(() => {
    if (typeof window === 'undefined') return null;
    return new URLSearchParams(window.location.search).get('draftId');
  });

  const { form, dealType, calculatedPrice, serverError, onSubmit } = useAddDeal({
    dealId,
    draftId: vendorId ? initialDraftId : undefined,
    defaultValues: (() => {
      const { start, end } = todayHoursDefault(businessHours);
      return { pickupStart: start, pickupEnd: end, ...defaultValues };
    })(),
    isVeteran,
    onSuccess: (id) => {
      window.location.href = id ? `/vendor/deals/${id}` : successRedirect;
    },
  });

  const {
    categories,
    tags,
    dealImagePreviewUrl,
    currentDealState,
    starred,
    setStarred,
    launchMode,
    setLaunchMode,
  } = useAddDealEffects({
    form,
    isEditMode,
    dealId,
    initialDealState,
    initialDraftId,
    onCategoriesError: (msg) => form.setError('root', { message: msg }),
    onTagsError: (msg) => form.setError('root', { message: msg }),
    errorMessages: {
      categories: t('error_load_categories'),
      tags: t('error_load_tags'),
    },
  });

  const allValues = form.watch();
  const autosavePayload = buildAutosavePayload(allValues, calculatedPrice);

  const {
    draftId,
    state: autosaveState,
    savedAt,
    saveNow,
  } = useDraftAutosave({
    vendorId: vendorId ?? '',
    initialDraftId,
    payload: autosavePayload,
    enabled: !!vendorId && !isEditMode,
  });

  const {
    handleSubmit,
    starPending,
    toggleStar,
    archivePending,
    onArchive,
    submitPending,
    onSubmitForReview,
  } = useAddDealActions({
    form,
    dealId,
    vendorId,
    isEditMode,
    draftId,
    launchMode,
    calculatedPrice,
    successRedirect,
    saveNow,
    hookOnSubmit: () => void onSubmit(),
    tDrafts,
    starred,
    setStarred,
  });

  const [showMobilePreview, setShowMobilePreview] = useState(false);
  const [phonePreviewRetryKey, setPhonePreviewRetryKey] = useState(0);
  const [quantityDelta, setQuantityDelta] = useState('');
  const [lifecyclePending, setLifecyclePending] = useState(false);
  const [lifecycleError, setLifecycleError] = useState<string | null>(null);
  const onPreviewRetry = () => {
    void importPhonePreview();
    setPhonePreviewRetryKey((k) => k + 1);
  };

  async function runLifecycleAction(action: 'quantity' | 'pause' | 'resume') {
    if (!dealId || lifecyclePending) return;
    setLifecycleError(null);
    setLifecyclePending(true);
    try {
      const response = await fetch(`/api/vendor/deals/${dealId}/${action}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'x-csrf-token': getCsrfToken() },
        body: action === 'quantity' ? JSON.stringify({ delta: Number(quantityDelta) }) : '{}',
      });
      const result = (await response.json()) as { ok: boolean; error?: string };
      if (!response.ok || !result.ok) {
        setLifecycleError(result.error ?? t('lifecycle_error'));
        return;
      }
      window.location.reload();
    } catch (err) {
      captureCaught(err, {
        scope: 'features.vendor-add-deal.AddDealShell.runLifecycleAction',
        severity: 'warning',
      });
      setLifecycleError(t('lifecycle_error'));
    } finally {
      setLifecyclePending(false);
    }
  }

  const title = form.watch('title');
  const description = form.watch('description');
  const originalPrice = form.watch('originalPrice');
  const groupTieredPricing = form.watch('groupTieredPricing') ?? false;
  const groupTiers = form.watch('groupTiers') ?? [];

  const phonePreviewDeal = {
    title: title || undefined,
    vendorName: undefined,
    description: description || undefined,
    priceNow: Number(calculatedPrice) || undefined,
    priceWas: Number(originalPrice) || undefined,
    imageUrl: dealImagePreviewUrl ?? undefined,
    tiersLabel:
      groupTieredPricing && groupTiers.length > 0
        ? t('preview_tiers_count').replace('{count}', String(groupTiers.length))
        : undefined,
  };

  const previewNode = <PhonePreviewLazy deal={phonePreviewDeal} />;

  return (
    <VendorShell variant="dashboard" currentPath={currentPath}>
      <div aria-labelledby="add-deal-heading" className="px-4 py-4 lg:px-6 lg:py-6">
        <h1 id="add-deal-heading" className="sr-only">
          {isEditMode ? t('title_edit') : t('title')}
        </h1>

        {rejection && (
          <div className="mb-4">
            <RejectionBanner
              title={t('rejection_title')}
              reason={rejection.reason}
              detail={rejection.detail ?? t('rejection_hint')}
            />
          </div>
        )}

        {/* Mobile preview toggle */}
        <div className="mb-4 flex justify-end lg:hidden">
          <Button
            type="button"
            variant="secondary"
            size="sm"
            onClick={() => setShowMobilePreview((v) => !v)}
            aria-expanded={showMobilePreview}
            iconStart={<Icon name="Eye" size="sm" />}
          >
            {t('preview_title')}
          </Button>
        </div>

        {showMobilePreview && (
          <MobilePreviewSheet
            retryKey={phonePreviewRetryKey}
            onClose={() => setShowMobilePreview(false)}
            onRetry={onPreviewRetry}
            preview={previewNode}
          />
        )}

        {/* Desktop two-column grid */}
        <div className="flex flex-col gap-6 lg:grid lg:grid-cols-[1fr_auto] lg:items-start lg:gap-8">
          <form
            onSubmit={handleSubmit}
            noValidate
            data-testid="deal-form"
            className="flex flex-col gap-5"
          >
            <TypePickerSection value={dealType} onChange={(v) => form.setValue('dealType', v)} />

            <section
              aria-labelledby="fields-heading"
              className="bg-surface-default rounded-2xl p-4 shadow-md"
            >
              <h2 id="fields-heading" className="text-text-primary mb-3 text-sm font-semibold">
                {t('fields_title')}
              </h2>

              <div className="flex flex-col gap-3">
                <FieldsCommon
                  form={form}
                  categories={categories}
                  displayedTags={tags}
                  calculatedPrice={calculatedPrice}
                  maxImagesPerDeal={maxImagesPerDeal ?? 5}
                  dealType={dealType}
                />

                {dealType === 'COUPON' && (
                  <FieldsCoupon
                    form={form}
                    launchMode={launchMode}
                    onLaunchModeChange={setLaunchMode}
                    businessHours={businessHours}
                  />
                )}

                {dealType === 'GROUP' && (
                  <FieldsGroup form={form} calculatedPrice={calculatedPrice} />
                )}

                {dealType === 'COUPON' && (
                  <VariantsStep form={form} {...({ maxImagesPerSku } as Record<string, unknown>)} />
                )}

                {isEditMode && (currentDealState === 'ACTIVE' || currentDealState === 'PAUSED') && (
                  <section
                    aria-labelledby="deal-lifecycle-heading"
                    className="border-border-subtle flex flex-col gap-3 rounded-lg border p-3"
                  >
                    <h3 id="deal-lifecycle-heading" className="text-text-primary font-semibold">
                      {t('lifecycle_title')}
                    </h3>
                    <p className="text-text-secondary text-sm">
                      {currentDealState === 'ACTIVE'
                        ? t('lifecycle_status_active')
                        : t('lifecycle_status_paused')}
                    </p>
                    <div className="flex flex-col gap-3 sm:flex-row sm:items-end">
                      <FormField
                        htmlFor="deal-quantity-delta"
                        label={t('lifecycle_quantity_label')}
                      >
                        <Input
                          id="deal-quantity-delta"
                          type="number"
                          min={1}
                          step={1}
                          value={quantityDelta}
                          onChange={(event) => setQuantityDelta(event.target.value)}
                        />
                      </FormField>
                      <Button
                        type="button"
                        variant="secondary"
                        disabled={!/^\d+$/.test(quantityDelta) || Number(quantityDelta) < 1}
                        loading={lifecyclePending}
                        onClick={() => void runLifecycleAction('quantity')}
                      >
                        {t('lifecycle_quantity_action')}
                      </Button>
                    </div>
                    <Button
                      type="button"
                      variant={currentDealState === 'ACTIVE' ? 'danger' : 'primary'}
                      loading={lifecyclePending}
                      onClick={() =>
                        void runLifecycleAction(currentDealState === 'ACTIVE' ? 'pause' : 'resume')
                      }
                    >
                      {currentDealState === 'ACTIVE'
                        ? t('lifecycle_pause_action')
                        : t('lifecycle_resume_action')}
                    </Button>
                    {lifecycleError && <InlineNotice tone="danger" title={lifecycleError} />}
                  </section>
                )}

                <FieldsFooter
                  form={form}
                  serverError={serverError}
                  isVeteran={isVeteran}
                  isEditMode={isEditMode}
                  isSubmitting={form.formState.isSubmitting}
                  showAutosave={!!vendorId && !isEditMode}
                  autosaveState={autosaveState}
                  savedAt={savedAt}
                  onSaveDraft={() => void saveNow()}
                  starred={starred}
                  starPending={starPending}
                  onToggleStar={() => void toggleStar()}
                  showSubmitForReview={isEditMode && currentDealState === 'REJECTED'}
                  submitPending={submitPending}
                  onSubmitForReview={() => void onSubmitForReview()}
                  showArchive={
                    isEditMode && (currentDealState === 'ACTIVE' || currentDealState === 'PAUSED')
                  }
                  archivePending={archivePending}
                  onArchive={onArchive}
                />
              </div>
            </section>
          </form>

          <DesktopPreviewAside
            retryKey={phonePreviewRetryKey}
            onRetry={onPreviewRetry}
            preview={previewNode}
          />
        </div>
      </div>
    </VendorShell>
  );
}

export function AddDeal(props: AddDealProps) {
  return (
    <HydratedIsland>
      <AddDealInner {...props} />
    </HydratedIsland>
  );
}
