/**
 * Group deal lifecycle — single-entity deadline + partial-timeout logic.
 *
 * Called by GroupDealDO.alarm(). Two alarm kinds:
 *   'deadline'          — group deal window/extendedDeadline has passed
 *   'partial_decision'  — vendor 24h decision window expired
 *
 * Deps shape: { db, payments, push, qrSecret } — mirrors GroupDealDeps from workflow.
 * No cloudflare:workers imports.
 */

import type { DoTxDbClient } from '../lib/db.js';
import type { PushClient } from '@/server/push/types';
import type { DoClient } from '@/server/services/types';
import type { GroupDealDeps } from '@/server/workflows/group-deal';

export interface GroupDealAlarmDeps {
  db: DoTxDbClient;
  push: PushClient;
  qrSecret: string;
  doClient: DoClient;
  payments: GroupDealDeps['payments'];
  storage: GroupDealDeps['storage'];
}

/**
 * Handle group deal deadline expiry for a single groupDealId.
 * Mirrors runGroupDealDeadline logic scoped to one row.
 */
export async function handleGroupDealDeadline(
  deps: GroupDealAlarmDeps,
  groupDealId: string,
): Promise<void> {
  const { executeGroupDeal, failGroupDeal, handlePartialExecution } =
    await import('@/server/workflows/group-deal');

  const row = await deps.db.query.groupDeals.findFirst({
    where: (gd, { eq }) => eq(gd.id, groupDealId),
  });

  if (!row) {
    return;
  }

  if (!['COLLECTING', 'THRESHOLD_MET', 'EXTENDED'].includes(row.groupState)) {
    // Already transitioned — alarm fired late or duplicate
    return;
  }

  const wfDeps: GroupDealDeps = {
    db: deps.db,
    push: deps.push,
    qrSecret: deps.qrSecret,
    doClient: deps.doClient,
    payments: deps.payments,
    storage: deps.storage,
  };

  if (row.currentReservationCount >= row.minGroupSize) {
    await executeGroupDeal(wfDeps, groupDealId);
  } else {
    if (row.fillRule === 'ALL_OR_NOTHING') {
      await failGroupDeal(wfDeps, groupDealId);
    } else {
      await handlePartialExecution(wfDeps, groupDealId);
    }
  }
}

/**
 * Handle group deal partial-decision timeout for a single groupDealId.
 * Mirrors runGroupPartialTimeout logic scoped to one row.
 */
export async function handleGroupPartialTimeout(
  deps: GroupDealAlarmDeps,
  groupDealId: string,
): Promise<void> {
  const { failGroupDeal } = await import('@/server/workflows/group-deal');

  const row = await deps.db.query.groupDeals.findFirst({
    where: (gd, { eq }) => eq(gd.id, groupDealId),
  });

  if (!row || row.groupState !== 'PARTIAL_PENDING') {
    return;
  }

  const wfDeps: GroupDealDeps = {
    db: deps.db,
    push: deps.push,
    qrSecret: deps.qrSecret,
    doClient: deps.doClient,
    payments: deps.payments,
    storage: deps.storage,
  };
  await failGroupDeal(wfDeps, groupDealId);
}
