import type { components } from '@alqove/types';
import type { AlqoveClient } from '../client';

/**
 * The check-in response schemas carry their own `{ data: ... }` envelope (they
 * mirror the API's response wrapper). We expose both the envelope type and the
 * inner payload type so callers can read `res.data` and pass the flat object on.
 */
export type CheckinBranding = components['schemas']['CheckinBranding'];
export type CheckinBrandingData = CheckinBranding['data'];
export type CheckinAccepted = components['schemas']['CheckinAccepted'];
export type CheckinAcceptedData = CheckinAccepted['data'];
export type CheckinStatus = components['schemas']['CheckinStatus'];
export type CheckinStatusData = CheckinStatus['data'];
/** Per-store status-page mode (lives on branding; absent from the status read). */
export type CheckinStatusVisibility = NonNullable<
  CheckinBrandingData['status_visibility']
>;

/**
 * Fields the customer fills in. The stable `idempotency_key` and the
 * `turnstile_token` are supplied separately via `submit`'s options so the key
 * can stay stable across retries (it goes in BOTH the body and the
 * `Idempotency-Key` header, which the API enforces equal).
 */
export interface CheckinSubmitPayload {
  phone: string;
  first_name: string;
  last_name: string;
  container_count: number;
  container_description?: string | null;
  opt_loyalty: boolean;
  opt_txn: boolean;
  opt_promo: boolean;
}

export interface CheckinSubmitOptions {
  /** Stable client-generated UUID; sent in the body AND the header. */
  idempotencyKey: string;
  /** Cloudflare Turnstile token; verified server-side. */
  turnstileToken: string;
  /**
   * Optional logged-in bearer. When present, the buy attaches to that user.
   * The public endpoint never 401s on its absence (optional auth).
   */
  authToken?: string;
}

/**
 * Public, anonymous check-in lane endpoints. Unlike the buyer endpoints, these
 * never require auth — `submit` only attaches a bearer when one is explicitly
 * passed. Build this off a client whose `getToken` may legitimately return null.
 */
export function createCheckinEndpoints(client: AlqoveClient) {
  return {
    getBranding: (token: string) =>
      client.get<CheckinBranding>(`/v1/checkin/${token}`),

    submit: (
      token: string,
      payload: CheckinSubmitPayload,
      { idempotencyKey, turnstileToken, authToken }: CheckinSubmitOptions,
    ) =>
      client.post<CheckinAccepted>(
        `/v1/checkin/${token}/requests`,
        {
          ...payload,
          idempotency_key: idempotencyKey,
          turnstile_token: turnstileToken,
        },
        {
          // The API enforces header == body key; keep them identical and stable
          // across retries (no random regeneration — see Task 0).
          headers: { 'Idempotency-Key': idempotencyKey },
          authToken,
        },
      ),

    getStatus: (statusToken: string) =>
      client.get<CheckinStatus>(`/v1/checkin/status/${statusToken}`),
  };
}
