import { eq, and, inArray } from 'drizzle-orm';
import type { DrizzleClient } from '../client';
import { caseOffers } from '../schema';
import type { InferInsertModel, InferSelectModel } from 'drizzle-orm';
import { asCaseId } from '../../platform-seams/ids';

export type CaseOfferRow = InferSelectModel<typeof caseOffers>;
export type NewCaseOffer = InferInsertModel<typeof caseOffers>;

export async function insert(db: DrizzleClient, values: NewCaseOffer): Promise<CaseOfferRow> {
  const [row] = await db.insert(caseOffers).values(values).returning();
  return row!;
}

export async function listByCase(db: DrizzleClient, caseId: string): Promise<CaseOfferRow[]> {
  return db
    .select()
    .from(caseOffers)
    .where(eq(caseOffers.caseId, asCaseId(caseId)));
}

export async function findById(db: DrizzleClient, id: string): Promise<CaseOfferRow | null> {
  const rows = await db.select().from(caseOffers).where(eq(caseOffers.id, id)).limit(1);
  return rows[0] ?? null;
}

/** Atomic accept: UPDATE … WHERE status='pending' RETURNING. Returns null if already decided. */
export async function tryAccept(db: DrizzleClient, id: string): Promise<CaseOfferRow | null> {
  const rows = await db
    .update(caseOffers)
    .set({ status: 'accepted', decidedAt: new Date() })
    .where(and(eq(caseOffers.id, id), eq(caseOffers.status, 'pending')))
    .returning();
  return rows[0] ?? null;
}

/** Atomic accept for an AI refund offer bound to one case. */
export async function tryAcceptAiRefund(
  db: DrizzleClient,
  input: { id: string; caseId: string },
): Promise<CaseOfferRow | null> {
  const rows = await db
    .update(caseOffers)
    .set({ status: 'accepted', decidedAt: new Date() })
    .where(
      and(
        eq(caseOffers.id, input.id),
        eq(caseOffers.caseId, asCaseId(input.caseId)),
        eq(caseOffers.offeredBy, 'ai'),
        eq(caseOffers.status, 'pending'),
        inArray(caseOffers.outcome, ['refund_full', 'refund_partial']),
      ),
    )
    .returning();
  return rows[0] ?? null;
}

export async function markRejected(db: DrizzleClient, id: string): Promise<void> {
  await db
    .update(caseOffers)
    .set({ status: 'rejected', decidedAt: new Date() })
    .where(and(eq(caseOffers.id, id), eq(caseOffers.status, 'pending')));
}

export async function markSuperseded(db: DrizzleClient, id: string): Promise<void> {
  await db.update(caseOffers).set({ status: 'superseded' }).where(eq(caseOffers.id, id));
}
