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

const prisma = new PrismaClient();

async function main() {
  const passwordHash = await bcrypt.hash("Password123!", 12);

  const superAdmin = await prisma.user.upsert({
    where: { email: "superadmin@incidentlog.local" },
    update: {},
    create: { name: "Super Admin", email: "superadmin@incidentlog.local", passwordHash, role: Role.SUPER_ADMIN },
  });

  const admin = await prisma.user.upsert({
    where: { email: "admin@incidentlog.local" },
    update: {},
    create: { name: "System Admin", email: "admin@incidentlog.local", passwordHash, role: Role.ADMIN },
  });

  const manager = await prisma.user.upsert({
    where: { email: "manager@incidentlog.local" },
    update: {},
    create: { name: "Site Manager", email: "manager@incidentlog.local", passwordHash, role: Role.MANAGER },
  });

  const employee = await prisma.user.upsert({
    where: { email: "user@incidentlog.local" },
    update: {},
    create: { name: "Floor Worker", email: "user@incidentlog.local", passwordHash, role: Role.USER },
  });

  const incidentTypeNames = [
    "Animal/Insect Bite",
    "Chemical Spill",
    "Confined Space Incident",
    "Contractor Incident",
    "Electrical Incident",
    "Environmental Incident",
    "Equipment Failure",
    "Explosion",
    "Falling Object",
    "Fatality",
    "Fire Incident",
    "First Aid Case",
    "Gas Leak",
    "Heat Stress",
    "LPG Leakage",
    "Lost Time Injury",
    "Manual Handling Injury",
    "Medical Treatment Injury",
    "Natural Disaster",
    "Natural Disaster Impact",
    "Near Miss",
    "Occupational Illness",
    "Other",
    "PPE Violation",
    "Property Damage",
    "Public/Visitors Incident",
    "Security Incident",
    "Slip Trip & Fall",
    "Theft",
    "Unsafe Act",
    "Unsafe Condition",
    "Vehicle Accident",
    "Working at Height Incident",
  ];
  const incidentTypes = await Promise.all(
    incidentTypeNames.map((name, i) =>
      prisma.incidentTypeOption.upsert({ where: { name }, update: {}, create: { name, sortOrder: i + 1 } })
    )
  );

  const superseded = ["Injury", "Environmental", "Security"];
  await prisma.incidentTypeOption.updateMany({
    where: { name: { in: superseded } },
    data: { isActive: false },
  });

  const severityNames = ["Low", "Medium", "High", "Critical"];
  const severities = await Promise.all(
    severityNames.map((name, i) =>
      prisma.severityOption.upsert({ where: { name }, update: {}, create: { name, sortOrder: i + 1 } })
    )
  );

  const locationNames = ["Ctg Plant", "Dhaka Plant", "HQ"];
  const locations = await Promise.all(
    locationNames.map((name, i) =>
      prisma.locationOption.upsert({ where: { name }, update: {}, create: { name, sortOrder: i + 1 } })
    )
  );

  const retiredLocations = ["Loading Dock B", "Main Warehouse", "Production Floor", "Office Building", "Parking Lot"];
  await prisma.locationOption.updateMany({
    where: { name: { in: retiredLocations } },
    data: { isActive: false },
  });

  const departmentNames = ["Operations", "Warehouse & Logistics", "Maintenance", "Administration"];
  const departments = await Promise.all(
    departmentNames.map((name, i) =>
      prisma.department.upsert({ where: { name }, update: {}, create: { name, sortOrder: i + 1 } })
    )
  );

  const nearMiss = incidentTypes.find((t) => t.name === "Near Miss")!;
  const medium = severities.find((s) => s.name === "Medium")!;
  const dhakaPlant = locations.find((l) => l.name === "Dhaka Plant")!;
  const warehouseDept = departments.find((d) => d.name === "Warehouse & Logistics")!;

  const existingIncident = await prisma.incident.findFirst({ where: { referenceNumber: "INC-2026-0001" } });
  if (!existingIncident) {
    const incident = await prisma.incident.create({
      data: {
        referenceNumber: "INC-2026-0001",
        title: "Slip hazard near loading dock",
        description: "Wet floor near loading dock B caused a near-miss slip incident.",
        typeId: nearMiss.id,
        severityId: medium.id,
        status: IncidentStatus.INVESTIGATING,
        locationId: dhakaPlant.id,
        departmentId: warehouseDept.id,
        dateOccurred: new Date(),
        reporterId: employee.id,
        assigneeId: manager.id,
        rootCause: "Leaking overhead pipe was not reported promptly.",
      },
    });

    await prisma.correctiveAction.create({
      data: {
        incidentId: incident.id,
        description: "Repair overhead pipe and install warning signage",
        assigneeId: manager.id,
        dueDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
      },
    });

    await prisma.comment.create({
      data: { incidentId: incident.id, authorId: manager.id, body: "Maintenance has been notified." },
    });

    await prisma.auditLog.create({
      data: { incidentId: incident.id, userId: employee.id, action: "CREATED", details: "Seed data" },
    });
  }

  console.log("Seed complete. Login with:");
  console.log("  superadmin@incidentlog.local / Password123!");
  console.log("  admin@incidentlog.local / Password123!");
  console.log("  manager@incidentlog.local / Password123!");
  console.log("  user@incidentlog.local / Password123!");
}

main()
  .catch((err) => {
    console.error(err);
    process.exit(1);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
