import "server-only";

import { PriorityLevel } from "@prisma/client";
import { getScoringConfig } from "@/lib/scoring-config";
import { recomputeAssessmentResults } from "@/lib/scoring";
import { prisma } from "@/lib/prisma";

type BadgeVariant = "success" | "warning" | "neutral";

export type RecommendationViewItem = {
  id: string;
  moduleLabel: string;
  moduleKey: string | null;
  title: string;
  detail: string;
  priorityLabel: string;
  priorityVariant: BadgeVariant;
  source: "module" | "global";
  scoreHint: string | null;
};

export type RecommendationSnapshot = {
  overallScore: number;
  recommendations: RecommendationViewItem[];
  targetedModuleCount: number;
  lowScoreThreshold: number;
};

function mapPriority(priority: PriorityLevel): { label: string; variant: BadgeVariant } {
  if (priority === PriorityLevel.HIGH) {
    return { label: "Alta", variant: "warning" };
  }

  if (priority === PriorityLevel.MEDIUM) {
    return { label: "Media", variant: "neutral" };
  }

  return { label: "Baja", variant: "success" };
}

export async function getRecommendationsForUser(userId: string): Promise<RecommendationSnapshot> {
  const assessment = await recomputeAssessmentResults(userId);
  const scoringConfig = await getScoringConfig();

  const lowScoringModules = assessment.moduleScores
    .filter((moduleScore) => moduleScore.answeredQuestions > 0 && moduleScore.score < scoringConfig.lowScoreThreshold)
    .sort((a, b) => a.score - b.score);

  const lowModuleIds = lowScoringModules.map((moduleScore) => moduleScore.moduleId);

  const recommendationRows = await prisma.recommendation.findMany({
    where: {
      isTemplate: true,
      OR: [
        {
          moduleId: {
            in: lowModuleIds.length ? lowModuleIds : ["__no_module__"],
          },
        },
        {
          moduleId: null,
        },
      ],
    },
    include: {
      module: {
        select: {
          key: true,
          name: true,
        },
      },
    },
    orderBy: [{ priority: "desc" }, { createdAt: "asc" }],
  });

  const recommendations: RecommendationViewItem[] = [];

  for (const moduleScore of lowScoringModules) {
    const moduleRecommendations = recommendationRows.filter((row) => row.moduleId === moduleScore.moduleId).slice(0, 2);

    for (const row of moduleRecommendations) {
      const priority = mapPriority(row.priority);

      recommendations.push({
        id: `${row.id}-${moduleScore.moduleKey}`,
        moduleLabel: moduleScore.moduleName,
        moduleKey: moduleScore.moduleKey,
        title: row.title,
        detail: row.description,
        priorityLabel: priority.label,
        priorityVariant: priority.variant,
        source: "module",
        scoreHint: `Puntaje actual del modulo: ${Math.round(moduleScore.score)}%`,
      });
    }
  }

  if (!recommendations.length) {
    const globalRecommendations = recommendationRows.filter((row) => row.moduleId === null).slice(0, 3);

    for (const row of globalRecommendations) {
      const priority = mapPriority(row.priority);

      recommendations.push({
        id: `${row.id}-global`,
        moduleLabel: "General",
        moduleKey: null,
        title: row.title,
        detail: row.description,
        priorityLabel: priority.label,
        priorityVariant: priority.variant,
        source: "global",
        scoreHint: null,
      });
    }
  }

  return {
    overallScore: assessment.overallScore,
    recommendations,
    targetedModuleCount: lowScoringModules.length,
    lowScoreThreshold: scoringConfig.lowScoreThreshold,
  };
}
