// Admin promo-code create/edit form — mirrors createPromoCodeSchema.
// POST to /api/admin/promo-codes (new) | PATCH to /api/admin/promo-codes/[id] (edit).

import { useState, useEffect, useMemo } from 'react';
import { useForm, Controller, useWatch } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { promoScopeKind } from '@/lib/enums/promo-scope-kind';
import { useT } from '@/lib/i18n/react';
import { Button } from '@/components/ui/primitives/Button';
import { Input } from '@/components/ui/primitives/Input';
import { Label } from '@/components/ui/primitives/Label';
import { Checkbox } from '@/components/ui/primitives/Checkbox';
import { NumberInput } from '@/components/ui/primitives/NumberInput';
import { RadioGroup, RadioItem } from '@/components/ui/primitives/RadioGroup';
import { Skeleton } from '@/components/ui/feedback/Skeleton';
import {
  Select,
  SelectTrigger,
  SelectContent,
  SelectItem,
  SelectValue,
} from '@/components/ui/primitives/Select';
import { notify } from '@/lib/query/toast-bridge';
import { captureCaught } from '@/lib/observability';
import { promoFunder, type PromoFunder } from '@/lib/enums/promo-funder';
import { promoKind, type PromoKind } from '@/lib/enums/promo-kind';
import { promoStatus, type PromoStatus } from '@/lib/enums/promo-status';
import { type PromoScopeKind } from '@/lib/enums/promo-scope-kind';

function buildFormSchema(t: (key: string) => string) {
  return z
    .object({
      code: z
        .string()
        .min(3, t('admin.form.err_code_format'))
        .max(64, t('admin.form.err_code_format'))
        .regex(/^[A-Za-z0-9_-]+$/, t('admin.form.err_code_format')),
      kind: promoKind.schema,
      valueBps: z.string().optional(),
      valueAmount: z.string().optional(),
      bogoBuy: z.string().optional(),
      bogoGetFree: z.string().optional(),
      maxCapAmount: z.string().optional(),
      funder: promoFunder.schema,
      vendorId: z.string().optional(),
      status: promoStatus.schema,
      validFrom: z.string().optional(),
      validUntil: z.string().optional(),
      minSubtotal: z.string().optional(),
      maxSubtotal: z.string().optional(),
      totalCap: z.string().optional(),
      perUserCap: z.string(),
      description: z.string().max(280).optional(),
      scopeKind: promoScopeKind.schema,
      scopeIds: z.string().optional(),
      firstPurchaseOnly: z.boolean().optional(),
      clubOnly: z.boolean().optional(),
      userAllowlist: z.string().optional(),
    })
    .refine((v) => (v.kind === 'percentage' ? (v.valueBps ?? '').length > 0 : true), {
      message: t('admin.form.err_percentage_required'),
      path: ['valueBps'],
    })
    .refine((v) => (v.kind === 'fixed_amount' ? (v.valueAmount ?? '').length > 0 : true), {
      message: t('admin.form.err_amount_required'),
      path: ['valueAmount'],
    })
    .refine(
      (v) =>
        v.kind === 'bogo' ? (v.bogoBuy ?? '').length > 0 && (v.bogoGetFree ?? '').length > 0 : true,
      {
        message: t('admin.form.err_bogo_required'),
        path: ['bogoBuy'],
      },
    )
    .refine((v) => (v.funder === 'vendor' ? (v.vendorId ?? '').length > 0 : true), {
      message: t('admin.form.err_vendor_required'),
      path: ['vendorId'],
    });
}

function scopeIdsLabel(scopeKind: PromoScopeKind, t: (key: string) => string): string {
  if (scopeKind === 'deals') return t('admin.form.scope_ids_deals');
  if (scopeKind === 'categories') return t('admin.form.scope_ids_categories');
  if (scopeKind === 'tags') return t('admin.form.scope_ids_tags');
  if (scopeKind === 'vendor') return t('admin.form.scope_ids_vendor');
  return t('admin.form.scope_ids_label');
}

interface PromoCodeApiRules {
  scope?:
    | { kind: 'all' }
    | { kind: 'deals'; dealIds: string[] }
    | { kind: 'categories'; categoryIds: string[] }
    | { kind: 'tags'; tagIds: string[] }
    | { kind: 'vendor'; vendorId: string };
  eligibility?: {
    firstPurchaseOnly?: boolean;
    clubOnly?: boolean;
    userAllowlist?: string[];
  };
}

interface PromoCodeApiRecord {
  id: string;
  code: string;
  kind: PromoKind;
  valueBps: number | null;
  valueAmount: number | null;
  bogoBuy: number | null;
  bogoGetFree: number | null;
  maxCapAmount: number | null;
  funder: PromoFunder;
  vendorId: string | null;
  status: PromoStatus;
  validFrom: string | null;
  validUntil: string | null;
  minSubtotal: number | null;
  maxSubtotal: number | null;
  totalCap: number | null;
  perUserCap: number;
  description: string | null;
  rulesJson: PromoCodeApiRules;
}

interface GetPromoCodeApiResponse {
  ok: boolean;
  data?: { code: PromoCodeApiRecord };
}

type FormValues = {
  code: string;
  kind: PromoKind;
  valueBps?: string;
  valueAmount?: string;
  bogoBuy?: string;
  bogoGetFree?: string;
  maxCapAmount?: string;
  funder: PromoFunder;
  vendorId?: string;
  status: PromoStatus;
  validFrom?: string;
  validUntil?: string;
  minSubtotal?: string;
  maxSubtotal?: string;
  totalCap?: string;
  perUserCap: string;
  description?: string;
  scopeKind: PromoScopeKind;
  scopeIds?: string;
  firstPurchaseOnly?: boolean;
  clubOnly?: boolean;
  userAllowlist?: string;
};

function csvToArray(csv: string | undefined): string[] {
  return (csv ?? '')
    .split(',')
    .map((s) => s.trim())
    .filter(Boolean);
}

function toApiPayload(v: FormValues) {
  const rulesJson: Record<string, unknown> = {
    eligibility: {
      ...(v.firstPurchaseOnly ? { firstPurchaseOnly: true } : {}),
      ...(v.clubOnly ? { clubOnly: true } : {}),
      ...(csvToArray(v.userAllowlist).length > 0
        ? { userAllowlist: csvToArray(v.userAllowlist) }
        : {}),
    },
    scope:
      v.scopeKind === 'all'
        ? { kind: 'all' }
        : v.scopeKind === 'deals'
          ? { kind: 'deals', dealIds: csvToArray(v.scopeIds) }
          : v.scopeKind === 'categories'
            ? { kind: 'categories', categoryIds: csvToArray(v.scopeIds) }
            : v.scopeKind === 'tags'
              ? { kind: 'tags', tagIds: csvToArray(v.scopeIds) }
              : { kind: 'vendor', vendorId: v.scopeIds ?? '' },
  };

  return {
    code: v.code.toUpperCase(),
    kind: v.kind,
    ...(v.kind === 'percentage' && v.valueBps
      ? { valueBps: Math.round(parseFloat(v.valueBps) * 100) }
      : {}),
    ...(v.kind === 'fixed_amount' && v.valueAmount
      ? { valueAmount: Math.round(parseFloat(v.valueAmount) * 100) }
      : {}),
    ...(v.kind === 'bogo' && v.bogoBuy ? { bogoBuy: parseInt(v.bogoBuy, 10) } : {}),
    ...(v.kind === 'bogo' && v.bogoGetFree ? { bogoGetFree: parseInt(v.bogoGetFree, 10) } : {}),
    ...(v.kind === 'percentage' && v.maxCapAmount
      ? { maxCapAmount: Math.round(parseFloat(v.maxCapAmount) * 100) }
      : {}),
    funder: v.funder,
    ...(v.vendorId ? { vendorId: v.vendorId } : { vendorId: null }),
    status: v.status,
    ...(v.validFrom ? { validFrom: new Date(v.validFrom).toISOString() } : {}),
    ...(v.validUntil ? { validUntil: new Date(v.validUntil).toISOString() } : {}),
    ...(v.minSubtotal ? { minSubtotal: Math.round(parseFloat(v.minSubtotal) * 100) } : {}),
    ...(v.maxSubtotal ? { maxSubtotal: Math.round(parseFloat(v.maxSubtotal) * 100) } : {}),
    ...(v.totalCap ? { totalCap: parseInt(v.totalCap, 10) } : {}),
    perUserCap: parseInt(v.perUserCap || '1', 10),
    rulesJson,
    ...(v.description ? { description: v.description } : {}),
  };
}

// ─── Props ────────────────────────────────────────────────────────────────────

interface PromoCodeFormProps {
  id?: string; // edit mode when present
}

function PromoCodeFormSkeleton() {
  return (
    <div className="mx-auto max-w-2xl px-4 py-6" aria-hidden="true">
      <div className="mb-4 space-y-2">
        <Skeleton className="h-4 w-32" />
        <Skeleton className="h-10 w-full" />
      </div>
      <div className="mb-4 space-y-2">
        <Skeleton className="h-4 w-40" />
        <Skeleton className="h-10 w-full" />
      </div>
      <div className="mb-4 space-y-2">
        <Skeleton className="h-4 w-28" />
        <Skeleton className="h-10 w-full" />
      </div>
      <div className="mb-4 space-y-2">
        <Skeleton className="h-4 w-24" />
        <Skeleton className="h-10 w-full" />
      </div>
      <div className="grid grid-cols-2 gap-4">
        <Skeleton className="h-10 w-full" />
        <Skeleton className="h-10 w-full" />
      </div>
    </div>
  );
}

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

export function PromoCodeForm({ id }: PromoCodeFormProps) {
  const t = useT('promo_codes') as unknown as (key: string) => string;
  const formSchema = useMemo(() => buildFormSchema(t), [t]);
  const isEdit = Boolean(id);
  const [fetching, setFetching] = useState(isEdit);
  const [submitting, setSubmitting] = useState(false);

  const {
    register,
    handleSubmit,
    control,
    reset,
    formState: { errors },
  } = useForm<FormValues>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      kind: 'percentage',
      funder: 'platform',
      status: 'active',
      scopeKind: 'all',
      perUserCap: '1',
      firstPurchaseOnly: false,
      clubOnly: false,
    },
  });

  const kind = useWatch({ control, name: 'kind' });
  const funder = useWatch({ control, name: 'funder' });
  const scopeKind = useWatch({ control, name: 'scopeKind' });

  // Load existing code for edit mode
  useEffect(() => {
    if (!isEdit) return;
    async function fetchCode() {
      try {
        const res = await fetch(`/api/admin/promo-codes/${id}`);
        const json = (await res.json()) as GetPromoCodeApiResponse;
        const c = json?.data?.code;
        if (!c) return;
        const rules = c.rulesJson ?? {};
        const scope = rules.scope ?? { kind: 'all' };
        const eligibility = rules.eligibility ?? {};
        reset({
          code: c.code,
          kind: c.kind,
          valueBps: c.valueBps != null ? String(c.valueBps / 100) : '',
          valueAmount: c.valueAmount != null ? String(c.valueAmount / 100) : '',
          bogoBuy: c.bogoBuy != null ? String(c.bogoBuy) : '',
          bogoGetFree: c.bogoGetFree != null ? String(c.bogoGetFree) : '',
          maxCapAmount: c.maxCapAmount != null ? String(c.maxCapAmount / 100) : '',
          funder: c.funder,
          vendorId: c.vendorId ?? '',
          status: c.status,
          validFrom: c.validFrom ? new Date(c.validFrom).toISOString().slice(0, 16) : '',
          validUntil: c.validUntil ? new Date(c.validUntil).toISOString().slice(0, 16) : '',
          minSubtotal: c.minSubtotal != null ? String(c.minSubtotal / 100) : '',
          maxSubtotal: c.maxSubtotal != null ? String(c.maxSubtotal / 100) : '',
          totalCap: c.totalCap != null ? String(c.totalCap) : '',
          perUserCap: String(c.perUserCap ?? 1),
          description: c.description ?? '',
          scopeKind: scope.kind,
          scopeIds:
            scope.kind === 'deals'
              ? (scope.dealIds ?? []).join(', ')
              : scope.kind === 'categories'
                ? (scope.categoryIds ?? []).join(', ')
                : scope.kind === 'tags'
                  ? (scope.tagIds ?? []).join(', ')
                  : scope.kind === 'vendor'
                    ? (scope.vendorId ?? '')
                    : '',
          firstPurchaseOnly: eligibility.firstPurchaseOnly ?? false,
          clubOnly: eligibility.clubOnly ?? false,
          userAllowlist: (eligibility.userAllowlist ?? []).join(', '),
        });
      } catch (err) {
        captureCaught(err, {
          scope: 'features.admin-promo-codes.PromoCodeForm.fetch',
          severity: 'warning',
        });
      } finally {
        setFetching(false);
      }
    }
    void fetchCode();
  }, [id, isEdit, reset]);

  async function onSubmit(values: FormValues) {
    setSubmitting(true);
    try {
      const payload = toApiPayload(values);
      const url = isEdit ? `/api/admin/promo-codes/${id}` : '/api/admin/promo-codes';
      const method = isEdit ? 'PATCH' : 'POST';
      const res = await fetch(url, {
        method,
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });
      if (!res.ok) {
        const json = (await res.json().catch((e: unknown) => {
          captureCaught(e, {
            scope: 'features.admin-promo-codes.PromoCodeForm.parse',
            severity: 'warning',
          });
          return {};
        })) as { error?: string };
        throw new Error(json.error ?? 'Submit failed');
      }
      notify.success(t('admin.form.saved_ok'));
      window.location.assign('/admin/promo-codes');
    } catch (err) {
      captureCaught(err, {
        scope: 'features.admin-promo-codes.PromoCodeForm.submit',
        severity: 'warning',
      });
      notify.error(t('admin.form.saved_error'));
    } finally {
      setSubmitting(false);
    }
  }

  if (fetching) {
    return <PromoCodeFormSkeleton />;
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="mx-auto max-w-2xl px-4 py-6" noValidate>
      {/* ── Code ── */}
      <div className="mb-4">
        <Label htmlFor="promo-code">{t('admin.form.code_label')}</Label>
        <Input
          id="promo-code"
          {...register('code')}
          invalid={!!errors.code}
          aria-describedby={errors.code ? 'promo-code-err' : undefined}
          className="mt-1 uppercase"
          placeholder="SUMMER20"
        />
        {errors.code && (
          <p id="promo-code-err" className="text-danger-600 mt-1 text-sm" role="alert">
            {errors.code.message}
          </p>
        )}
        <p className="text-text-muted mt-1 text-xs">{t('admin.form.code_hint')}</p>
      </div>

      {/* ── Description ── */}
      <div className="mb-4">
        <Label htmlFor="promo-description">{t('admin.form.description_label')}</Label>
        <Input
          id="promo-description"
          {...register('description')}
          className="mt-1"
          placeholder={t('admin.form.description_placeholder')}
        />
      </div>

      {/* ── Status ── */}
      <div className="mb-4">
        <Label htmlFor="promo-status">{t('admin.form.status_label')}</Label>
        <Controller
          name="status"
          control={control}
          render={({ field }) => (
            <Select value={field.value} onValueChange={field.onChange}>
              <SelectTrigger id="promo-status" className="mt-1">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="active">{t('admin.form.status_active')}</SelectItem>
                <SelectItem value="paused">{t('admin.form.status_paused')}</SelectItem>
                <SelectItem value="archived">{t('admin.form.status_archived')}</SelectItem>
              </SelectContent>
            </Select>
          )}
        />
      </div>

      {/* ── Kind ── */}
      <div className="mb-4">
        <Label htmlFor="promo-kind">{t('admin.form.kind_label')}</Label>
        <Controller
          name="kind"
          control={control}
          render={({ field }) => (
            <Select value={field.value} onValueChange={field.onChange}>
              <SelectTrigger id="promo-kind" className="mt-1">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="percentage">{t('admin.form.kind_percentage')}</SelectItem>
                <SelectItem value="fixed_amount">{t('admin.form.kind_fixed')}</SelectItem>
                <SelectItem value="bogo">{t('admin.form.kind_bogo')}</SelectItem>
              </SelectContent>
            </Select>
          )}
        />
      </div>

      {/* ── Kind-specific value fields ── */}
      {kind === 'percentage' && (
        <div className="mb-4">
          <Label htmlFor="promo-valueBps">{t('admin.form.value_bps_label')}</Label>
          <Controller
            name="valueBps"
            control={control}
            render={({ field }) => (
              <NumberInput
                id="promo-valueBps"
                min={0.01}
                max={100}
                step={0.01}
                invalid={!!errors.valueBps}
                className="mt-1"
                value={field.value ? parseFloat(field.value) : 0}
                onChange={(n) => field.onChange(String(n))}
              />
            )}
          />
          {errors.valueBps && (
            <p className="text-danger-600 mt-1 text-sm" role="alert">
              {errors.valueBps.message}
            </p>
          )}
        </div>
      )}

      {kind === 'percentage' && (
        <div className="mb-4">
          <Label htmlFor="promo-maxCapAmount">{t('admin.form.max_cap_amount_label')}</Label>
          <Controller
            name="maxCapAmount"
            control={control}
            render={({ field }) => (
              <NumberInput
                id="promo-maxCapAmount"
                min={0}
                step={0.01}
                className="mt-1"
                value={field.value ? parseFloat(field.value) : 0}
                onChange={(n) => field.onChange(n > 0 ? String(n) : '')}
              />
            )}
          />
        </div>
      )}

      {kind === 'fixed_amount' && (
        <div className="mb-4">
          <Label htmlFor="promo-valueAmount">{t('admin.form.value_amount_label')}</Label>
          <Controller
            name="valueAmount"
            control={control}
            render={({ field }) => (
              <NumberInput
                id="promo-valueAmount"
                min={0.01}
                step={0.01}
                invalid={!!errors.valueAmount}
                className="mt-1"
                value={field.value ? parseFloat(field.value) : 0}
                onChange={(n) => field.onChange(String(n))}
              />
            )}
          />
          {errors.valueAmount && (
            <p className="text-danger-600 mt-1 text-sm" role="alert">
              {errors.valueAmount.message}
            </p>
          )}
        </div>
      )}

      {kind === 'bogo' && (
        <div className="mb-4 grid grid-cols-2 gap-4">
          <div>
            <Label htmlFor="promo-bogoBuy">{t('admin.form.bogo_buy_label')}</Label>
            <Controller
              name="bogoBuy"
              control={control}
              render={({ field }) => (
                <NumberInput
                  id="promo-bogoBuy"
                  min={1}
                  step={1}
                  invalid={!!errors.bogoBuy}
                  className="mt-1"
                  value={field.value ? parseInt(field.value, 10) : 1}
                  onChange={(n) => field.onChange(String(n))}
                />
              )}
            />
            {errors.bogoBuy && (
              <p className="text-danger-600 mt-1 text-sm" role="alert">
                {errors.bogoBuy.message}
              </p>
            )}
          </div>
          <div>
            <Label htmlFor="promo-bogoGetFree">{t('admin.form.bogo_get_label')}</Label>
            <Controller
              name="bogoGetFree"
              control={control}
              render={({ field }) => (
                <NumberInput
                  id="promo-bogoGetFree"
                  min={1}
                  step={1}
                  className="mt-1"
                  value={field.value ? parseInt(field.value, 10) : 1}
                  onChange={(n) => field.onChange(String(n))}
                />
              )}
            />
          </div>
        </div>
      )}

      {/* ── Funder ── */}
      <div className="mb-4">
        <Label htmlFor="promo-funder">{t('admin.form.funder_label')}</Label>
        <Controller
          name="funder"
          control={control}
          render={({ field }) => (
            <Select value={field.value} onValueChange={field.onChange}>
              <SelectTrigger id="promo-funder" className="mt-1">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="platform">{t('admin.form.funder_platform')}</SelectItem>
                <SelectItem value="vendor">{t('admin.form.funder_vendor')}</SelectItem>
              </SelectContent>
            </Select>
          )}
        />
      </div>

      {funder === 'vendor' && (
        <div className="mb-4">
          <Label htmlFor="promo-vendorId">{t('admin.form.vendor_id_label')}</Label>
          <Input
            id="promo-vendorId"
            {...register('vendorId')}
            invalid={!!errors.vendorId}
            className="mt-1"
            placeholder={t('admin.form.vendor_id_placeholder')}
          />
          {errors.vendorId && (
            <p className="text-danger-600 mt-1 text-sm" role="alert">
              {errors.vendorId.message}
            </p>
          )}
          <p className="text-text-muted mt-1 text-xs">{t('admin.form.vendor_id_hint')}</p>
        </div>
      )}

      {/* ── Scope ── */}
      <fieldset className="border-border-default mb-6 rounded-lg border p-4">
        <legend className="px-1 text-sm font-medium text-neutral-700">
          {t('admin.form.scope_label')}
        </legend>
        <Controller
          name="scopeKind"
          control={control}
          render={({ field }) => (
            <RadioGroup
              value={field.value}
              onValueChange={field.onChange}
              className="flex flex-row flex-wrap gap-4"
            >
              {promoScopeKind.values.map((kind) => (
                <RadioItem
                  key={kind}
                  id={`scope-kind-${kind}`}
                  value={kind}
                  label={t(`admin.form.scope_${kind}`)}
                />
              ))}
            </RadioGroup>
          )}
        />
        {scopeKind !== 'all' && (
          <div className="mt-3">
            <Label htmlFor="promo-scopeIds">{scopeIdsLabel(scopeKind, t)}</Label>
            <Input
              id="promo-scopeIds"
              {...register('scopeIds')}
              className="mt-1"
              placeholder={
                scopeKind === 'vendor'
                  ? t('admin.form.scope_vendor_placeholder')
                  : t('admin.form.scope_ids_placeholder')
              }
            />
            <p className="mt-1 text-xs text-neutral-500">{t('admin.form.scope_ids_hint')}</p>
          </div>
        )}
      </fieldset>

      {/* ── Validity ── */}
      <fieldset className="border-border-default mb-6 rounded-lg border p-4">
        <legend className="px-1 text-sm font-medium text-neutral-700">
          {t('admin.form.validity_label')}
        </legend>
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
          <div>
            <Label htmlFor="promo-validFrom">{t('admin.form.from')}</Label>
            <Input
              id="promo-validFrom"
              type="datetime-local"
              {...register('validFrom')}
              className="mt-1"
            />
          </div>
          <div>
            <Label htmlFor="promo-validUntil">{t('admin.form.until')}</Label>
            <Input
              id="promo-validUntil"
              type="datetime-local"
              {...register('validUntil')}
              className="mt-1"
            />
          </div>
        </div>
      </fieldset>

      {/* ── Caps ── */}
      <fieldset className="border-border-default mb-6 rounded-lg border p-4">
        <legend className="px-1 text-sm font-medium text-neutral-700">
          {t('admin.form.caps_label')}
        </legend>
        <div className="grid grid-cols-2 gap-4 sm:grid-cols-4">
          <div>
            <Label htmlFor="promo-minSubtotal">{t('admin.form.min_subtotal_label')}</Label>
            <Controller
              name="minSubtotal"
              control={control}
              render={({ field }) => (
                <NumberInput
                  id="promo-minSubtotal"
                  min={0}
                  step={0.01}
                  className="mt-1"
                  value={field.value ? parseFloat(field.value) : 0}
                  onChange={(n) => field.onChange(n > 0 ? String(n) : '')}
                />
              )}
            />
          </div>
          <div>
            <Label htmlFor="promo-maxSubtotal">{t('admin.form.max_subtotal_label')}</Label>
            <Controller
              name="maxSubtotal"
              control={control}
              render={({ field }) => (
                <NumberInput
                  id="promo-maxSubtotal"
                  min={0}
                  step={0.01}
                  className="mt-1"
                  value={field.value ? parseFloat(field.value) : 0}
                  onChange={(n) => field.onChange(n > 0 ? String(n) : '')}
                />
              )}
            />
          </div>
          <div>
            <Label htmlFor="promo-totalCap">{t('admin.form.total_cap')}</Label>
            <Controller
              name="totalCap"
              control={control}
              render={({ field }) => (
                <NumberInput
                  id="promo-totalCap"
                  min={1}
                  step={1}
                  className="mt-1"
                  value={field.value ? parseInt(field.value, 10) : 0}
                  onChange={(n) => field.onChange(n > 0 ? String(n) : '')}
                />
              )}
            />
          </div>
          <div>
            <Label htmlFor="promo-perUserCap">{t('admin.form.per_user_cap')}</Label>
            <Controller
              name="perUserCap"
              control={control}
              render={({ field }) => (
                <NumberInput
                  id="promo-perUserCap"
                  min={1}
                  step={1}
                  className="mt-1"
                  value={field.value ? parseInt(field.value, 10) : 1}
                  onChange={(n) => field.onChange(String(n))}
                />
              )}
            />
          </div>
        </div>
      </fieldset>

      {/* ── Eligibility ── */}
      <fieldset className="border-border-default mb-6 rounded-lg border p-4">
        <legend className="px-1 text-sm font-medium text-neutral-700">
          {t('admin.form.eligibility_label')}
        </legend>
        <div className="flex flex-col gap-3">
          <Controller
            name="firstPurchaseOnly"
            control={control}
            render={({ field }) => (
              <label className="flex cursor-pointer items-center gap-2">
                <Checkbox
                  id="promo-firstPurchaseOnly"
                  checked={field.value ?? false}
                  onCheckedChange={(v) => field.onChange(Boolean(v))}
                />
                <span className="text-sm">{t('admin.form.first_purchase_only')}</span>
              </label>
            )}
          />
          <Controller
            name="clubOnly"
            control={control}
            render={({ field }) => (
              <label className="flex cursor-pointer items-center gap-2">
                <Checkbox
                  id="promo-clubOnly"
                  checked={field.value ?? false}
                  onCheckedChange={(v) => field.onChange(Boolean(v))}
                />
                <span className="text-sm">{t('admin.form.club_only')}</span>
              </label>
            )}
          />
          <div>
            <Label htmlFor="promo-userAllowlist">{t('admin.form.user_allowlist_label')}</Label>
            <Input
              id="promo-userAllowlist"
              {...register('userAllowlist')}
              className="mt-1"
              placeholder={t('admin.form.user_allowlist_placeholder')}
            />
            <p className="mt-1 text-xs text-neutral-500">{t('admin.form.user_allowlist_hint')}</p>
          </div>
        </div>
      </fieldset>

      {/* ── Actions ── */}
      <div className="border-border-default flex items-center justify-end gap-3 border-t pt-4">
        <Button asChild variant="ghost" size="md">
          <a href="/admin/promo-codes">{t('admin.form.cancel')}</a>
        </Button>
        <Button variant="primary" size="md" type="submit" loading={submitting}>
          {t('admin.form.submit')}
        </Button>
      </div>
    </form>
  );
}
