import 'dotenv/config';
import { PrismaClient } from '@prisma/client';
import { PrismaMssql } from '@prisma/adapter-mssql';

// Le seed tourne hors du contexte applicatif : il instancie son propre client
// avec l'adapter MSSQL, en lisant directement les variables d'environnement DB.
function getEnv(name: string): string {
  const value = process.env[name];

  if (!value) {
    throw new Error(`Variable d'environnement manquante: ${name}`);
  }

  return value;
}

const adapter = new PrismaMssql({
  server: getEnv('DB_SERVER'),
  port: Number(process.env.DB_PORT ?? 1433),
  database: getEnv('DB_NAME'),
  user: getEnv('DB_USER'),
  password: getEnv('DB_PASSWORD'),
  options: {
    encrypt: true,
    trustServerCertificate: true,
  },
});

const prisma = new PrismaClient({ adapter });

// Données de référence — voir review.md (Étape seeds).
const ROLES = [
  {
    code: 'ETUDIANT',
    libelle: 'Étudiant',
    description: 'Emprunte et restitue du matériel via le poste dédié.',
  },
  {
    code: 'RESPONSABLE',
    libelle: 'Responsable matériel',
    description: 'Supervise, gère le stock et traite les anomalies.',
  },
];

const CATEGORIES = [
  { nom: 'Ordinateur portable', description: 'Ordinateurs portables pédagogiques.' },
  { nom: 'Vidéoprojecteur', description: 'Vidéoprojecteurs et accessoires de projection.' },
  { nom: 'Tablette', description: 'Tablettes tactiles.' },
  { nom: 'Caméra', description: 'Caméras et matériel de captation vidéo.' },
  { nom: 'Périphérique audio', description: 'Micros, casques et enceintes.' },
  { nom: 'Câble / Adaptateur', description: 'Câbles, adaptateurs et connectique.' },
];

async function main(): Promise<void> {
  // Rôles — upsert sur la clé unique `code` (idempotent).
  for (const role of ROLES) {
    await prisma.role.upsert({
      where: { code: role.code },
      update: { libelle: role.libelle, description: role.description },
      create: role,
    });
  }
  console.log(`[seed] ${ROLES.length} rôles assurés`);

  // Campus — pas de clé unique : on cherche par nom avant de créer.
  const campusNom = 'Campus Saint-Christophe';
  let campus = await prisma.campus.findFirst({ where: { nom: campusNom } });

  if (!campus) {
    campus = await prisma.campus.create({
      data: {
        nom: campusNom,
        adresse: 'À compléter — Cergy Saint-Christophe',
        ville: 'Cergy',
        codePostal: '95800',
      },
    });
  }
  console.log(`[seed] campus "${campus.nom}" (id ${campus.id})`);

  // Salle de prêt — rattachée au campus.
  const salleNom = 'Salle de prêt principale';
  let salle = await prisma.sallePret.findFirst({
    where: { nom: salleNom, campusId: campus.id },
  });

  if (!salle) {
    salle = await prisma.sallePret.create({
      data: {
        nom: salleNom,
        localisation: campusNom,
        campusId: campus.id,
      },
    });
  }
  console.log(`[seed] salle "${salle.nom}" (id ${salle.id})`);

  // Poste d'emprunt — rattaché à la salle, identifié par `identifiantPoste`.
  const identifiantPoste = 'POSTE-01';
  let poste = await prisma.posteEmprunt.findFirst({
    where: { identifiantPoste },
  });

  if (!poste) {
    poste = await prisma.posteEmprunt.create({
      data: {
        nom: 'Poste 1',
        identifiantPoste,
        sallePretId: salle.id,
      },
    });
  }
  console.log(`[seed] poste "${poste.nom}" (${poste.identifiantPoste})`);

  // Catégories de matériel — cherche par nom avant de créer.
  for (const categorie of CATEGORIES) {
    const existante = await prisma.categorieMateriel.findFirst({
      where: { nom: categorie.nom },
    });

    if (!existante) {
      await prisma.categorieMateriel.create({ data: categorie });
    }
  }
  console.log(`[seed] ${CATEGORIES.length} catégories assurées`);
}

main()
  .then(async () => {
    await prisma.$disconnect();
    console.log('[seed] termine');
  })
  .catch(async (error: unknown) => {
    console.error('[seed] echec', error);
    await prisma.$disconnect();
    process.exit(1);
  });
