import { z } from 'zod';
import * as caseQ from '@/server/db/queries/support-cases.js';
import * as offersQ from '@/server/db/queries/case-offers.js';
import * as transitionsQ from '@/server/db/queries/support-state-transitions.js';
import * as messagesQ from '@/server/db/queries/support-messages.js';
import type { SupportTool, ToolResult } from './_types.js';
import type { AgentDeps } from '../types.js';
import { asCaseId } from '@/server/platform-seams/ids.js';

const inputSchema = z.object({
  caseId: z.uuid(),
  amountCents: z.number().int().positive(),
  reason: z.string().min(1).max(1000),
});

type Output = { offerId: string };

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 { amountCents, reason } = parsed.data;
  const caseId = asCaseId(parsed.data.caseId);

  const c = await caseQ.findById(deps.db, caseId);
  if (!c) return { ok: false, error: 'NOT_FOUND:case' };
  if (c.status !== 'ai_handling') {
    return { ok: false, error: 'AUTONOMY_GATE:status_not_ai_handling' };
  }
  const existing = await offersQ.listByCase(deps.db, caseId);
  for (const offer of existing.filter((candidate) => candidate.status === 'pending')) {
    await offersQ.markSuperseded(deps.db, offer.id);
  }

  const offer = await offersQ.insert(deps.db, {
    caseId,
    offeredBy: 'ai',
    outcome: 'refund_partial',
    amountCents,
    reason,
    status: 'pending',
  });

  await transitionsQ.insert(deps.db, {
    parentType: 'case',
    parentId: caseId,
    fromState: c.status,
    toState: c.status,
    actorType: 'ai',
    actorId: null,
    reason: 'propose_refund',
    metadata: {
      offerId: offer.id,
      amountCents,
      reason,
      confidence: deps.runState.currentConfidence,
    },
  });

  await messagesQ.insertEncrypted(
    deps.db,
    {
      parentType: 'case',
      parentId: caseId,
      authorType: 'ai',
      authorId: null,
      visibility: 'public',
    },
    'A refund proposal has been submitted for approval.',
    deps.piiKey,
  );

  deps.runState.decision = 'propose';

  return { ok: true, data: { offerId: offer.id } };
}

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