import { eq } from 'drizzle-orm';
import type { TxDrizzleClient } from '../../client';
import { supportTickets, transactionCases, supportStateTransitions } from '../../schema';
import { asCaseId } from '@/server/platform-seams/ids.js';
import { insertOutboxRow } from '../outbox.js';
import type { CaseCategory, CaseStatus, TicketState } from '@/server/domain/support-case/events.js';
import type { SupportTicketRow } from '../support-tickets.js';

export type SupportParentType = 'ticket' | 'case';
export type TicketCategory = SupportTicketRow['category'];
export type SetCategoryInput =
  | { parentType: 'ticket'; parentId: string; category: TicketCategory }
  | { parentType: 'case'; parentId: string; category: CaseCategory };
export type EscalateInput =
  | { parentType: 'ticket'; parentId: string; fromState: TicketState; reason: string }
  | { parentType: 'case'; parentId: string; fromState: CaseStatus; reason: string };

export async function setPriority(
  db: TxDrizzleClient,
  id: string,
  level: 'low' | 'normal' | 'high' | 'urgent',
): Promise<void> {
  await db
    .update(supportTickets)
    .set({ priority: level, updatedAt: new Date() })
    .where(eq(supportTickets.id, id));
}

export async function setCategory(db: TxDrizzleClient, input: SetCategoryInput): Promise<void> {
  if (input.parentType === 'ticket') {
    await db
      .update(supportTickets)
      .set({ category: input.category, updatedAt: new Date() })
      .where(eq(supportTickets.id, input.parentId));
    return;
  }
  await db
    .update(transactionCases)
    .set({ category: input.category, updatedAt: new Date() })
    .where(eq(transactionCases.id, asCaseId(input.parentId)));
}

export async function closeTicket(
  db: TxDrizzleClient,
  id: string,
  fromState: SupportTicketRow['status'],
  resolution: string,
  metadata: Record<string, unknown>,
): Promise<void> {
  const now = new Date();
  await db
    .update(supportTickets)
    .set({
      status: 'resolved',
      resolvedAt: now,
      updatedAt: now,
      metadata: { ...metadata, resolution, resolvedByAi: true },
    })
    .where(eq(supportTickets.id, id));
  await db.insert(supportStateTransitions).values({
    parentType: 'ticket',
    parentId: id,
    fromState,
    toState: 'resolved',
    actorType: 'ai',
    actorId: null,
    reason: resolution,
    metadata: {},
  });
}

export async function escalate(db: TxDrizzleClient, input: EscalateInput): Promise<void> {
  if (input.parentType === 'ticket') {
    await db
      .update(supportTickets)
      .set({ status: 'awaiting_agent', updatedAt: new Date() })
      .where(eq(supportTickets.id, input.parentId));
    await db.insert(supportStateTransitions).values({
      parentType: 'ticket',
      parentId: input.parentId,
      fromState: input.fromState,
      toState: 'awaiting_agent',
      actorType: 'ai',
      actorId: null,
      reason: input.reason,
      metadata: {},
    });
    await insertOutboxRow(db, {
      aggregateType: 'ticket',
      aggregateId: input.parentId,
      eventType: 'support.notif.email',
      payload: {
        ticketId: input.parentId,
        templateKey: 'escalated_to_human',
        recipients: ['site_support'],
      },
    });
    return;
  }
  await db
    .update(transactionCases)
    .set({ status: 'human_review', updatedAt: new Date() })
    .where(eq(transactionCases.id, asCaseId(input.parentId)));
  await db.insert(supportStateTransitions).values({
    parentType: 'case',
    parentId: input.parentId,
    fromState: input.fromState,
    toState: 'human_review',
    actorType: 'ai',
    actorId: null,
    reason: input.reason,
    metadata: {},
  });
  await insertOutboxRow(db, {
    aggregateType: 'case',
    aggregateId: input.parentId,
    eventType: 'support.notif.email',
    payload: {
      caseId: input.parentId,
      templateKey: 'escalated_to_human',
      recipients: ['customer', 'vendor', 'site_support'],
    },
  });
}
