import { http, HttpResponse } from "msw";
import { z } from "zod";
import { RELANCE_TONES } from "@rubis/shared";

import { mockDb } from "../db";
import { userIdFromAuthHeader } from "./auth";

const apiBase = "*/api/v1";

function unauthenticated() {
  return HttpResponse.json(
    { errors: [{ code: "unauthenticated", message: "Non authentifié" }] },
    { status: 401 },
  );
}

const generateSchema = z.object({
  tone: z.enum(RELANCE_TONES),
  offsetDays: z.number().int().min(-30).max(180),
  prompt: z.string().max(1000).optional(),
  planName: z.string().max(80).optional(),
  planDescription: z.string().max(500).optional(),
});

/**
 * Mock de Mistral pour le dev sans clé API. Renvoie un template plausible
 * en fonction du ton et du timing. Le wording n'est pas calibré pour la
 * prod — c'est juste pour valider l'UX du wizard sans coût.
 */
function mockGenerate(
  tone: z.infer<typeof generateSchema>["tone"],
  _offsetDays: number,
  prompt: string,
): { subject: string; body: string } {
  const briefSuffix = prompt.trim() ? ` (${prompt.trim().slice(0, 60)}…)` : "";
  switch (tone) {
    case "amical":
      return {
        subject: "Petit rappel — facture {{numero}}",
        body: [
          "Bonjour {{client.contactFirstName}},",
          "",
          `J'espère que tout va bien chez {{client.name}}. Un petit rappel concernant la facture {{numero}} d'un montant de {{amount}}, échue le {{dueDate}}.${briefSuffix}`,
          "",
          "Si le règlement est déjà parti, n'en tenez pas compte. Sinon, merci d'avance.",
          "",
          "{{signature}}",
        ].join("\n"),
      };
    case "courtois":
      return {
        subject: "Relance — facture {{numero}} en attente de règlement",
        body: [
          "Bonjour {{client.contactFirstName}},",
          "",
          `Sauf erreur de notre part, la facture {{numero}} d'un montant de {{amount}} émise le {{issueDate}} reste impayée à ce jour ({{daysLate}} jours de retard).${briefSuffix}`,
          "",
          "Merci de procéder au règlement dans les meilleurs délais.",
          "",
          "{{signature}}",
        ].join("\n"),
      };
    case "ferme":
      return {
        subject: "Relance ferme — facture {{numero}}",
        body: [
          "Bonjour,",
          "",
          `Malgré nos précédentes relances, la facture {{numero}} d'un montant de {{amount}} reste impayée. Le retard atteint aujourd'hui {{daysLate}} jours.${briefSuffix}`,
          "",
          "Nous vous demandons de régulariser cette situation sous 8 jours afin d'éviter une mise en demeure formelle.",
          "",
          "{{signature}}",
        ].join("\n"),
      };
    case "mise_en_demeure":
      return {
        subject: "Mise en demeure — facture {{numero}}",
        body: [
          "Madame, Monsieur,",
          "",
          `Par la présente, nous vous mettons en demeure de procéder, sous 8 jours, au règlement de la facture {{numero}} d'un montant de {{amount}}, émise le {{issueDate}} et échue depuis {{daysLate}} jours.${briefSuffix}`,
          "",
          "À défaut, nous nous réservons le droit d'engager toute procédure utile à la préservation de nos droits, en ce compris la voie judiciaire, et de réclamer les pénalités de retard ainsi que l'indemnité forfaitaire pour frais de recouvrement prévues par la loi.",
          "",
          "{{signature}}",
        ].join("\n"),
      };
  }
}

export const aiHandlers = [
  // POST /api/v1/ai/generate-relance — génération d'un template
  http.post(`${apiBase}/ai/generate-relance`, async ({ request }) => {
    const userId = userIdFromAuthHeader(request.headers.get("authorization"));
    if (!userId || !mockDb.findUserById(userId)) return unauthenticated();

    const json = await request.json();
    const parsed = generateSchema.safeParse(json);
    if (!parsed.success) {
      return HttpResponse.json(
        {
          errors: parsed.error.issues.map((i) => ({
            code: "validation_failed",
            message: i.message,
            field: i.path.join("."),
          })),
        },
        { status: 422 },
      );
    }

    // Latence simulée pour que le spinner soit visible.
    await new Promise((r) => setTimeout(r, 600));
    const result = mockGenerate(parsed.data.tone, parsed.data.offsetDays, parsed.data.prompt ?? "");
    return HttpResponse.json({ data: result });
  }),
];
