"use server";

import { prisma } from "@/lib/db";
import { getEvaluation } from "@/lib/server-data";
import { requireAuth, requireEvaluationAccess, type ActionResult } from "@/lib/action-helpers";
import { revalidatePath } from "next/cache";


export async function fetchEvaluation(id: string): Promise<ActionResult<Awaited<ReturnType<typeof getEvaluation>>>> {
  const session = await requireAuth();
  if (!session) return { success: false, error: "Non authentifié" };

  const evaluation = await getEvaluation(id);
  if (!evaluation) return { success: false, error: "Évaluation introuvable" };

  return { success: true, data: evaluation };
}

export async function deleteEvaluation(id: string): Promise<ActionResult> {
  const session = await requireAuth();
  if (!session) return { success: false, error: "Non authentifié" };

  const hasAccess = await requireEvaluationAccess(id, session.user.id, session.user.role === "admin");
  if (!hasAccess) return { success: false, error: "Accès refusé" };

  try {
    await prisma.evaluation.delete({ where: { id } });
    revalidatePath("/dashboard");
    return { success: true };
  } catch (e) {
    console.error(e);
    return { success: false, error: "Erreur lors de la suppression" };
  }
}

export async function createEvaluation(data: {
  candidateName: string;
  candidateRole: string;
  candidateTeam?: string;
  evaluationDate: string;
  templateId: string;
}): Promise<ActionResult<{ id: string }>> {
  const session = await requireAuth();
  if (!session) return { success: false, error: "Non authentifié" };

  const { candidateName, candidateRole, candidateTeam, evaluationDate, templateId } = data;
  if (!candidateName || !candidateRole || !evaluationDate || !templateId) {
    return { success: false, error: "Champs requis manquants" };
  }

  try {
    const evaluatorName = session.user.name || session.user.email || "Évaluateur";

    const template = await prisma.template.findUnique({
      where: { id: templateId },
      include: { dimensions: { orderBy: { orderIndex: "asc" } } },
    });
    if (!template) return { success: false, error: "Template introuvable" };

    const evaluation = await prisma.evaluation.create({
      data: {
        candidateName,
        candidateRole,
        candidateTeam: candidateTeam || null,
        evaluatorName,
        evaluatorId: session.user.id,
        evaluationDate: new Date(evaluationDate),
        templateId,
        status: "draft",
      },
    });

    await prisma.dimensionScore.createMany({
      data: template.dimensions.map((dim) => ({
        evaluationId: evaluation.id,
        dimensionId: dim.id,
      })),
    });

    revalidatePath("/dashboard");
    return { success: true, data: { id: evaluation.id } };
  } catch (e) {
    console.error(e);
    return { success: false, error: "Erreur lors de la création" };
  }
}

export interface UpdateEvaluationInput {
  candidateName?: string;
  candidateRole?: string;
  candidateTeam?: string | null;
  evaluatorName?: string;
  evaluationDate?: string;
  status?: string;
  findings?: string | null;
  recommendations?: string | null;
  isPublic?: boolean;
  dimensionScores?: {
    dimensionId: string;
    evaluationId: string;
    score: number | null;
    justification?: string | null;
    examplesObserved?: string | null;
    confidence?: string | null;
    candidateNotes?: string | null;
  }[];
}

export async function updateDimensionScore(
  evaluationId: string,
  dimensionId: string,
  data: { score?: number | null; justification?: string | null; examplesObserved?: string | null; confidence?: string | null; candidateNotes?: string | null }
): Promise<ActionResult> {
  const session = await requireAuth();
  if (!session) return { success: false, error: "Non authentifié" };

  const hasAccess = await requireEvaluationAccess(evaluationId, session.user.id, session.user.role === "admin");
  if (!hasAccess) return { success: false, error: "Accès refusé" };

  try {
    await prisma.dimensionScore.upsert({
      where: { evaluationId_dimensionId: { evaluationId, dimensionId } },
      update: data,
      create: { evaluationId, dimensionId, ...data },
    });
    revalidatePath(`/evaluations/${evaluationId}`);
    return { success: true };
  } catch (e) {
    return { success: false, error: e instanceof Error ? e.message : "Erreur" };
  }
}

export async function updateEvaluation(id: string, data: UpdateEvaluationInput): Promise<ActionResult> {
  const session = await requireAuth();
  if (!session) return { success: false, error: "Non authentifié" };

  const hasAccess = await requireEvaluationAccess(id, session.user.id, session.user.role === "admin");
  if (!hasAccess) return { success: false, error: "Accès refusé" };

  const existing = await prisma.evaluation.findUnique({ where: { id } });
  if (!existing) return { success: false, error: "Évaluation introuvable" };

  try {
    const {
      candidateName,
      candidateRole,
      candidateTeam,
      evaluatorName,
      evaluationDate,
      status,
      findings,
      recommendations,
      isPublic,
      dimensionScores,
    } = data;

    const updateData: Record<string, unknown> = {};
    if (candidateName != null) updateData.candidateName = candidateName;
    if (candidateRole != null) updateData.candidateRole = candidateRole;
    if (candidateTeam !== undefined) updateData.candidateTeam = candidateTeam;
    if (evaluatorName != null) updateData.evaluatorName = evaluatorName;
    if (evaluationDate != null) {
      const d = new Date(evaluationDate);
      if (!isNaN(d.getTime())) updateData.evaluationDate = d;
    }
    if (status != null) updateData.status = status;
    if (findings != null) updateData.findings = findings;
    if (recommendations != null) updateData.recommendations = recommendations;
    if (typeof isPublic === "boolean") updateData.isPublic = isPublic;

    if (Object.keys(updateData).length > 0) {
      await prisma.auditLog.create({
        data: { evaluationId: id, action: "updated", newValue: JSON.stringify(updateData) },
      });
      await prisma.evaluation.update({ where: { id }, data: updateData as Record<string, unknown> });
    }

    if (dimensionScores && Array.isArray(dimensionScores)) {
      const validScores = dimensionScores.filter((ds) => ds.dimensionId);
      if (validScores.length > 0) {
        await prisma.$transaction(
          validScores.map((ds) =>
            prisma.dimensionScore.upsert({
              where: {
                evaluationId_dimensionId: { evaluationId: id, dimensionId: ds.dimensionId },
              },
              update: {
                score: ds.score,
                justification: ds.justification,
                examplesObserved: ds.examplesObserved,
                confidence: ds.confidence,
                candidateNotes: ds.candidateNotes,
              },
              create: {
                evaluationId: id,
                dimensionId: ds.dimensionId,
                score: ds.score,
                justification: ds.justification,
                examplesObserved: ds.examplesObserved,
                confidence: ds.confidence,
                candidateNotes: ds.candidateNotes,
              },
            })
          )
        );
      }
    }

    revalidatePath(`/evaluations/${id}`);
    revalidatePath("/dashboard");
    return { success: true };
  } catch (e) {
    console.error(e);
    return { success: false, error: e instanceof Error ? e.message : "Erreur lors de la sauvegarde" };
  }
}
