import { eq } from 'drizzle-orm';
import type { DrizzleClient } from '@/server/db/client.js';
import { reportTickets } from '@/server/db/schema.js';
import { ReportError } from './errors.js';
import type {
  CreateReportTicketInput,
  CreateReportTicketResult,
  DismissReportInput,
  MarkInvestigatingInput,
  ResolveReportInput,
} from './types.js';
import { recordAdminAction } from '@/server/db/queries/admin-actions.js';
import {
  createReportTicketRecord,
  updateReportTicketStatus,
} from '@/server/db/queries/report-tickets.js';

const TARGET_TYPE_MAP: Record<string, 'DEAL' | 'VENDOR' | 'REVIEW' | 'USER'> = {
  DEAL: 'DEAL',
  VENDOR: 'VENDOR',
  REVIEW: 'REVIEW',
  USER: 'USER',
};

export async function createReportTicket(
  db: DrizzleClient,
  input: CreateReportTicketInput,
): Promise<CreateReportTicketResult> {
  const row = await createReportTicketRecord(db, {
      reporterUserId: input.reporterUserId ?? undefined,
      targetType: input.targetType,
      targetId: input.targetId,
      reason: input.reason,
      body: input.body ?? '',
      status: 'OPEN',
    });
  return { id: row.id };
}

async function loadOpenReport(db: DrizzleClient, reportId: string) {
  const [report] = await db
    .select({
      id: reportTickets.id,
      status: reportTickets.status,
      targetType: reportTickets.targetType,
      targetId: reportTickets.targetId,
    })
    .from(reportTickets)
    .where(eq(reportTickets.id, reportId))
    .limit(1);
  if (!report) throw new ReportError('NOT_FOUND', 'Report ticket not found');
  if (report.status === 'RESOLVED' || report.status === 'DISMISSED') {
    throw new ReportError('INVALID_STATE', `Report is already ${report.status}`);
  }
  return report;
}

export async function resolveReport(
  deps: { db: DrizzleClient },
  input: ResolveReportInput,
): Promise<void> {
  const report = await loadOpenReport(deps.db, input.reportId);
  await updateReportTicketStatus(deps.db, input.reportId, 'RESOLVED', new Date());
  await recordAdminAction(deps.db, {
    adminId: input.adminId,
    targetType: TARGET_TYPE_MAP[report.targetType] ?? 'DEAL',
    targetId: report.targetId,
    action: 'APPROVE',
    note: input.resolution,
  });
}

export async function dismissReport(
  deps: { db: DrizzleClient },
  input: DismissReportInput,
): Promise<void> {
  const report = await loadOpenReport(deps.db, input.reportId);
  await updateReportTicketStatus(deps.db, input.reportId, 'DISMISSED', new Date());
  await recordAdminAction(deps.db, {
    adminId: input.adminId,
    targetType: TARGET_TYPE_MAP[report.targetType] ?? 'DEAL',
    targetId: report.targetId,
    action: 'REJECT',
    note: input.note ?? 'Report dismissed',
  });
}

export async function markInvestigating(
  deps: { db: DrizzleClient },
  input: MarkInvestigatingInput,
): Promise<void> {
  const report = await loadOpenReport(deps.db, input.reportId);
  await updateReportTicketStatus(deps.db, input.reportId, 'INVESTIGATING');
  await recordAdminAction(deps.db, {
    adminId: input.adminId,
    targetType: TARGET_TYPE_MAP[report.targetType] ?? 'DEAL',
    targetId: report.targetId,
    action: 'APPROVE',
    note: 'Report marked as investigating',
  });
}
