import { inArray } from 'drizzle-orm';
import type { DrizzleClient } from '@/server/db/client.js';
import { deals } from '@/server/db/schema.js';
import type { PromoFunder } from '@/lib/enums/promo-funder';
import type { PromoRules } from './types.js';

export type VendorMintError =
  | { code: 'SCOPE_ALL_FORBIDDEN' }
  | { code: 'VENDOR_MISMATCH' }
  | { code: 'DEAL_NOT_OWNED'; dealId: string }
  | { code: 'FUNDER_MUST_BE_VENDOR' };

/** Returns clamped rulesJson + clamped vendorId, OR an error code. */
export async function clampVendorMint(
  db: DrizzleClient,
  sessionVendorId: string,
  input: {
    funder: PromoFunder;
    vendorId?: string | null;
    rulesJson: PromoRules;
  },
): Promise<
  { ok: true; vendorId: string; rulesJson: PromoRules } | { ok: false; error: VendorMintError }
> {
  if (input.funder !== 'vendor') return { ok: false, error: { code: 'FUNDER_MUST_BE_VENDOR' } };

  // Server clamps vendor_id to the session — never trust client-supplied value.
  const clampedVendorId = sessionVendorId;

  const scope = input.rulesJson.scope;
  if (scope.kind === 'all') return { ok: false, error: { code: 'SCOPE_ALL_FORBIDDEN' } };
  if (scope.kind === 'vendor' && scope.vendorId !== sessionVendorId) {
    return { ok: false, error: { code: 'VENDOR_MISMATCH' } };
  }
  if (scope.kind === 'deals') {
    const rows = await db
      .select({ id: deals.id, vendorId: deals.vendorId })
      .from(deals)
      .where(inArray(deals.id, scope.dealIds));
    const foreign = rows.find((r) => r.vendorId !== sessionVendorId);
    if (foreign) return { ok: false, error: { code: 'DEAL_NOT_OWNED', dealId: foreign.id } };
    const missing = scope.dealIds.find((id) => !rows.some((r) => r.id === id));
    if (missing) return { ok: false, error: { code: 'DEAL_NOT_OWNED', dealId: missing } };
  }
  // For categories/tags scopes, resolver already filters lines by vendor at redemption time.

  return {
    ok: true,
    vendorId: clampedVendorId,
    rulesJson:
      scope.kind === 'vendor'
        ? { ...input.rulesJson, scope: { kind: 'vendor', vendorId: sessionVendorId } }
        : input.rulesJson,
  };
}
