/**
 * useGroupReservation - react-hook-form + mutation for joining a group deal (FDS §PKG-7).
 *
 * Validates with Zod against joinGroupDealBodySchema, then posts to
 * POST /api/group-deals/[id]/reserve.
 */

'use client';

import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { captureCaught } from '@/lib/observability';
import { joinGroupDealBodySchema as serverJoinSchema } from '@/server/schemas/group-deal';
import { useAuthGateStore } from '@/lib/stores/auth-gate';
import { authenticatedFetch } from '@/lib/authenticated-fetch';

// ─── Schema ───────────────────────────────────────────────────────────────────

// Form fields only — idempotencyKey is generated at submit time, not a user field.
export const joinGroupDealFormSchema = z.object({
  quantity: z.number({ error: 'Enter a number' }).int().min(1, 'Quantity must be at least 1'),
  paymentMethodId: z.uuid(),
});

// Re-export server schema as the authoritative body schema so callers stay in sync.
export { serverJoinSchema as joinGroupDealBodySchema };

export type JoinGroupDealFormValues = z.infer<typeof joinGroupDealFormSchema>;

// ─── Options ──────────────────────────────────────────────────────────────────

export interface UseGroupReservationOptions {
  groupDealId: string;
  /** Maximum units per customer (from group.perCustomerLimit). */
  maxQuantity?: number;
  /** Called on successful reservation. Receives the new reservation id. */
  onSuccess?: (reservationId: string) => void;
}

// ─── Return type ──────────────────────────────────────────────────────────────

export interface UseGroupReservationReturn {
  form: ReturnType<typeof useForm<JoinGroupDealFormValues>>;
  serverError: string | null;
  successId: string | null;
  onSubmit: (e?: React.BaseSyntheticEvent) => Promise<void>;
}

// ─── Hook ─────────────────────────────────────────────────────────────────────

export function useGroupReservation({
  groupDealId,
  maxQuantity,
  onSuccess,
}: UseGroupReservationOptions): UseGroupReservationReturn {
  const [serverError, setServerError] = useState<string | null>(null);
  const [successId, setSuccessId] = useState<string | null>(null);

  const schema = maxQuantity
    ? joinGroupDealFormSchema.extend({
        quantity: z
          .number({ error: 'Enter a number' })
          .int()
          .min(1, 'Quantity must be at least 1')
          .max(maxQuantity, `Maximum quantity is ${maxQuantity}`),
      })
    : joinGroupDealFormSchema;

  const form = useForm<JoinGroupDealFormValues>({
    resolver: zodResolver(schema),
    defaultValues: {
      quantity: 1,
      paymentMethodId: '',
    },
  });

  async function onSubmitHandler(values: JoinGroupDealFormValues) {
    setServerError(null);
    try {
      const res = await authenticatedFetch(`/api/group-deals/${groupDealId}/reserve`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ...values, idempotencyKey: crypto.randomUUID() }),
        credentials: 'same-origin',
      });

      const data = (await res.json()) as {
        ok: boolean;
        reservation?: { id: string };
        error?: string;
        code?: string;
      };

      if (!data.ok) {
        if (data.code === 'AUTH_REQUIRED') {
          useAuthGateStore.getState().triggerAuth(() => void onSubmitHandler(values));
          return;
        }
        setServerError(data.error ?? 'Reservation failed. Please try again.');
        return;
      }

      const id = data.reservation?.id ?? '';
      setSuccessId(id);
      onSuccess?.(id);
    } catch (err) {
      captureCaught(err, {
        scope: 'features.group-reservation-flow.useGroupReservation',
        severity: 'warning',
      });
      setServerError('Network error. Please try again.');
    }
  }

  return {
    form,
    serverError,
    successId,
    onSubmit: form.handleSubmit(onSubmitHandler),
  };
}
