/**
 * Personal deal request queries.
 *
 * Entity-alarm law (§7): requestPersonalDeal arms the PersonalOfferDO alarm.
 * Cancelling/accepting/rejecting disarms it.
 */

import { eq, and } from 'drizzle-orm';
import type { DrizzleClient } from '../client.js';
import { personalDealRequests } from '../schema.js';
import type { ServiceBundle } from '@/server/services/types.js';
import { captureCaught } from '@/server/observability/capture.server.js';

export async function findById(db: DrizzleClient, id: string) {
  const [row] = await db
    .select()
    .from(personalDealRequests)
    .where(eq(personalDealRequests.id, id))
    .limit(1);
  return row ?? null;
}

/**
 * Create a new personal deal request.
 * Alarm arming is handled at the API route callsite (POST /api/personal-deals).
 */
export async function createPersonalDealRequest(
  db: DrizzleClient,
  _services: Pick<ServiceBundle, 'doClient'>,
  input: {
    userId: string;
    vendorId: string;
    sourceDealId: string;
    responseDeadline: Date;
  },
) {
  const [row] = await db
    .insert(personalDealRequests)
    .values({
      userId: input.userId,
      vendorId: input.vendorId,
      sourceDealId: input.sourceDealId,
      status: 'PENDING',
      responseDeadline: input.responseDeadline,
    })
    .returning();
  return row!;
}

/**
 * Expire a personal deal request — disarm alarm.
 */
export async function expirePersonalDealRequest(
  db: DrizzleClient,
  services: Pick<ServiceBundle, 'doClient'>,
  id: string,
) {
  const [row] = await db
    .update(personalDealRequests)
    .set({ status: 'EXPIRED' })
    .where(and(eq(personalDealRequests.id, id), eq(personalDealRequests.status, 'PENDING')))
    .returning();
  if (row) {
    try {
      await services.doClient.disarmPersonalOfferAlarm(id);
    } catch (err) {
      captureCaught(err, { scope: 'disarmPersonalOfferAlarm.expire', extra: { requestId: id } });
    }
  }
  return row ?? null;
}

/**
 * Accept a personal deal request — disarm alarm (vendor responded in time).
 */
export async function acceptPersonalDealRequest(
  db: DrizzleClient,
  services: Pick<ServiceBundle, 'doClient'>,
  id: string,
  createdDealId: string,
) {
  const [row] = await db
    .update(personalDealRequests)
    .set({ status: 'ACCEPTED', respondedAt: new Date(), createdDealId })
    .where(and(eq(personalDealRequests.id, id), eq(personalDealRequests.status, 'PENDING')))
    .returning();
  if (row) {
    try {
      await services.doClient.disarmPersonalOfferAlarm(id);
    } catch (err) {
      captureCaught(err, { scope: 'disarmPersonalOfferAlarm.accept', extra: { requestId: id } });
    }
  }
  return row ?? null;
}

/**
 * Reject a personal deal request — disarm alarm.
 */
export async function rejectPersonalDealRequest(
  db: DrizzleClient,
  services: Pick<ServiceBundle, 'doClient'>,
  id: string,
) {
  const [row] = await db
    .update(personalDealRequests)
    .set({ status: 'REJECTED', respondedAt: new Date() })
    .where(and(eq(personalDealRequests.id, id), eq(personalDealRequests.status, 'PENDING')))
    .returning();
  if (row) {
    try {
      await services.doClient.disarmPersonalOfferAlarm(id);
    } catch (err) {
      captureCaught(err, { scope: 'disarmPersonalOfferAlarm.reject', extra: { requestId: id } });
    }
  }
  return row ?? null;
}
