import { z } from 'zod';
import * as ticketQ from '@/server/db/queries/support-tickets.js';
import * as caseQ from '@/server/db/queries/support-cases.js';
import * as interventionsQ from '@/server/db/queries/ai-interventions.js';
import * as actionsQ from '@/server/db/queries/support/ai-actions.js';
import type { SupportTool, ToolResult } from './_types.js';
import type { AgentDeps } from '../types.js';

const inputSchema = z.object({
  parentType: z.enum(['ticket', 'case']),
  parentId: z.uuid(),
  reason: z.string().min(1).max(500),
  confidence: z.number().min(0).max(1),
});

type Output = { escalated: true };

const AGENT_NAME = 'support_agent' as const;

async function impl(deps: AgentDeps, rawInput: unknown): Promise<ToolResult<Output>> {
  const parsed = inputSchema.safeParse(rawInput);
  if (!parsed.success) return { ok: false, error: `INVALID_INPUT:${parsed.error.message}` };

  const { parentType, parentId, reason } = parsed.data;

  if (parentType === 'ticket') {
    const ticket = await ticketQ.findById(deps.db, parentId);
    if (!ticket) return { ok: false, error: 'NOT_FOUND:ticket' };

    await deps.db.transaction(async (tx) => {
      await actionsQ.escalate(tx, {
        parentType: 'ticket',
        parentId,
        fromState: ticket.status,
        reason,
      });
      await interventionsQ.insertEncrypted(
        tx,
        {
          parentType,
          parentId,
          agentName: AGENT_NAME,
          toolName: 'escalate_to_human',
          confidence: String(parsed.data.confidence),
          decision: 'escalate',
          tokensIn: null,
          tokensOut: null,
          latencyMs: null,
          costUsd: null,
        },
        JSON.stringify({ reason }),
        JSON.stringify({ escalated: true }),
        deps.piiKey,
      );
    });
  } else {
    const c = await caseQ.findById(deps.db, parentId);
    if (!c) return { ok: false, error: 'NOT_FOUND:case' };

    await deps.db.transaction(async (tx) => {
      await actionsQ.escalate(tx, { parentType: 'case', parentId, fromState: c.status, reason });
      await interventionsQ.insertEncrypted(
        tx,
        {
          parentType,
          parentId,
          agentName: AGENT_NAME,
          toolName: 'escalate_to_human',
          confidence: String(parsed.data.confidence),
          decision: 'escalate',
          tokensIn: null,
          tokensOut: null,
          latencyMs: null,
          costUsd: null,
        },
        JSON.stringify({ reason }),
        JSON.stringify({ escalated: true }),
        deps.piiKey,
      );
    });
  }

  deps.runState.decision = 'escalate';

  return { ok: true, data: { escalated: true } };
}

export const escalateToHumanTool = {
  name: 'escalate_to_human',
  inputSchema,
  impl,
} satisfies SupportTool<'escalate_to_human', z.infer<typeof inputSchema>, Output>;
