import { eq, and, desc, sql } from "drizzle-orm";
import { getDb } from "./db";
import { formations, attestations, inscriptions, apprenants, sequences, datesFormation } from "../drizzle/schema";

/**
 * Récupérer la configuration d'une formation
 */
export async function getFormationConfig(formationId: number) {
  const db = await getDb();
  if (!db) return null;

  const results = await db
    .select({
      id: formations.id,
      nom: formations.nom,
      modeAttestation: formations.modeAttestation,
      modeEnvoi: formations.modeEnvoi,
    })
    .from(formations)
    .where(eq(formations.id, formationId))
    .limit(1);

  return results.length > 0 ? results[0] : null;
}

/**
 * Mettre à jour la configuration d'une formation
 */
export async function updateFormationConfig(
  formationId: number,
  modeAttestation: "auto" | "manuel",
  modeEnvoi: "auto" | "manuel"
) {
  const db = await getDb();
  if (!db) throw new Error("Database not available");

  await db
    .update(formations)
    .set({
      modeAttestation,
      modeEnvoi,
      updatedAt: new Date(),
    })
    .where(eq(formations.id, formationId));

  return true;
}

/**
 * Récupérer toutes les attestations d'une formation avec les informations des apprenants
 */
export async function getAttestationsByFormation(formationId: number) {
  const db = await getDb();
  if (!db) return [];

  const results = await db
    .select({
      attestation: attestations,
      apprenant: apprenants,
      sequence: sequences,
    })
    .from(attestations)
    .innerJoin(inscriptions, eq(attestations.inscriptionId, inscriptions.id))
    .innerJoin(apprenants, eq(inscriptions.apprenantId, apprenants.id))
    .innerJoin(sequences, eq(inscriptions.sequenceId, sequences.id))
    .where(eq(sequences.formationId, formationId))
    .orderBy(desc(attestations.createdAt));

  return results;
}

/**
 * Uploader un document d'attestation pour un apprenant
 */
export async function uploadAttestationDocument(
  inscriptionId: number,
  documentUrl: string,
  documentS3Key: string,
  uploadedBy: number
) {
  const db = await getDb();
  if (!db) throw new Error("Database not available");

  // Vérifier si une attestation existe déjà pour cette inscription
  const existing = await db
    .select()
    .from(attestations)
    .where(eq(attestations.inscriptionId, inscriptionId))
    .limit(1);

  if (existing.length > 0) {
    // Mettre à jour l'attestation existante
    await db
      .update(attestations)
      .set({
        documentUrl,
        documentS3Key,
        uploadedBy,
        uploadedAt: new Date(),
      })
      .where(eq(attestations.inscriptionId, inscriptionId));

    return existing[0].id;
  } else {
    // Créer une nouvelle attestation
    const result = await db
      .insert(attestations)
      .values({
        inscriptionId,
        documentUrl,
        documentS3Key,
        uploadedBy,
        uploadedAt: new Date(),
      })
      .$returningId();

    return result[0].id;
  }
}

/**
 * Envoyer une attestation par email
 */
export async function markAttestationAsSent(attestationId: number) {
  const db = await getDb();
  if (!db) throw new Error("Database not available");

  await db
    .update(attestations)
    .set({
      emailEnvoye: true,
      dateEnvoiEmail: new Date(),
    })
    .where(eq(attestations.id, attestationId));

  return true;
}

/**
 * Récupérer les apprenants d'une formation avec leur statut d'attestation
 */
export async function getApprenantsWithAttestationStatus(formationId: number) {
  const db = await getDb();
  if (!db) return [];

  const results = await db
    .select({
      apprenant: {
        id: apprenants.id,
        nom: apprenants.nom,
        prenom: apprenants.prenom,
        email: apprenants.email,
      },
      inscription: {
        id: inscriptions.id,
        sequenceId: inscriptions.sequenceId,
      },
      sequence: {
        id: sequences.id,
        nom: sequences.nom,
      },
      attestation: {
        id: attestations.id,
        documentUrl: attestations.documentUrl,
        emailEnvoye: attestations.emailEnvoye,
        dateEnvoiEmail: attestations.dateEnvoiEmail,
      },
    })
    .from(inscriptions)
    .innerJoin(apprenants, eq(inscriptions.apprenantId, apprenants.id))
    .innerJoin(sequences, eq(inscriptions.sequenceId, sequences.id))
    .leftJoin(attestations, eq(attestations.inscriptionId, inscriptions.id))
    .where(
      and(
        eq(sequences.formationId, formationId),
        eq(inscriptions.statut, "confirmee")
      )
    )
    .orderBy(apprenants.nom, apprenants.prenom);

  return results;
}

/**
 * Supprimer un document d'attestation
 */
export async function deleteAttestationDocument(attestationId: number) {
  const db = await getDb();
  if (!db) throw new Error("Database not available");

  await db
    .update(attestations)
    .set({
      documentUrl: null,
      documentS3Key: null,
      uploadedBy: null,
      uploadedAt: null,
    })
    .where(eq(attestations.id, attestationId));

  return true;
}
