import { NextResponse } from "next/server";
import { ZodError, type ZodIssue } from "zod";

function formatIssueMessage(issue: ZodIssue) {
  const field = issue.path.join(".");

  switch (field) {
    case "userMessage":
      if (issue.code === "too_small") {
        return "Votre message ne peut pas etre vide.";
      }

      if (issue.code === "too_big" && "maximum" in issue) {
        return `Votre message depasse la limite de ${issue.maximum} caracteres.`;
      }

      return "Votre message est invalide.";
    case "sessionId":
      return "La session courante est invalide. Rechargez la page et reessayez.";
    case "scenarioId":
      return "Le cas pratique demandé est invalide. Rechargez la page et réessayez.";
    case "conversationStatus":
      return "Le statut de la conversation est invalide.";
    default:
      if (issue.code === "too_small") {
        return "Un champ obligatoire est incomplet.";
      }

      if (issue.code === "too_big") {
        return "Une valeur depasse la taille autorisee.";
      }

      return "La requete envoyee est invalide.";
  }
}

function normalizeRouteError(error: unknown, fallbackMessage: string) {
  if (error instanceof SyntaxError) {
    return {
      message: "La requete envoyee est invalide. Rechargez la page et reessayez.",
      statusCode: 400,
    };
  }

  if (error instanceof ZodError) {
    return {
      message: formatIssueMessage(error.issues[0]),
      statusCode: 400,
    };
  }

  if (error instanceof Error) {
    if (error.message.includes("OPENAI_API_KEY")) {
      return {
        message: "Le service IA n'est pas disponible pour le moment.",
        statusCode: 503,
      };
    }

    if (error.message.includes("Le modele a renvoye une reponse invalide")) {
      return {
        message: "Le service IA a renvoye une reponse inexploitable. Reessayez.",
        statusCode: 502,
      };
    }

    if (/429|rate limit/i.test(error.message)) {
      return {
        message: "Le service est temporairement sature. Reessayez dans quelques instants.",
        statusCode: 429,
      };
    }
  }

  return {
    message: fallbackMessage,
    statusCode: 500,
  };
}

export function createRouteErrorResponse(
  error: unknown,
  fallbackMessage: string,
) {
  const normalized = normalizeRouteError(error, fallbackMessage);

  console.error(fallbackMessage, error);

  return NextResponse.json(
    { error: normalized.message },
    { status: normalized.statusCode },
  );
}
