import type { TicketIntake } from '@wa-ticketing/shared';
import {
  HUMAN_CONFIRM_CLARIFY,
  HUMAN_DECLINED_REPLY,
  HUMAN_ESCALATED_REPLY,
} from '@wa-ticketing/shared';
import { sql } from '../db.js';
import { auditService } from './auditService.js';
import {
  isUnableToAssistReply,
  matchesDirectHumanRequest,
  matchesHumanConfirmNo,
  matchesHumanConfirmYes,
} from './humanRequestPhrases.js';

export {
  isUnableToAssistReply,
  matchesDirectHumanRequest,
  matchesHumanConfirmNo,
  matchesHumanConfirmYes,
} from './humanRequestPhrases.js';

async function persistIntake(ticketId: string, intake: TicketIntake, escalate: boolean): Promise<void> {
  if (escalate) {
    await sql`
      UPDATE tickets
      SET intake = ${sql.json(intake as never)},
          needs_escalation = true,
          updated_at = NOW()
      WHERE id = ${ticketId}
    `;
    await auditService.log(null, 'system', 'ticket.human_requested', 'ticket', ticketId, {});
  } else {
    await sql`
      UPDATE tickets
      SET intake = ${sql.json(intake as never)}, updated_at = NOW()
      WHERE id = ${ticketId}
    `;
  }
}

export type HumanInboundResult = {
  handled: boolean;
  intake: TicketIntake;
  outbound: string | null;
  escalated: boolean;
  intakeChanged: boolean;
};

/**
 * Phrase match on inbound text: direct human request, yes/no after AI prompt, or suppress talkback.
 */
export async function processHumanRequestInbound(opts: {
  ticketId: string;
  inboundText: string;
  intake: TicketIntake;
}): Promise<HumanInboundResult> {
  const text = opts.inboundText.trim();
  const base = { handled: false as const, intake: opts.intake, outbound: null as string | null, escalated: false, intakeChanged: false };

  if (!text) return base;

  if (opts.intake.suppress_talkback) {
    return { ...base, handled: true };
  }

  if (opts.intake.awaiting_human_confirm) {
    if (matchesHumanConfirmYes(text)) {
      const intake: TicketIntake = {
        ...opts.intake,
        awaiting_human_confirm: false,
        suppress_talkback: true,
      };
      await persistIntake(opts.ticketId, intake, true);
      return {
        handled: true,
        intake,
        outbound: HUMAN_ESCALATED_REPLY,
        escalated: true,
        intakeChanged: true,
      };
    }
    if (matchesHumanConfirmNo(text)) {
      const intake: TicketIntake = { ...opts.intake, awaiting_human_confirm: false };
      await persistIntake(opts.ticketId, intake, false);
      return {
        handled: true,
        intake,
        outbound: HUMAN_DECLINED_REPLY,
        escalated: false,
        intakeChanged: true,
      };
    }
    return {
      handled: true,
      intake: opts.intake,
      outbound: HUMAN_CONFIRM_CLARIFY,
      escalated: false,
      intakeChanged: false,
    };
  }

  if (matchesDirectHumanRequest(text)) {
    const intake: TicketIntake = {
      ...opts.intake,
      awaiting_human_confirm: false,
      suppress_talkback: true,
    };
    await persistIntake(opts.ticketId, intake, true);
    return {
      handled: true,
      intake,
      outbound: HUMAN_ESCALATED_REPLY,
      escalated: true,
      intakeChanged: true,
    };
  }

  return base;
}

export async function markAwaitingHumanConfirm(ticketId: string, intake: TicketIntake): Promise<TicketIntake> {
  const next: TicketIntake = { ...intake, awaiting_human_confirm: true };
  await persistIntake(ticketId, next, false);
  return next;
}
