/**
 * Script de seed pour Residence Marrakech Hotel Manager
 * Génère des données de démonstration réalistes
 *
 * Exécution : npm run db:seed
 */

import { PrismaClient } from "@prisma/client";
import bcrypt from "bcryptjs";

const prisma = new PrismaClient();

// Helpers
const randomItem = <T>(arr: T[]): T => arr[Math.floor(Math.random() * arr.length)];
const randomInt = (min: number, max: number) =>
  Math.floor(Math.random() * (max - min + 1)) + min;
const addDays = (date: Date, days: number) => {
  const d = new Date(date);
  d.setDate(d.getDate() + days);
  return d;
};

async function main() {
  console.log("🌱 Démarrage du seed...");

  // Nettoyage (dans l'ordre des dépendances)
  console.log("🧹 Nettoyage de la base...");
  await prisma.operationLog.deleteMany();
  await prisma.facture.deleteMany();
  await prisma.paiement.deleteMany();
  await prisma.reservation.deleteMany();
  await prisma.chambre.deleteMany();
  await prisma.client.deleteMany();
  await prisma.user.deleteMany();
  await prisma.hotel.deleteMany();

  // ========== HOTEL ==========
  console.log("🏨 Création de l'hôtel...");
  await prisma.hotel.create({
    data: {
      nom: "Residence Marrakech",
      adresse: "Avenue Mohammed VI, Gueliz, 40000 Marrakech, Maroc",
      telephone: "+212 5 24 12 34 56",
      email: "contact@residence-marrakech.ma",
      site_web: "https://residence-marrakech.ma",
      devise: "MAD",
      taux_taxe: 10,
      conditions_generales:
        "Annulation gratuite jusqu'à 48h avant l'arrivée. Au-delà, le montant de la première nuit sera facturé. Le check-in est possible à partir de 14h00, le check-out doit être effectué avant 12h00.",
    },
  });

  // ========== UTILISATEURS ==========
  console.log("👤 Création des utilisateurs...");
  await prisma.user.createMany({
    data: [
      {
        nom: "Karim El Mansouri",
        email: "admin@residence-marrakech.ma",
        password: await bcrypt.hash("Admin123!", 10),
        role: "ADMIN",
      },
      {
        nom: "Fatima Benali",
        email: "manager@residence-marrakech.ma",
        password: await bcrypt.hash("Manager123!", 10),
        role: "MANAGER",
      },
      {
        nom: "Youssef Tazi",
        email: "reception@residence-marrakech.ma",
        password: await bcrypt.hash("Reception123!", 10),
        role: "RECEPTIONIST",
      },
    ],
  });

  // ========== CHAMBRES ==========
  console.log("🛏️  Création des chambres...");
  const chambresData = [
    // Simples
    { numero: "101", type: "SIMPLE", prix_nuit: 350, capacite: 1 },
    { numero: "102", type: "SIMPLE", prix_nuit: 350, capacite: 1 },
    { numero: "103", type: "SIMPLE", prix_nuit: 400, capacite: 1 },
    // Doubles
    { numero: "201", type: "DOUBLE", prix_nuit: 550, capacite: 2 },
    { numero: "202", type: "DOUBLE", prix_nuit: 550, capacite: 2 },
    { numero: "203", type: "DOUBLE", prix_nuit: 600, capacite: 2 },
    { numero: "204", type: "DOUBLE", prix_nuit: 650, capacite: 2 },
    // Suites
    { numero: "301", type: "SUITE", prix_nuit: 1200, capacite: 2 },
    { numero: "302", type: "SUITE", prix_nuit: 1400, capacite: 3 },
    { numero: "303", type: "SUITE", prix_nuit: 1600, capacite: 3 },
    // Familiales
    { numero: "401", type: "FAMILIALE", prix_nuit: 950, capacite: 4 },
    { numero: "402", type: "FAMILIALE", prix_nuit: 1100, capacite: 5 },
  ];

  const equipementsParDefaut = ["Climatisation", "Wi-Fi", "TV LCD", "Coffre-fort", "Salle de bain privée"];
  const equipementsSuite = [...equipementsParDefaut, "Mini-bar", "Vue jardin", "Balcon"];

  const chambres = await Promise.all(
    chambresData.map((c) =>
      prisma.chambre.create({
        data: {
          ...c,
          description: `Chambre ${c.type.toLowerCase()} confortable avec vue sur la médina.`,
          equipements: JSON.stringify(
            c.type === "SUITE" || c.type === "FAMILIALE" ? equipementsSuite : equipementsParDefaut
          ),
          photos: JSON.stringify([]),
          statut: "DISPONIBLE",
        },
      })
    )
  );

  // ========== CLIENTS ==========
  console.log("👥 Création des clients...");
  const clientsData = [
    { nom_complet: "Ahmed Bennani", telephone: "+212 6 12 34 56 78", email: "ahmed.bennani@gmail.com", pays: "Maroc", numero_identite: "AB123456" },
    { nom_complet: "Sophie Dubois", telephone: "+33 6 78 90 12 34", email: "sophie.dubois@email.fr", pays: "France", numero_identite: "FR9876543" },
    { nom_complet: "John Smith", telephone: "+44 20 7946 0958", email: "john.smith@example.com", pays: "Royaume-Uni", numero_identite: "GB-PASS-123" },
    { nom_complet: "Maria Garcia", telephone: "+34 612 345 678", email: "maria.garcia@correo.es", pays: "Espagne", numero_identite: "ES-DNI-456" },
    { nom_complet: "Karim Alaoui", telephone: "+212 6 55 44 33 22", email: "k.alaoui@hotmail.com", pays: "Maroc", numero_identite: "KA789012" },
    { nom_complet: "Hans Müller", telephone: "+49 30 12345678", email: "hans.muller@mail.de", pays: "Allemagne", numero_identite: "DE-PASS-789" },
    { nom_complet: "Yuki Tanaka", telephone: "+81 90 1234 5678", email: "y.tanaka@example.jp", pays: "Japon", numero_identite: "JP-PASS-321" },
    { nom_complet: "Fatima Zahra", telephone: "+212 6 99 88 77 66", email: "fatima.z@gmail.com", pays: "Maroc", numero_identite: "FZ345678" },
    { nom_complet: "Pierre Martin", telephone: "+33 7 12 34 56 78", email: "pierre.martin@gmail.fr", pays: "France", numero_identite: "FR1234567" },
    { nom_complet: "Anna Rossi", telephone: "+39 333 1234567", email: "anna.rossi@mail.it", pays: "Italie", numero_identite: "IT-CI-987" },
    { nom_complet: "Omar Fassi", telephone: "+212 6 33 22 11 00", email: "omar.fassi@yahoo.com", pays: "Maroc", numero_identite: "OF901234" },
    { nom_complet: "Emma Johnson", telephone: "+1 415 555 0123", email: "emma.j@example.com", pays: "États-Unis", numero_identite: "US-PASS-456" },
    { nom_complet: "Mohamed Idrissi", telephone: "+212 6 11 22 33 44", email: "m.idrissi@gmail.com", pays: "Maroc", numero_identite: "MI567890" },
    { nom_complet: "Lucie Bernard", telephone: "+33 6 11 22 33 44", email: "lucie.b@email.fr", pays: "France", numero_identite: "FR5432109" },
    { nom_complet: "Ali Saoudi", telephone: "+966 50 123 4567", email: "ali.saoudi@mail.sa", pays: "Arabie Saoudite", numero_identite: "SA-PASS-654" },
  ];

  const clients = await Promise.all(
    clientsData.map((c) => prisma.client.create({ data: c }))
  );

  // ========== RÉSERVATIONS ==========
  console.log("📅 Création des réservations...");
  const today = new Date();
  today.setHours(12, 0, 0, 0);

  const reservationsToCreate: Array<{
    clientIdx: number;
    chambreIdx: number;
    dayOffset: number; // jours par rapport à aujourd'hui
    nights: number;
    statut: string;
  }> = [
    // Réservations terminées (passées)
    { clientIdx: 0, chambreIdx: 3, dayOffset: -85, nights: 3, statut: "TERMINEE" },
    { clientIdx: 1, chambreIdx: 7, dayOffset: -75, nights: 5, statut: "TERMINEE" },
    { clientIdx: 2, chambreIdx: 0, dayOffset: -65, nights: 2, statut: "TERMINEE" },
    { clientIdx: 3, chambreIdx: 4, dayOffset: -60, nights: 4, statut: "TERMINEE" },
    { clientIdx: 4, chambreIdx: 10, dayOffset: -50, nights: 6, statut: "TERMINEE" },
    { clientIdx: 5, chambreIdx: 8, dayOffset: -45, nights: 3, statut: "TERMINEE" },
    { clientIdx: 6, chambreIdx: 2, dayOffset: -40, nights: 2, statut: "TERMINEE" },
    { clientIdx: 7, chambreIdx: 5, dayOffset: -35, nights: 4, statut: "TERMINEE" },
    { clientIdx: 8, chambreIdx: 9, dayOffset: -30, nights: 5, statut: "TERMINEE" },
    { clientIdx: 9, chambreIdx: 11, dayOffset: -25, nights: 7, statut: "TERMINEE" },
    { clientIdx: 10, chambreIdx: 6, dayOffset: -20, nights: 3, statut: "TERMINEE" },
    { clientIdx: 11, chambreIdx: 1, dayOffset: -15, nights: 2, statut: "TERMINEE" },
    { clientIdx: 12, chambreIdx: 7, dayOffset: -10, nights: 4, statut: "TERMINEE" },
    { clientIdx: 13, chambreIdx: 3, dayOffset: -5, nights: 2, statut: "TERMINEE" },

    // Réservations en cours / aujourd'hui
    { clientIdx: 14, chambreIdx: 0, dayOffset: 0, nights: 3, statut: "CONFIRMEE" },
    { clientIdx: 0, chambreIdx: 4, dayOffset: 0, nights: 2, statut: "CONFIRMEE" },

    // Réservations futures
    { clientIdx: 2, chambreIdx: 8, dayOffset: 5, nights: 4, statut: "CONFIRMEE" },
    { clientIdx: 5, chambreIdx: 10, dayOffset: 10, nights: 6, statut: "EN_ATTENTE" },
    { clientIdx: 7, chambreIdx: 5, dayOffset: 15, nights: 3, statut: "CONFIRMEE" },
    { clientIdx: 11, chambreIdx: 9, dayOffset: 20, nights: 5, statut: "CONFIRMEE" },
  ];

  const reservations = [];
  for (const r of reservationsToCreate) {
    const dateArrivee = addDays(today, r.dayOffset);
    const dateDepart = addDays(dateArrivee, r.nights);
    const chambre = chambres[r.chambreIdx];
    const prix_total = r.nights * chambre.prix_nuit;

    const reservation = await prisma.reservation.create({
      data: {
        client_id: clients[r.clientIdx].id,
        chambre_id: chambre.id,
        date_arrivee: dateArrivee,
        date_depart: dateDepart,
        nb_nuits: r.nights,
        nb_personnes: randomInt(1, chambre.capacite),
        prix_total,
        statut: r.statut,
      },
    });
    reservations.push({ ...reservation, chambre, isPast: r.statut === "TERMINEE" });
  }

  // ========== PAIEMENTS ==========
  console.log("💳 Création des paiements...");
  const methodes = ["ESPECES", "CARTE", "VIREMENT", "MOBILE_MONEY"];
  for (const r of reservations) {
    if (r.statut === "ANNULEE") continue;
    // Toutes les réservations terminées sont payées intégralement
    // Les réservations en cours/futures ont 50% payé
    const ratio = r.statut === "TERMINEE" ? 1 : Math.random() > 0.5 ? 0.5 : 1;
    const montant = Math.round(r.prix_total * ratio);
    await prisma.paiement.create({
      data: {
        reservation_id: r.id,
        montant,
        methode: randomItem(methodes),
        date_paiement: addDays(r.date_arrivee, -1),
      },
    });
  }

  // ========== FACTURES ==========
  console.log("📄 Création des factures...");
  let factureCount = 0;
  for (const r of reservations) {
    if (r.statut !== "TERMINEE") continue;
    factureCount++;
    const sousTotal = r.prix_total;
    const tauxTaxe = 10;
    const montantTaxe = (sousTotal * tauxTaxe) / 100;
    const total = sousTotal + montantTaxe;

    await prisma.facture.create({
      data: {
        numero_facture: `F-${String(factureCount).padStart(4, "0")}`,
        reservation_id: r.id,
        sous_total: sousTotal,
        montant_taxe: montantTaxe,
        remise: 0,
        total,
        date_emission: r.date_depart,
      },
    });
  }

  // ========== STATUTS CHAMBRES (en cours) ==========
  console.log("🔄 Mise à jour des statuts de chambres...");
  // Marquer les chambres actuellement occupées
  const enCours = reservations.filter(
    (r) =>
      r.statut === "CONFIRMEE" &&
      r.date_arrivee <= today &&
      r.date_depart > today
  );
  for (const r of enCours) {
    await prisma.chambre.update({
      where: { id: r.chambre_id },
      data: { statut: "OCCUPEE" },
    });
  }

  console.log("✅ Seed terminé avec succès !");
  console.log("");
  console.log("Comptes de connexion :");
  console.log("  • admin@residence-marrakech.ma / Admin123!");
  console.log("  • manager@residence-marrakech.ma / Manager123!");
  console.log("  • reception@residence-marrakech.ma / Reception123!");
}

main()
  .catch((e) => {
    console.error("❌ Erreur durant le seed :", e);
    process.exit(1);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
