import {
  AllocationStatus,
  AllocationType,
  BlueprintTarget,
  FieldType,
  OrderType,
  ProjectStatus,
  ResourceType,
  SystemRole,
  VacationStatus,
  VacationType,
} from "@capakraken/shared";
import { PrismaClient, type Prisma, type Resource, type Project } from "@prisma/client";
import { hash } from "@node-rs/argon2";
import { getHolidayDemoProfileForIndex } from "./holiday-demo-profiles.js";
import { loadWorkspaceEnv } from "./load-workspace-env.js";
import { assertSafeSeedTarget } from "./safe-destructive-env.js";
import { buildSystemRoleConfigSeedData } from "./system-role-config-defaults.js";

loadWorkspaceEnv();

const prisma = new PrismaClient();

async function seedSystemRoleConfigs() {
  for (const config of buildSystemRoleConfigSeedData()) {
    await prisma.systemRoleConfig.upsert({
      where: { role: config.role },
      update: {
        label: config.label,
        description: config.description,
        defaultPermissions: config.defaultPermissions,
        color: config.color,
        sortOrder: config.sortOrder,
      },
      create: config,
    });
  }
}

// ─── Skill helpers ─────────────────────────────────────────────────────────────

interface SkillEntry {
  skill: string;
  proficiency: number;
  category: string;
}

function computeProficiency(lcr: number): number {
  if (lcr >= 118) return 5;
  if (lcr >= 95) return 4;
  return 3;
}

function computeSkills(chapter: string, typeOfWork: string, lcr: number): SkillEntry[] {
  const prof = computeProficiency(lcr);
  const p2 = Math.max(2, prof - 1);

  if (chapter === "Project Management" && typeOfWork === "Project Management") {
    return [
      { skill: "Project Manager", proficiency: prof, category: "PM" },
      { skill: "Scrum Master", proficiency: p2, category: "PM" },
    ];
  }
  if (chapter === "Digital Content Production" && typeOfWork === "Unreal Engine Layerstack") {
    return [
      { skill: "Unreal Engine", proficiency: prof, category: "3D" },
      { skill: "3D Lighting", proficiency: p2, category: "3D" },
      { skill: "3D Modeling", proficiency: p2, category: "3D" },
    ];
  }
  if (chapter === "Product Data Management" && typeOfWork === "Vis Logic") {
    return [
      { skill: "Visualization Logic", proficiency: prof, category: "PDM" },
      { skill: "Quality Assurance", proficiency: p2, category: "PDM" },
    ];
  }
  if (chapter === "Art Direction" && typeOfWork === "Art Direction") {
    return [
      { skill: "Art Direction", proficiency: prof, category: "Art" },
      { skill: "2D Compositing", proficiency: p2, category: "Art" },
    ];
  }
  if (chapter === "CGI-Dev" && typeOfWork === "Dev Unreal") {
    return [
      { skill: "Unreal Dev", proficiency: prof, category: "Dev" },
      { skill: "Technical Architect", proficiency: p2, category: "Dev" },
    ];
  }
  if (chapter === "CGI-Dev" && typeOfWork === "Dev Frontend") {
    return [
      { skill: "Frontend Dev", proficiency: prof, category: "Dev" },
      { skill: "Backend Dev", proficiency: p2, category: "Dev" },
    ];
  }
  return [{ skill: typeOfWork, proficiency: prof, category: chapter }];
}

// ─── Availability helpers ───────────────────────────────────────────────────────

interface WeekdayAvailability {
  monday: number;
  tuesday: number;
  wednesday: number;
  thursday: number;
  friday: number;
}

function computeAvailability(fraction: number, availDays: string): WeekdayAvailability {
  const full = 8;
  const half = Math.round(full * fraction);

  if (availDays === "all") {
    if (fraction === 1.0) {
      return { monday: 8, tuesday: 8, wednesday: 8, thursday: 8, friday: 8 };
    }
    if (fraction === 0.5) {
      return { monday: 4, tuesday: 4, wednesday: 4, thursday: 4, friday: 4 };
    }
    if (fraction === 0.8) {
      return { monday: 8, tuesday: 8, wednesday: 8, thursday: 8, friday: 0 };
    }
    return { monday: half, tuesday: half, wednesday: half, thursday: half, friday: half };
  }

  if (availDays === "tue,wed,thu,fri") {
    return { monday: 0, tuesday: 8, wednesday: 8, thursday: 8, friday: 8 };
  }
  if (availDays === "mon,tue,thu,fri") {
    return { monday: 8, tuesday: 8, wednesday: 0, thursday: 8, friday: 8 };
  }
  if (availDays === "mon,tue,wed,thu") {
    return { monday: 8, tuesday: 8, wednesday: 8, thursday: 8, friday: 0 };
  }

  return { monday: 8, tuesday: 8, wednesday: 8, thursday: 8, friday: 8 };
}

// ─── Resource data ─────────────────────────────────────────────────────────────

// [eid, chapter, typeOfWork, clientUnit, city, employeeType, lcr, ucr, fraction, availDays, chargeability]
type ResourceRow = [
  string,
  string,
  string,
  string,
  string,
  string,
  number,
  number,
  number,
  string,
  number,
];

const RESOURCE_DATA: ResourceRow[] = [
  // ── Project Management ──
  ["steve.rogers",    "Project Management",        "Project Management",         "Porsche AG",        "Stuttgart", "Employee",  133.77, 74.65, 1.0, "all",          0.75],
  ["bruce.banner",    "Project Management",        "Project Management",         "Daimler",           "Stuttgart", "Employee",  118.35, 88.52, 1.0, "all",          0.75],
  ["natasha.romanoff","Project Management",        "Project Management",         "Italy (FER/MAS)",   "Stuttgart", "Employee",  133.77, 74.65, 1.0, "all",          1.0 ],
  ["charles.xavier",  "Project Management",        "Project Management",         "Moving Image",      "Muenchen",  "Employee",   96.77, 65.24, 1.0, "all",          0.75],
  ["scott.summers",   "Project Management",        "Project Management",         "Moving Image",      "Stuttgart", "Employee",   65.00, 88.52, 0.8, "mon,tue,thu,fri", 0.75],
  ["ororo.munroe",    "Project Management",        "Project Management",         "Moving Image",      "Stuttgart", "Employee",  118.35, 88.52, 1.0, "all",          0.75],
  ["gamora.gamora",   "Project Management",        "Project Management",         "Moving Image",      "Hamburg",   "Employee",   67.00, 88.52, 0.8, "mon,tue,wed,thu", 1.0 ],
  // ── 3D / Digital Content Production ──
  ["tony.stark",      "Digital Content Production","Unreal Engine Layerstack",   "Italy (FER/MAS)",   "Hamburg",   "Employee",   96.77, 65.24, 1.0, "all",          0.75],
  ["thor.odinson",    "Digital Content Production","Unreal Engine Layerstack",   "Daimler",           "Stuttgart", "Employee",   76.64, 55.98, 1.0, "all",          0.75],
  ["sam.wilson",      "Digital Content Production","Unreal Engine Layerstack",   "Porsche AG",        "Stuttgart", "Employee",  133.77, 74.65, 1.0, "all",          0.75],
  ["james.barnes",    "Digital Content Production","Unreal Engine Layerstack",   "Porsche AG",        "Hamburg",   "Employee",  118.35, 88.52, 1.0, "all",          0.75],
  ["wanda.maximoff",  "Digital Content Production","Unreal Engine Layerstack",   "BMW",               "Stuttgart", "Employee",   76.64, 55.98, 0.8, "tue,wed,thu,fri", 0.75],
  ["peter.parker",    "Digital Content Production","Unreal Engine Layerstack",   "BMW",               "Hamburg",   "Employee",   96.77, 65.24, 1.0, "all",          0.75],
  ["miles.morales",   "Digital Content Production","Unreal Engine Layerstack",   "Cross-Unit",        "Stuttgart", "Employee",   76.64, 55.98, 1.0, "all",          0.86],
  ["jessica.drew",    "Digital Content Production","Unreal Engine Layerstack",   "BMW",               "Stuttgart", "Employee",   76.64, 55.98, 1.0, "all",          0.75],
  ["logan.howlett",   "Digital Content Production","Unreal Engine Layerstack",   "BMW",               "Hamburg",   "Employee",   66.67, 49.18, 1.0, "all",          0.75],
  ["erik.lehnsherr",  "Digital Content Production","Unreal Engine Layerstack",   "Daimler",           "Hamburg",   "Employee",   66.67, 49.18, 1.0, "all",          1.0 ],
  ["jean.grey",       "Digital Content Production","Unreal Engine Layerstack",   "Daimler",           "Muenchen",  "Employee",  133.77, 74.65, 1.0, "all",          0.75],
  ["stephen.strange", "Digital Content Production","Unreal Engine Layerstack",   "Porsche AG",        "Muenchen",  "Employee",   66.67, 49.18, 1.0, "all",          0.75],
  ["wong.wong",       "Digital Content Production","Unreal Engine Layerstack",   "Porsche AG",        "Stuttgart", "Employee",   66.67, 49.18, 0.5, "all",          0.75],
  // ── Art Direction ──
  ["vision.vision",   "Art Direction",             "Art Direction",              "BMW",               "Stuttgart", "Employee",   66.67, 49.18, 1.0, "all",          0.75],
  ["drax.drax",       "Art Direction",             "Art Direction",              "Daimler",           "Stuttgart", "Employee",   96.77, 65.24, 1.0, "all",          0.75],
  ["rocket.rocket",   "Art Direction",             "Art Direction",              "Cross-Unit",        "Stuttgart", "Employee",  118.35, 88.52, 0.8, "mon,tue,wed,thu", 0.75],
  ["groot.groot",     "Art Direction",             "Art Direction",              "Jaguar Land Rover", "Hamburg",   "Employee",  118.35, 88.52, 1.0, "all",          0.75],
  ["tchalla.tchalla", "Art Direction",             "Art Direction",              "Jaguar Land Rover", "Stuttgart", "Employee",   96.77, 65.24, 1.0, "all",          0.9 ],
  // ── Product Data Management / Compositor ──
  ["clint.barton",    "Product Data Management",   "Vis Logic",                  "Cross-Unit",        "Muenchen",  "Employee",   76.64, 55.98, 1.0, "all",          0.9 ],
  ["hank.mccoy",      "Product Data Management",   "Vis Logic",                  "Porsche AG",        "Muenchen",  "Employee",  133.77, 74.65, 1.0, "all",          1.0 ],
  ["anna.marie",      "Product Data Management",   "Vis Logic",                  "Daimler",           "Hamburg",   "Employee",  118.35, 88.52, 1.0, "all",          0.86],
  ["peter.quill",     "Product Data Management",   "Vis Logic",                  "Moving Image",      "Stuttgart", "Employee",   95.00, 88.52, 1.0, "all",          0.75],
  // ── CGI-Dev Unreal ──
  ["matt.murdock",    "CGI-Dev",                   "Dev Unreal",                 "Daimler",           "Muenchen",  "Employee",  118.35, 88.52, 1.0, "all",          1.0 ],
  ["carl.lucas",      "CGI-Dev",                   "Dev Unreal",                 "Daimler",           "Muenchen",  "Employee",  133.77, 74.65, 0.5, "all",          0.75],
  ["jessica.jones",   "CGI-Dev",                   "Dev Unreal",                 "Porsche AG",        "Stuttgart", "Employee",   76.64, 55.98, 1.0, "all",          0.85],
  ["danny.rand",      "CGI-Dev",                   "Dev Unreal",                 "Porsche AG",        "Stuttgart", "Employee",  118.35, 88.52, 1.0, "all",          0.75],
  // ── CGI-Dev Frontend ──
  ["frank.castle",    "CGI-Dev",                   "Dev Frontend",               "Daimler",           "Hamburg",   "Employee",   96.77, 65.24, 0.5, "all",          0.75],
  ["carol.danvers",   "CGI-Dev",                   "Dev Frontend",               "Moving Image",      "Stuttgart", "Freelancer", 76.64, 55.98, 1.0, "all",          0.85],
  ["kamala.khan",     "CGI-Dev",                   "Dev Frontend",               "Jaguar Land Rover", "Stuttgart", "Freelancer", 76.64, 55.98, 1.0, "all",          0.75],
];

// ─── Project data ──────────────────────────────────────────────────────────────
// [shortCode, name, clientTag, isOrdered, orderTypeStr, winProb, allocTypeStr, budgetCents]
type ProjectRow = [string, string, string, boolean, string, number, string, number];

const PROJECT_DATA: ProjectRow[] = [
  // ── Completed 3D Stills ────────────────────────────────────────────────────
  ["PORS24A", "Porsche 911 GT3 Campaign Stills",          "PAG", true,  "CHARGEABLE", 100, "EXT", 11500000],
  ["BMW24B",  "BMW M5 Competition Pack",                  "BMW", true,  "CHARGEABLE", 100, "EXT",  8800000],
  ["JLR24C",  "Jaguar F-Type Reveal Stills",              "JLR", true,  "CHARGEABLE", 100, "EXT",  6700000],
  ["DAI24E",  "Mercedes AMG Night Edition Stills",        "DAI", true,  "CHARGEABLE", 100, "EXT",  9200000],
  ["JLR24G",  "Defender Trail Series Stills",             "JLR", true,  "BD",         100, "EXT",  5500000],
  ["AUDI25C", "Audi Q8 e-tron Campaign Stills",           "PAG", true,  "CHARGEABLE", 100, "EXT", 10500000],
  ["JLR25E",  "Range Rover Lifestyle Stills",             "JLR", true,  "CHARGEABLE", 100, "EXT",  7200000],
  ["DAI25F",  "Mercedes S-Class Interior Viz",            "DAI", true,  "CHARGEABLE", 100, "EXT",  9800000],
  ["BMW25H",  "BMW M3 Competition Still Pack",            "BMW", true,  "CHARGEABLE", 100, "EXT",  8500000],
  // ── Completed Animated Movies ──────────────────────────────────────────────
  ["HERO24D", "Heritage Brand Film Stuttgart",            "PAG", true,  "CHARGEABLE", 100, "EXT", 28500000],
  ["BMW24F",  "BMW iX Vision Brand Film",                 "BMW", true,  "CHARGEABLE", 100, "EXT", 34000000],
  ["DAI24H",  "AMG GT Campaign 2024",                     "DAI", true,  "CHARGEABLE", 100, "EXT", 21000000],
  ["JLR25A",  "Defender Chronicles Pilot Film",           "JLR", true,  "CHARGEABLE", 100, "EXT", 43500000],
  ["PAG25B",  "Porsche 75 Years Anniversary Film",        "PAG", true,  "CHARGEABLE", 100, "EXT", 44500000],
  ["BMW25D",  "MINI Electric Short Film",                 "BMW", true,  "CHARGEABLE", 100, "EXT", 19500000],
  // ── Completed Pipeline / Internal ─────────────────────────────────────────
  ["DEV24A",  "Render Farm v3 Migration",                 "INT", true,  "OVERHEAD",   100, "INT",  5200000],
  ["DEV25A",  "Houdini UE5 Pipeline Bridge",              "INT", true,  "INTERNAL",   100, "INT",  7800000],
  // ── Active Animated Movies ─────────────────────────────────────────────────
  ["PAG25G",  "Porsche Taycan Sport Film",                "PAG", true,  "CHARGEABLE", 100, "EXT", 32000000],
  ["JLR26A",  "Jaguar EV Launch Film",                    "JLR", true,  "CHARGEABLE", 100, "EXT", 38500000],
  // ── Active Pipeline ────────────────────────────────────────────────────────
  ["DEV25B",  "Asset Library & Pipeline Rebuild",         "INT", true,  "OVERHEAD",   100, "INT",  6500000],
  // ── Active 3D Stills ───────────────────────────────────────────────────────
  ["DAI26B",  "AMG EV Reveal Campaign Stills",            "DAI", true,  "CHARGEABLE", 100, "EXT", 12500000],
  ["PAG26C",  "Porsche Carrera Grand Viz",                "PAG", true,  "CHARGEABLE", 100, "EXT", 11000000],
  // ── Draft 3D Stills ────────────────────────────────────────────────────────
  ["BMW26B",  "BMW X5 Facelift Campaign",                 "BMW", false, "CHARGEABLE",  80, "EXT",  9500000],
  ["BMW26C",  "MINI Aceman Launch Campaign",              "BMW", false, "CHARGEABLE",  75, "EXT",  7800000],
  // ── Draft Animated Movies ──────────────────────────────────────────────────
  ["JLR26B",  "Defender 90 Anniversary Film",             "JLR", false, "CHARGEABLE",  90, "EXT", 41000000],
  ["PAG26D",  "Porsche Mission X Concept Film",           "PAG", false, "BD",          60, "EXT", 45000000],
  ["DAI26C",  "Mercedes G-Class Offroad Film",            "DAI", false, "CHARGEABLE",  85, "EXT", 29500000],
  // ── Draft Pipeline ─────────────────────────────────────────────────────────
  ["DEV26A",  "UE5 Realtime Pipeline v4",                 "INT", false, "INTERNAL",   100, "INT",  8500000],
];

// shortCode → [startDate, endDate, status]
const PROJECT_DATES: Record<string, [string, string, ProjectStatus]> = {
  // Completed 3D Stills
  PORS24A: ["2024-02-05", "2024-03-15", ProjectStatus.COMPLETED],
  BMW24B:  ["2024-03-18", "2024-05-03", ProjectStatus.COMPLETED],
  JLR24C:  ["2024-04-08", "2024-05-17", ProjectStatus.COMPLETED],
  DAI24E:  ["2024-06-03", "2024-07-12", ProjectStatus.COMPLETED],
  JLR24G:  ["2024-09-02", "2024-10-11", ProjectStatus.COMPLETED],
  AUDI25C: ["2025-05-05", "2025-06-20", ProjectStatus.COMPLETED],
  JLR25E:  ["2025-08-04", "2025-09-26", ProjectStatus.COMPLETED],
  DAI25F:  ["2025-09-01", "2025-10-17", ProjectStatus.COMPLETED],
  BMW25H:  ["2025-11-03", "2025-12-31", ProjectStatus.COMPLETED],
  // Completed Animated Movies
  HERO24D: ["2024-05-06", "2024-09-27", ProjectStatus.COMPLETED],
  BMW24F:  ["2024-08-05", "2024-12-20", ProjectStatus.COMPLETED],
  DAI24H:  ["2024-10-07", "2025-01-31", ProjectStatus.COMPLETED],
  JLR25A:  ["2025-02-03", "2025-09-30", ProjectStatus.COMPLETED],
  PAG25B:  ["2025-04-01", "2025-12-19", ProjectStatus.COMPLETED],
  BMW25D:  ["2025-07-07", "2025-11-28", ProjectStatus.COMPLETED],
  // Completed Pipeline
  DEV24A:  ["2024-07-01", "2024-08-30", ProjectStatus.COMPLETED],
  DEV25A:  ["2025-06-02", "2025-09-30", ProjectStatus.COMPLETED],
  // Active (currently running — today is 2026-03-04)
  PAG25G:  ["2025-10-01", "2026-03-31", ProjectStatus.ACTIVE],
  JLR26A:  ["2026-01-05", "2026-07-31", ProjectStatus.ACTIVE],
  DEV25B:  ["2025-11-03", "2026-04-30", ProjectStatus.ACTIVE],
  DAI26B:  ["2026-02-02", "2026-04-17", ProjectStatus.ACTIVE],
  PAG26C:  ["2026-02-16", "2026-04-24", ProjectStatus.ACTIVE],
  // Draft / Planned
  BMW26B:  ["2026-05-04", "2026-06-26", ProjectStatus.DRAFT],
  BMW26C:  ["2026-10-01", "2026-11-27", ProjectStatus.DRAFT],
  JLR26B:  ["2026-06-01", "2026-11-30", ProjectStatus.DRAFT],
  PAG26D:  ["2026-07-01", "2027-01-31", ProjectStatus.DRAFT],
  DAI26C:  ["2026-09-01", "2027-02-28", ProjectStatus.DRAFT],
  DEV26A:  ["2026-05-04", "2026-08-28", ProjectStatus.DRAFT],
};

function parseOrderType(s: string): OrderType {
  switch (s) {
    case "BD":         return OrderType.BD;
    case "CHARGEABLE": return OrderType.CHARGEABLE;
    case "INTERNAL":   return OrderType.INTERNAL;
    case "OVERHEAD":   return OrderType.OVERHEAD;
    default:           return OrderType.CHARGEABLE;
  }
}

function parseAllocationType(s: string): AllocationType {
  return s === "INT" ? AllocationType.INT : AllocationType.EXT;
}

// ─── Main ──────────────────────────────────────────────────────────────────────

async function main() {
  const target = assertSafeSeedTarget("db:seed");
  console.warn(`Seeding CapaKraken example data into ${target.databaseName} (${target.hostname}${target.port ? `:${target.port}` : ""})...`);

  // ── 1. Delete all data (keep users) ────────────────────────────────────────
  console.warn(`Deleting existing data from disposable seed target '${target.databaseName}'...`);
  await prisma.auditLog.deleteMany({});
  await prisma.notification.deleteMany({});
  // Estimates (deep hierarchy)
  await prisma.estimateExport.deleteMany({});
  await prisma.estimateMetric.deleteMany({});
  await prisma.estimateDemandLine.deleteMany({});
  await prisma.estimateAssumption.deleteMany({});
  await prisma.resourceCostSnapshot.deleteMany({});
  await prisma.estimateVersion.deleteMany({});
  await prisma.estimate.deleteMany({});
  // Assignments + demands before projects/resources
  await prisma.assignment.deleteMany({});
  await prisma.demandRequirement.deleteMany({});
  await prisma.resourceRole.deleteMany({});
  await prisma.vacation.deleteMany({});
  await prisma.vacationEntitlement.deleteMany({});
  await prisma.calculationRule.deleteMany({});
  await prisma.project.deleteMany({});
  await prisma.resource.deleteMany({});
  await prisma.role.deleteMany({});
  await prisma.blueprint.deleteMany({});
  // Dispo v2 entities (children before parents)
  await prisma.managementLevel.deleteMany({});
  await prisma.managementLevelGroup.deleteMany({});
  await prisma.metroCity.deleteMany({});
  await prisma.country.deleteMany({});
  await prisma.orgUnit.deleteMany({});
  await prisma.utilizationCategory.deleteMany({});
  await prisma.client.deleteMany({});
  console.warn("Existing data deleted.");

  // ── 2. Upsert users ────────────────────────────────────────────────────────
  const adminHash = await hash("admin123");
  const managerHash = await hash("manager123");
  const viewerHash = await hash("viewer123");

  const admin = await prisma.user.upsert({
    where: { email: "admin@capakraken.dev" },
    update: { passwordHash: adminHash },
    create: { email: "admin@capakraken.dev", name: "Admin User", passwordHash: adminHash, systemRole: SystemRole.ADMIN },
  });

  const manager = await prisma.user.upsert({
    where: { email: "manager@capakraken.dev" },
    update: { passwordHash: managerHash },
    create: { email: "manager@capakraken.dev", name: "Manager User", passwordHash: managerHash, systemRole: SystemRole.MANAGER },
  });

  const viewer = await prisma.user.upsert({
    where: { email: "viewer@capakraken.dev" },
    update: { passwordHash: viewerHash },
    create: { email: "viewer@capakraken.dev", name: "Viewer User", passwordHash: viewerHash, systemRole: SystemRole.VIEWER },
  });

  console.warn(`Users: admin=${admin.id}, manager=${manager.id}, viewer=${viewer.id}`);
  await seedSystemRoleConfigs();

  // ── 2b. Create Dispo v2 entities ──────────────────────────────────────────

  // Countries + Metro Cities
  const countryDE = await prisma.country.create({
    data: { code: "DE", name: "Germany", dailyWorkingHours: 8.0 },
  });
  const countryIN = await prisma.country.create({
    data: { code: "IN", name: "India", dailyWorkingHours: 9.0 },
  });
  const countryES = await prisma.country.create({
    data: {
      code: "ES",
      name: "Spain",
      dailyWorkingHours: 8.0,
      scheduleRules: {
        type: "spain",
        regularHours: 8.5,
        fridayHours: 7,
        summerHours: 7,
        summerPeriod: { from: "06-15", to: "09-15" },
      } as unknown as Prisma.InputJsonValue,
    },
  });
  const countryUS = await prisma.country.create({
    data: { code: "US", name: "United States", dailyWorkingHours: 8.0 },
  });

  const cityMap = new Map<string, string>(); // cityName → id
  for (const [countryId, cities] of [
    [countryDE.id, ["Augsburg", "Berlin", "Hamburg", "Koeln", "Muenchen", "Stuttgart"]],
    [countryIN.id, ["Bangalore", "Mumbai"]],
    [countryES.id, ["Madrid", "Barcelona"]],
    [countryUS.id, ["New York", "Los Angeles"]],
  ] as [string, string[]][]) {
    for (const cityName of cities) {
      const city = await prisma.metroCity.create({
        data: { name: cityName, countryId },
      });
      cityMap.set(cityName, city.id);
    }
  }
  console.warn(`Countries: 4 created, Metro Cities: ${cityMap.size} created`);

  // Org Units (3-level hierarchy: L5 → L6 → L7)
  const orgUnitMap = new Map<string, string>(); // name → id
  const l5 = await prisma.orgUnit.create({
    data: { name: "Studio Services", level: 5, sortOrder: 1 },
  });
  orgUnitMap.set("Studio Services", l5.id);

  const l6ContentProd = await prisma.orgUnit.create({
    data: { name: "Content Production", level: 6, parentId: l5.id, sortOrder: 1 },
  });
  orgUnitMap.set("Content Production", l6ContentProd.id);
  for (const [name, order] of [["3D Visualization", 1], ["Animation", 2], ["Art Direction", 3]] as [string, number][]) {
    const unit = await prisma.orgUnit.create({
      data: { name, level: 7, parentId: l6ContentProd.id, sortOrder: order },
    });
    orgUnitMap.set(name, unit.id);
  }

  const l6Tech = await prisma.orgUnit.create({
    data: { name: "Technology", level: 6, parentId: l5.id, sortOrder: 2 },
  });
  orgUnitMap.set("Technology", l6Tech.id);
  for (const [name, order] of [["CGI Development", 1], ["Pipeline Engineering", 2]] as [string, number][]) {
    const unit = await prisma.orgUnit.create({
      data: { name, level: 7, parentId: l6Tech.id, sortOrder: order },
    });
    orgUnitMap.set(name, unit.id);
  }

  const l6Ops = await prisma.orgUnit.create({
    data: { name: "Operations", level: 6, parentId: l5.id, sortOrder: 3 },
  });
  orgUnitMap.set("Operations", l6Ops.id);
  for (const [name, order] of [["Product Data Management", 1], ["Project Management", 2]] as [string, number][]) {
    const unit = await prisma.orgUnit.create({
      data: { name, level: 7, parentId: l6Ops.id, sortOrder: order },
    });
    orgUnitMap.set(name, unit.id);
  }
  console.warn(`Org Units: ${orgUnitMap.size} created`);

  // Utilization Categories
  const utilCatMap = new Map<string, string>(); // code → id
  const UTIL_CATS = [
    { code: "Chg", name: "Chargeable", isDefault: true, sortOrder: 1 },
    { code: "BD", name: "Business Development", sortOrder: 2 },
    { code: "MD&I", name: "Market Development & Innovation", sortOrder: 3 },
    { code: "M&O", name: "Management & Operations", sortOrder: 4 },
    { code: "PD&R", name: "People Development & Recruiting", sortOrder: 5 },
    { code: "Absence", name: "Absence", sortOrder: 6 },
  ];
  for (const cat of UTIL_CATS) {
    const created = await prisma.utilizationCategory.create({ data: cat });
    utilCatMap.set(cat.code, created.id);
  }
  console.warn(`Utilization Categories: ${utilCatMap.size} created`);

  // Management Level Groups + Levels
  const mgmtGroupMap = new Map<string, string>(); // groupName → id
  const mgmtLevelMap = new Map<string, string>(); // levelName → id
  const MGMT_GROUPS = [
    { name: "Accenture Leadership", target: 0.365, levels: ["CL10-Managing Director", "CL9-Senior Managing Director"] },
    { name: "Senior Manager", target: 0.546, levels: ["CL8-Senior Manager"] },
    { name: "Manager", target: 0.747, levels: ["CL7-Manager"] },
    { name: "Consultant", target: 0.808, levels: ["CL6-Consultant", "CL5-Senior Analyst"] },
    { name: "Analyst", target: 0.805, levels: ["CL4-Analyst"] },
    { name: "Associate", target: 0.77, levels: ["CL3-Associate", "CL2-Junior Associate"] },
  ];
  for (const g of MGMT_GROUPS) {
    const group = await prisma.managementLevelGroup.create({
      data: { name: g.name, targetPercentage: g.target, sortOrder: MGMT_GROUPS.indexOf(g) + 1 },
    });
    mgmtGroupMap.set(g.name, group.id);
    for (const levelName of g.levels) {
      const level = await prisma.managementLevel.create({
        data: { name: levelName, groupId: group.id },
      });
      mgmtLevelMap.set(levelName, level.id);
    }
  }
  console.warn(`Management Level Groups: ${mgmtGroupMap.size}, Levels: ${mgmtLevelMap.size} created`);

  // Clients (hierarchy: Master → Entity)
  const clientMap = new Map<string, string>(); // name → id
  const CLIENT_TREE = [
    { master: "Automotive OEM", entities: ["Porsche AG", "BMW Group", "Daimler / Mercedes", "Jaguar Land Rover"] },
    { master: "Moving Image & Digital", entities: ["Moving Image", "Cross-Unit"] },
    { master: "Internal", entities: ["Internal Projects"] },
  ];
  for (const tree of CLIENT_TREE) {
    const master = await prisma.client.create({
      data: { name: tree.master, sortOrder: CLIENT_TREE.indexOf(tree) + 1 },
    });
    clientMap.set(tree.master, master.id);
    for (const entityName of tree.entities) {
      const entity = await prisma.client.create({
        data: { name: entityName, parentId: master.id, sortOrder: tree.entities.indexOf(entityName) + 1 },
      });
      clientMap.set(entityName, entity.id);
    }
  }
  console.warn(`Clients: ${clientMap.size} created`);

  // ── 3. Create blueprints ───────────────────────────────────────────────────

  // Shared option sets
  const deliveryFormatOptions = [
    { value: "WebHD_1080p", label: "Web HD (1080p)" },
    { value: "4K_UHD",      label: "4K UHD (3840×2160)" },
    { value: "8K",          label: "8K (7680×4320)" },
    { value: "DCP",         label: "DCP (Cinema)" },
    { value: "Custom",      label: "Custom / TBD" },
  ];
  const frameRateOptions = [
    { value: "24", label: "24 fps (Film)" },
    { value: "25", label: "25 fps (PAL)" },
    { value: "30", label: "30 fps (NTSC)" },
    { value: "60", label: "60 fps (HFR)" },
  ];
  const colorSpaceOptions = [
    { value: "sRGB_Rec709", label: "sRGB / Rec.709" },
    { value: "DCI-P3",      label: "DCI-P3 (Cinema)" },
    { value: "Rec2020_HDR", label: "Rec.2020 / HDR" },
  ];
  const classificationOptions = [
    { value: "Confidential",     label: "Confidential" },
    { value: "Not Confidential", label: "Not Confidential" },
  ];

  const resourceBlueprint = await prisma.blueprint.create({
    data: {
      name: "Studio Resource Blueprint",
      target: BlueprintTarget.RESOURCE,
      description: "Standard fields for 3D studio resources",
      fieldDefs: [
        // Group: Basic Info
        { id: "fd-client-unit",       label: "Client Unit / Account",           key: "clientUnit",       type: FieldType.TEXT,         required: false, order: 0,  group: "Basic Info" },
        { id: "fd-work-type",         label: "Type of Work / Specialization",   key: "workType",         type: FieldType.TEXT,         required: false, order: 1,  group: "Basic Info" },
        { id: "fd-city",              label: "Office Location (Metro City)",     key: "city",             type: FieldType.TEXT,         required: false, order: 2,  group: "Basic Info" },
        { id: "fd-employee-type",     label: "Employee Type",                   key: "employeeType",     type: FieldType.SELECT,       required: false, order: 3,  group: "Basic Info",
          options: [
            { value: "Employee",   label: "Employee" },
            { value: "Freelancer", label: "Freelancer" },
            { value: "Intern",     label: "Intern" },
            { value: "External",   label: "External Contractor" },
          ],
        },
        // Group: Work Setup
        { id: "fd-remote-eligible",   label: "Eligible for Remote Work",        key: "remoteEligible",   type: FieldType.BOOLEAN,      required: false, order: 4,  group: "Work Setup" },
        { id: "fd-timezone",          label: "Timezone",                        key: "timezone",         type: FieldType.SELECT,       required: false, order: 5,  group: "Work Setup",
          options: [
            { value: "UTC-5",   label: "UTC-5 (EST)" },
            { value: "UTC-4",   label: "UTC-4 (EDT)" },
            { value: "UTC+0",   label: "UTC+0 (GMT/WET)" },
            { value: "UTC+1",   label: "UTC+1 (CET)" },
            { value: "UTC+2",   label: "UTC+2 (EET/CEST)" },
            { value: "UTC+3",   label: "UTC+3 (MSK)" },
            { value: "UTC+5.5", label: "UTC+5:30 (IST)" },
            { value: "UTC+8",   label: "UTC+8 (CST/HKT)" },
            { value: "UTC+9",   label: "UTC+9 (JST)" },
          ],
        },
        { id: "fd-primary-software",  label: "Primary Software",                key: "primarySoftware",  type: FieldType.MULTI_SELECT, required: false, order: 6,  group: "Work Setup",
          options: [
            { value: "Maya",             label: "Maya" },
            { value: "Cinema4D",         label: "Cinema 4D" },
            { value: "Houdini",          label: "Houdini" },
            { value: "Blender",          label: "Blender" },
            { value: "UnrealEngine",     label: "Unreal Engine" },
            { value: "AfterEffects",     label: "After Effects" },
            { value: "Nuke",             label: "Nuke" },
            { value: "Photoshop",        label: "Photoshop" },
            { value: "SubstancePainter", label: "Substance Painter" },
            { value: "ZBrush",           label: "ZBrush" },
            { value: "PremierePro",      label: "Premiere Pro" },
            { value: "DaVinciResolve",   label: "DaVinci Resolve" },
          ],
        },
        // Group: Background
        { id: "fd-years-experience",  label: "Years of Industry Experience",    key: "yearsOfExperience", type: FieldType.NUMBER,      required: false, order: 7,  group: "Background", description: "Total years working in the industry" },
        { id: "fd-languages",         label: "Spoken Languages",                key: "spokenLanguages",   type: FieldType.TEXT,        required: false, order: 8,  group: "Background", placeholder: "e.g. English, German, French" },
        { id: "fd-portfolio-notes",   label: "Portfolio / Work Notes",          key: "portfolioNotes",    type: FieldType.TEXTAREA,    required: false, order: 9,  group: "Background", description: "Links or notes about portfolio / notable projects" },
        { id: "fd-internal-notes",    label: "Internal Notes",                  key: "internalNotes",     type: FieldType.TEXTAREA,    required: false, order: 10, group: "Background", description: "HR / team notes (not visible to the resource)" },
      ],
      defaults: {},
      validationRules: [],
    },
  });

  const projectBlueprint = await prisma.blueprint.create({
    data: {
      name: "Studio Project Blueprint",
      target: BlueprintTarget.PROJECT,
      description: "Standard fields for client and internal projects",
      fieldDefs: [
        // Group: Client & Billing
        { id: "fd-proj-client-unit",   label: "Client Unit Tag",               key: "clientUnit",           type: FieldType.TEXT,     required: false, order: 0,  group: "Client & Billing", placeholder: "e.g. [DAI], [BMW]" },
        { id: "fd-person-hours-sold",  label: "Person Hours Sold",             key: "personHoursSold",      type: FieldType.NUMBER,   required: false, order: 1,  group: "Client & Billing", description: "Planned billable person hours agreed with client" },
        { id: "fd-classification",     label: "Classification",                key: "classification",       type: FieldType.SELECT,   required: false, order: 2,  group: "Client & Billing", options: classificationOptions },
        { id: "fd-client-contact",     label: "Client Contact / Account Mgr",  key: "clientContact",        type: FieldType.TEXT,     required: false, order: 3,  group: "Client & Billing" },
        { id: "fd-crm-reference",      label: "CRM Reference / Opportunity",   key: "crmReference",         type: FieldType.TEXT,     required: false, order: 4,  group: "Client & Billing", description: "CRM opportunity ID or ticket reference" },
        // Group: Delivery
        { id: "fd-delivery-deadline",  label: "Final Delivery Date",           key: "deliveryDeadline",     type: FieldType.DATE,     required: false, order: 5,  group: "Delivery" },
        { id: "fd-delivery-format",    label: "Delivery Format",               key: "deliveryFormat",       type: FieldType.SELECT,   required: false, order: 6,  group: "Delivery", options: deliveryFormatOptions },
        { id: "fd-frame-rate",         label: "Frame Rate",                    key: "frameRate",            type: FieldType.SELECT,   required: false, order: 7,  group: "Delivery", options: frameRateOptions },
        { id: "fd-color-space",        label: "Color Space",                   key: "colorSpace",           type: FieldType.SELECT,   required: false, order: 8,  group: "Delivery", options: colorSpaceOptions },
        // Group: Scope
        { id: "fd-approval-rounds",    label: "Client Approval Rounds",        key: "clientApprovalRounds", type: FieldType.NUMBER,   required: false, order: 9,  group: "Scope", description: "Estimated number of client review cycles" },
        { id: "fd-revision-budget",    label: "Revision Budget (hours)",       key: "revisionBudgetHours",  type: FieldType.NUMBER,   required: false, order: 10, group: "Scope", description: "Person-hours reserved for revisions and corrections" },
        { id: "fd-notes",              label: "Project Notes",                 key: "notes",                type: FieldType.TEXTAREA, required: false, order: 11, group: "Scope", description: "Technical or creative notes / special requirements" },
      ],
      defaults: { classification: "Not Confidential" },
      validationRules: [],
    },
  });

  const blueprint3D = await prisma.blueprint.create({
    data: {
      name: "3D Content Production",
      target: BlueprintTarget.PROJECT,
      description: "Blueprint for 3D rendering and stills projects",
      fieldDefs: [
        // Group: Client & Billing
        { id: "fd-3d-client-unit",       label: "Client Unit Tag",               key: "clientUnit",                   type: FieldType.TEXT,     required: false, order: 0,  group: "Client & Billing", placeholder: "e.g. [DAI], [BMW]" },
        { id: "fd-3d-hours-sold",         label: "Person Hours Sold",             key: "personHoursSold",              type: FieldType.NUMBER,   required: false, order: 1,  group: "Client & Billing", description: "Planned billable person hours agreed with client" },
        { id: "fd-3d-classification",     label: "Classification",                key: "classification",               type: FieldType.SELECT,   required: false, order: 2,  group: "Client & Billing", options: classificationOptions },
        { id: "fd-3d-client-contact",     label: "Client Contact / Account Mgr",  key: "clientContact",                type: FieldType.TEXT,     required: false, order: 3,  group: "Client & Billing" },
        { id: "fd-3d-crm",               label: "CRM Reference / Opportunity",   key: "crmReference",                 type: FieldType.TEXT,     required: false, order: 4,  group: "Client & Billing", description: "CRM opportunity ID or ticket reference" },
        // Group: Technical Specs
        { id: "fd-3d-render-engine",     label: "Render Engine",                 key: "renderEngine",                 type: FieldType.SELECT,   required: false, order: 5,  group: "Technical Specs",
          options: [
            { value: "Arnold",   label: "Arnold" },
            { value: "VRay",     label: "V-Ray" },
            { value: "Redshift", label: "Redshift" },
            { value: "Cycles",   label: "Cycles (Blender)" },
            { value: "Octane",   label: "Octane" },
            { value: "Corona",   label: "Corona" },
            { value: "KeyShot",  label: "KeyShot" },
          ],
        },
        { id: "fd-3d-render-farm",       label: "Render Farm",                   key: "renderFarm",                   type: FieldType.SELECT,   required: false, order: 6,  group: "Technical Specs",
          options: [
            { value: "InhouseCPU", label: "In-house CPU" },
            { value: "InhouseGPU", label: "In-house GPU" },
            { value: "CloudAWS",   label: "Cloud (AWS)" },
            { value: "CloudGCP",   label: "Cloud (GCP)" },
            { value: "Hybrid",     label: "Hybrid" },
          ],
        },
        { id: "fd-3d-delivery-format",   label: "Delivery Format",               key: "deliveryFormat",               type: FieldType.SELECT,   required: false, order: 7,  group: "Technical Specs", options: deliveryFormatOptions },
        { id: "fd-3d-frame-rate",        label: "Frame Rate",                    key: "frameRate",                    type: FieldType.SELECT,   required: false, order: 8,  group: "Technical Specs", options: frameRateOptions },
        { id: "fd-3d-color-space",       label: "Color Space",                   key: "colorSpace",                   type: FieldType.SELECT,   required: false, order: 9,  group: "Technical Specs", options: colorSpaceOptions },
        { id: "fd-3d-texture-res",       label: "Texture Resolution",            key: "textureResolution",            type: FieldType.SELECT,   required: false, order: 10, group: "Technical Specs",
          options: [
            { value: "2K", label: "2K Textures" },
            { value: "4K", label: "4K Textures" },
            { value: "8K", label: "8K Textures" },
          ],
        },
        // Group: Asset Scope
        { id: "fd-3d-num-assets",        label: "Number of Assets",              key: "numberOfAssets",               type: FieldType.NUMBER,   required: false, order: 11, group: "Asset Scope", description: "Total 3D models / assets to produce" },
        { id: "fd-3d-asset-complexity",  label: "Asset Complexity",              key: "assetComplexity",              type: FieldType.SELECT,   required: false, order: 12, group: "Asset Scope",
          options: [
            { value: "Low",      label: "Low" },
            { value: "Medium",   label: "Medium" },
            { value: "High",     label: "High" },
            { value: "VeryHigh", label: "Very High" },
          ],
        },
        { id: "fd-3d-lighting-setups",   label: "Lighting Setups",               key: "numberOfLightingSetups",       type: FieldType.NUMBER,   required: false, order: 13, group: "Asset Scope", description: "Number of distinct lighting scenarios" },
        { id: "fd-3d-render-hours",      label: "Render Hours / Frame",          key: "estimatedRenderHoursPerFrame", type: FieldType.NUMBER,   required: false, order: 14, group: "Asset Scope" },
        { id: "fd-3d-iterations",        label: "Iterations per Asset",          key: "numberOfIterations",           type: FieldType.NUMBER,   required: false, order: 15, group: "Asset Scope" },
        { id: "fd-3d-post-processing",   label: "Post-Processing Required",      key: "postProcessingRequired",       type: FieldType.BOOLEAN,  required: false, order: 16, group: "Asset Scope", description: "Compositing / retouching needed" },
        // Group: Scope
        { id: "fd-3d-scope-approval-rounds",  label: "Client Approval Rounds",   key: "clientApprovalRounds",         type: FieldType.NUMBER,   required: false, order: 17, group: "Scope", description: "Estimated number of client review cycles" },
        { id: "fd-3d-scope-revision-budget",  label: "Revision Budget (hours)",  key: "revisionBudgetHours",          type: FieldType.NUMBER,   required: false, order: 18, group: "Scope", description: "Person-hours reserved for revisions and corrections" },
        { id: "fd-3d-scope-notes",            label: "Project Notes",            key: "notes",                        type: FieldType.TEXTAREA, required: false, order: 19, group: "Scope", description: "Technical or creative notes / special requirements" },
      ],
      defaults: { classification: "Not Confidential" },
      validationRules: [],
      rolePresets: [
        { id: "rp-3d-pm",   role: "Project Manager",   requiredSkills: ["Project Manager"],                 hoursPerDay: 4, headcount: 1 },
        { id: "rp-3d-lead", role: "3D Lead",            requiredSkills: ["3D Modeling", "3D Lighting"],      hoursPerDay: 8, headcount: 1 },
        { id: "rp-3d-art",  role: "3D Artist",          requiredSkills: ["3D Modeling"],                     hoursPerDay: 8, headcount: 2 },
        { id: "rp-3d-comp", role: "Compositor",         requiredSkills: ["Compositing"],                     hoursPerDay: 8, headcount: 1 },
        { id: "rp-3d-ad",   role: "Art Director",       requiredSkills: ["Art Direction"],                   hoursPerDay: 4, headcount: 1 },
        { id: "rp-3d-td",   role: "Technical Director", requiredSkills: ["Pipeline", "3D Modeling"],         hoursPerDay: 6, headcount: 1 },
      ],
    },
  });

  const blueprintAnimation = await prisma.blueprint.create({
    data: {
      name: "Animation Production",
      target: BlueprintTarget.PROJECT,
      description: "Blueprint for animated films and motion projects",
      fieldDefs: [
        // Group: Client & Billing
        { id: "fd-anim-client-unit",         label: "Client Unit Tag",               key: "clientUnit",           type: FieldType.TEXT,     required: false, order: 0,  group: "Client & Billing", placeholder: "e.g. [DAI], [BMW]" },
        { id: "fd-anim-hours-sold",          label: "Person Hours Sold",             key: "personHoursSold",      type: FieldType.NUMBER,   required: false, order: 1,  group: "Client & Billing", description: "Planned billable person hours agreed with client" },
        { id: "fd-anim-classification",      label: "Classification",                key: "classification",       type: FieldType.SELECT,   required: false, order: 2,  group: "Client & Billing", options: classificationOptions },
        { id: "fd-anim-client-contact",      label: "Client Contact / Account Mgr",  key: "clientContact",        type: FieldType.TEXT,     required: false, order: 3,  group: "Client & Billing" },
        { id: "fd-anim-crm",                 label: "CRM Reference / Opportunity",   key: "crmReference",         type: FieldType.TEXT,     required: false, order: 4,  group: "Client & Billing", description: "CRM opportunity ID or ticket reference" },
        // Group: Animation Specs
        { id: "fd-anim-style",               label: "Animation Style",               key: "animationStyle",       type: FieldType.SELECT,   required: false, order: 5,  group: "Animation Specs",
          options: [
            { value: "Realistic",     label: "Realistic / Photoreal" },
            { value: "Stylized",      label: "Stylized" },
            { value: "MotionCapture", label: "Motion Capture" },
            { value: "Procedural",    label: "Procedural" },
            { value: "CelShaded",     label: "Cel-Shaded / Toon" },
            { value: "Mixed",         label: "Mixed / Hybrid" },
          ],
        },
        { id: "fd-anim-duration",            label: "Duration (seconds)",            key: "durationSeconds",      type: FieldType.NUMBER,   required: false, order: 6,  group: "Animation Specs" },
        { id: "fd-anim-scenes",              label: "Number of Scenes",              key: "sceneCount",           type: FieldType.NUMBER,   required: false, order: 7,  group: "Animation Specs" },
        { id: "fd-anim-shots",               label: "Number of Shots",               key: "shotCount",            type: FieldType.NUMBER,   required: false, order: 8,  group: "Animation Specs" },
        { id: "fd-anim-delivery",            label: "Delivery Format",               key: "deliveryFormat",       type: FieldType.SELECT,   required: false, order: 9,  group: "Animation Specs", options: deliveryFormatOptions },
        { id: "fd-anim-fps",                 label: "Frame Rate",                    key: "frameRate",            type: FieldType.SELECT,   required: false, order: 10, group: "Animation Specs", options: frameRateOptions },
        // Group: Characters & Rigging
        { id: "fd-anim-chars",               label: "Number of Characters",          key: "characterCount",       type: FieldType.NUMBER,   required: false, order: 11, group: "Characters & Rigging" },
        { id: "fd-anim-rig-complexity",      label: "Rig Complexity",                key: "rigComplexity",        type: FieldType.SELECT,   required: false, order: 12, group: "Characters & Rigging",
          options: [
            { value: "Simple",   label: "Simple (basic bones)" },
            { value: "Standard", label: "Standard (FK/IK)" },
            { value: "Complex",  label: "Complex (full-body IK)" },
            { value: "Hero",     label: "Hero (simulation + secondary motion)" },
          ],
        },
        { id: "fd-anim-mocap",               label: "Motion Capture Required",       key: "mocapRequired",        type: FieldType.BOOLEAN,  required: false, order: 13, group: "Characters & Rigging" },
        { id: "fd-anim-storyboard",          label: "Storyboard Provided",           key: "storyboardProvided",   type: FieldType.BOOLEAN,  required: false, order: 14, group: "Characters & Rigging", description: "Client provides storyboard" },
        // Group: Post & Audio
        { id: "fd-anim-music",               label: "Music / Sound Design",          key: "musicPostRequired",       type: FieldType.BOOLEAN, required: false, order: 15, group: "Post & Audio" },
        { id: "fd-anim-colgrade",            label: "Color Grading",                 key: "colorGradingRequired",    type: FieldType.BOOLEAN, required: false, order: 16, group: "Post & Audio" },
        // Group: Scope
        { id: "fd-anim-scope-approval-rounds", label: "Client Approval Rounds",      key: "clientApprovalRounds", type: FieldType.NUMBER,   required: false, order: 17, group: "Scope", description: "Estimated number of client review cycles" },
        { id: "fd-anim-scope-revision-budget", label: "Revision Budget (hours)",     key: "revisionBudgetHours",  type: FieldType.NUMBER,   required: false, order: 18, group: "Scope", description: "Person-hours reserved for revisions and corrections" },
        { id: "fd-anim-scope-notes",           label: "Project Notes",               key: "notes",                type: FieldType.TEXTAREA, required: false, order: 19, group: "Scope", description: "Technical or creative notes / special requirements" },
      ],
      defaults: { classification: "Not Confidential" },
      validationRules: [],
      rolePresets: [
        { id: "rp-anim-pm",   role: "Project Manager",    requiredSkills: ["Project Manager"],            hoursPerDay: 4, headcount: 1 },
        { id: "rp-anim-dir",  role: "Animation Director", requiredSkills: ["Animation", "Unreal Engine"], hoursPerDay: 8, headcount: 1 },
        { id: "rp-anim-anim", role: "Animator",           requiredSkills: ["Animation"],                  hoursPerDay: 8, headcount: 2 },
        { id: "rp-anim-rig",  role: "Rigger / TD",        requiredSkills: ["Rigging"],                    hoursPerDay: 8, headcount: 1 },
        { id: "rp-anim-comp", role: "Compositor",         requiredSkills: ["Compositing"],                hoursPerDay: 8, headcount: 1 },
        { id: "rp-anim-ad",   role: "Art Director",       requiredSkills: ["Art Direction"],              hoursPerDay: 4, headcount: 1 },
      ],
    },
  });

  const blueprintVFX = await prisma.blueprint.create({
    data: {
      name: "VFX / Compositing",
      target: BlueprintTarget.PROJECT,
      description: "Blueprint for VFX and compositing projects",
      fieldDefs: [
        // Group: Client & Billing
        { id: "fd-vfx-client-unit",          label: "Client Unit Tag",               key: "clientUnit",           type: FieldType.TEXT,         required: false, order: 0,  group: "Client & Billing", placeholder: "e.g. [DAI], [BMW]" },
        { id: "fd-vfx-hours-sold",           label: "Person Hours Sold",             key: "personHoursSold",      type: FieldType.NUMBER,       required: false, order: 1,  group: "Client & Billing", description: "Planned billable person hours agreed with client" },
        { id: "fd-vfx-classification",       label: "Classification",                key: "classification",       type: FieldType.SELECT,       required: false, order: 2,  group: "Client & Billing", options: classificationOptions },
        { id: "fd-vfx-client-contact",       label: "Client Contact / Account Mgr",  key: "clientContact",        type: FieldType.TEXT,         required: false, order: 3,  group: "Client & Billing" },
        { id: "fd-vfx-crm",                  label: "CRM Reference / Opportunity",   key: "crmReference",         type: FieldType.TEXT,         required: false, order: 4,  group: "Client & Billing", description: "CRM opportunity ID or ticket reference" },
        // Group: VFX Specs
        { id: "fd-vfx-type",                 label: "VFX Type(s)",                   key: "vfxType",              type: FieldType.MULTI_SELECT, required: false, order: 5,  group: "VFX Specs",
          options: [
            { value: "GreenScreen",    label: "Green Screen / Chroma Key" },
            { value: "CGIIntegration", label: "CGI Integration" },
            { value: "MotionTracking", label: "Motion Tracking" },
            { value: "Rotoscoping",    label: "Rotoscoping" },
            { value: "ParticleFX",    label: "Particle FX" },
            { value: "FluidSim",      label: "Fluid Simulation" },
            { value: "MattePainting", label: "Matte Painting" },
            { value: "TitleSequence", label: "Title Sequence" },
          ],
        },
        { id: "fd-vfx-shot-count",           label: "Number of VFX Shots",           key: "shotCount",            type: FieldType.NUMBER,       required: false, order: 6,  group: "VFX Specs" },
        { id: "fd-vfx-complexity",           label: "Avg. Shot Complexity",           key: "avgShotComplexity",    type: FieldType.SELECT,       required: false, order: 7,  group: "VFX Specs",
          options: [
            { value: "Low",       label: "Low (cleanup / grade)" },
            { value: "Medium",    label: "Medium (integration)" },
            { value: "High",      label: "High (simulation)" },
            { value: "Photoreal", label: "Photoreal" },
          ],
        },
        { id: "fd-vfx-delivery",             label: "Delivery Format",               key: "deliveryFormat",       type: FieldType.SELECT,       required: false, order: 8,  group: "VFX Specs", options: deliveryFormatOptions },
        { id: "fd-vfx-fps",                  label: "Frame Rate",                    key: "frameRate",            type: FieldType.SELECT,       required: false, order: 9,  group: "VFX Specs", options: frameRateOptions },
        { id: "fd-vfx-color-space",          label: "Color Space",                   key: "colorSpace",           type: FieldType.SELECT,       required: false, order: 10, group: "VFX Specs", options: colorSpaceOptions },
        // Group: Source Material
        { id: "fd-vfx-footage",              label: "Footage Provided by Client",     key: "footageProvided",      type: FieldType.BOOLEAN,      required: false, order: 11, group: "Source Material" },
        { id: "fd-vfx-audio-sync",           label: "Audio Sync Required",            key: "audioSyncRequired",   type: FieldType.BOOLEAN,      required: false, order: 12, group: "Source Material" },
        { id: "fd-vfx-onset-sup",            label: "VFX Supervisor On Set",          key: "hasOnSetVFXSup",      type: FieldType.BOOLEAN,      required: false, order: 13, group: "Source Material" },
        // Group: Scope
        { id: "fd-vfx-scope-approval-rounds", label: "Client Approval Rounds",       key: "clientApprovalRounds", type: FieldType.NUMBER,       required: false, order: 14, group: "Scope", description: "Estimated number of client review cycles" },
        { id: "fd-vfx-scope-revision-budget", label: "Revision Budget (hours)",      key: "revisionBudgetHours",  type: FieldType.NUMBER,       required: false, order: 15, group: "Scope", description: "Person-hours reserved for revisions and corrections" },
        { id: "fd-vfx-scope-notes",           label: "Project Notes",                key: "notes",                type: FieldType.TEXTAREA,     required: false, order: 16, group: "Scope", description: "Technical or creative notes / special requirements" },
      ],
      defaults: { classification: "Not Confidential" },
      validationRules: [],
      rolePresets: [
        { id: "rp-vfx-producer",  role: "VFX Producer",        requiredSkills: ["Project Manager"],                  hoursPerDay: 4, headcount: 1 },
        { id: "rp-vfx-sup",       role: "VFX Supervisor",      requiredSkills: ["Compositing", "Art Direction"],      hoursPerDay: 6, headcount: 1 },
        { id: "rp-vfx-sr-comp",   role: "Senior Compositor",   requiredSkills: ["Compositing", "Nuke"],              hoursPerDay: 8, headcount: 2 },
        { id: "rp-vfx-comp",      role: "Compositor",          requiredSkills: ["Compositing"],                      hoursPerDay: 8, headcount: 1 },
        { id: "rp-vfx-roto",      role: "Roto / Paint Artist", requiredSkills: ["Rotoscoping"],                      hoursPerDay: 8, headcount: 1 },
        { id: "rp-vfx-tracker",   role: "Motion Tracker",      requiredSkills: ["Motion Tracking"],                  hoursPerDay: 8, headcount: 1 },
      ],
    },
  });

  const blueprintMotion = await prisma.blueprint.create({
    data: {
      name: "Motion Design",
      target: BlueprintTarget.PROJECT,
      description: "Blueprint for motion graphics and animation",
      fieldDefs: [
        // Group: Client & Billing
        { id: "fd-mog-client-unit",          label: "Client Unit Tag",               key: "clientUnit",               type: FieldType.TEXT,         required: false, order: 0,  group: "Client & Billing", placeholder: "e.g. [DAI], [BMW]" },
        { id: "fd-mog-hours-sold",           label: "Person Hours Sold",             key: "personHoursSold",          type: FieldType.NUMBER,       required: false, order: 1,  group: "Client & Billing", description: "Planned billable person hours agreed with client" },
        { id: "fd-mog-classification",       label: "Classification",                key: "classification",           type: FieldType.SELECT,       required: false, order: 2,  group: "Client & Billing", options: classificationOptions },
        { id: "fd-mog-client-contact",       label: "Client Contact / Account Mgr",  key: "clientContact",            type: FieldType.TEXT,         required: false, order: 3,  group: "Client & Billing" },
        { id: "fd-mog-crm",                  label: "CRM Reference / Opportunity",   key: "crmReference",             type: FieldType.TEXT,         required: false, order: 4,  group: "Client & Billing", description: "CRM opportunity ID or ticket reference" },
        // Group: Motion Specs
        { id: "fd-mog-style",                label: "Motion Style",                  key: "motionStyle",              type: FieldType.SELECT,       required: false, order: 5,  group: "Motion Specs",
          options: [
            { value: "Flat2D",      label: "2D Flat / Icon Animation" },
            { value: "KineticType", label: "Kinetic Typography" },
            { value: "TwoHalfD",   label: "2.5D" },
            { value: "ThreeD",     label: "3D Motion" },
            { value: "Mixed",      label: "Mixed / Hybrid" },
          ],
        },
        { id: "fd-mog-duration",             label: "Duration (seconds)",            key: "durationSeconds",          type: FieldType.NUMBER,       required: false, order: 6,  group: "Motion Specs" },
        { id: "fd-mog-formats",              label: "Delivery Formats",              key: "deliveryFormats",          type: FieldType.MULTI_SELECT, required: false, order: 7,  group: "Motion Specs",
          options: [
            { value: "Social_916",    label: "Social (9:16 vertical)" },
            { value: "Landscape_169", label: "Landscape (16:9)" },
            { value: "Square_11",    label: "Square (1:1)" },
            { value: "Banner",       label: "Banner / Display Ads" },
            { value: "Custom",       label: "Custom" },
          ],
        },
        { id: "fd-mog-variants",             label: "Number of Variants",            key: "numberOfVariants",         type: FieldType.NUMBER,       required: false, order: 8,  group: "Motion Specs", description: "Format / language / size variants" },
        // Group: Assets & Design
        { id: "fd-mog-design-system",        label: "Client Design System Provided", key: "hasDesignSystem",          type: FieldType.BOOLEAN,      required: false, order: 9,  group: "Assets & Design", description: "Brand guidelines, fonts, and color palette provided" },
        { id: "fd-mog-storyboard",           label: "Storyboard / Animatic Required",key: "storyboardRequired",       type: FieldType.BOOLEAN,      required: false, order: 10, group: "Assets & Design" },
        { id: "fd-mog-assets",               label: "Design Assets Provided",        key: "assetsProvided",           type: FieldType.BOOLEAN,      required: false, order: 11, group: "Assets & Design", description: "Logos, images, and fonts provided by client" },
        // Group: Post & Audio
        { id: "fd-mog-voiceover",            label: "Voice-Over Required",           key: "voiceoverRequired",        type: FieldType.BOOLEAN,      required: false, order: 12, group: "Post & Audio" },
        { id: "fd-mog-music",                label: "Music Licensing Required",      key: "musicLicensingRequired",   type: FieldType.BOOLEAN,      required: false, order: 13, group: "Post & Audio" },
        { id: "fd-mog-sound",                label: "Custom Sound Design",           key: "soundDesignRequired",      type: FieldType.BOOLEAN,      required: false, order: 14, group: "Post & Audio" },
        // Group: Scope
        { id: "fd-mog-scope-approval-rounds", label: "Client Approval Rounds",       key: "clientApprovalRounds",     type: FieldType.NUMBER,       required: false, order: 15, group: "Scope", description: "Estimated number of client review cycles" },
        { id: "fd-mog-scope-revision-budget", label: "Revision Budget (hours)",      key: "revisionBudgetHours",      type: FieldType.NUMBER,       required: false, order: 16, group: "Scope", description: "Person-hours reserved for revisions and corrections" },
        { id: "fd-mog-scope-notes",           label: "Project Notes",                key: "notes",                   type: FieldType.TEXTAREA,     required: false, order: 17, group: "Scope", description: "Technical or creative notes / special requirements" },
      ],
      defaults: { classification: "Not Confidential" },
      validationRules: [],
      rolePresets: [
        { id: "rp-mog-designer",    role: "Motion Designer",        requiredSkills: ["After Effects", "Motion Design"],                 hoursPerDay: 8, headcount: 2 },
        { id: "rp-mog-sr-designer", role: "Senior Motion Designer", requiredSkills: ["After Effects", "Motion Design", "Art Direction"], hoursPerDay: 8, headcount: 1 },
        { id: "rp-mog-ad",          role: "Art Director",           requiredSkills: ["Art Direction"],                                  hoursPerDay: 4, headcount: 1 },
        { id: "rp-mog-producer",    role: "Producer",               requiredSkills: ["Project Manager"],                                hoursPerDay: 4, headcount: 1 },
        { id: "rp-mog-sound",       role: "Sound Designer",         requiredSkills: ["Sound Design"],                                   hoursPerDay: 4, headcount: 1 },
      ],
    },
  });

  console.warn(`Blueprints: resource=${resourceBlueprint.id}, project=${projectBlueprint.id}, 3D=${blueprint3D.id}, animation=${blueprintAnimation.id}, vfx=${blueprintVFX.id}, motion=${blueprintMotion.id}`);

  // ── 4. Create roles ────────────────────────────────────────────────────────
  const ROLE_SEED = [
    { name: "Project Manager",    color: "#6366f1", description: "Project lead and client liaison" },
    { name: "3D Lead",            color: "#8b5cf6", description: "Senior 3D artist and technical lead" },
    { name: "3D Artist",          color: "#a78bfa", description: "3D modeling, texturing, lighting" },
    { name: "Art Director",       color: "#ec4899", description: "Visual direction and brand alignment" },
    { name: "Unreal Dev",         color: "#14b8a6", description: "Real-time engine development (UE5)" },
    { name: "Frontend Dev",       color: "#22d3ee", description: "Web & tool frontend development" },
    { name: "PDM Specialist",     color: "#f59e0b", description: "Product data management and compositing" },
    { name: "3D Generalist",      color: "#84cc16", description: "General 3D production support" },
    { name: "3D Tech Tester",     color: "#f97316", description: "Pipeline and render QA testing" },
  ];
  const roleMap = new Map<string, string>(); // name → id
  for (const r of ROLE_SEED) {
    const role = await prisma.role.create({
      data: { name: r.name, color: r.color, description: r.description, isActive: true },
    });
    roleMap.set(r.name, role.id);
  }
  console.warn(`Roles: ${roleMap.size} created`);

  // ── 5. Create resources ────────────────────────────────────────────────────
  const resourceMap = new Map<string, Resource>();

  const countryIdByCode = new Map<string, string>([
    ["DE", countryDE.id],
    ["ES", countryES.id],
    ["IN", countryIN.id],
    ["US", countryUS.id],
  ]);

  for (const [index, row] of RESOURCE_DATA.entries()) {
    const [eid, chapter, typeOfWork, clientUnit, , employeeType, lcr, ucr, fraction, availDays, chargeability] = row;
    const holidayProfile = getHolidayDemoProfileForIndex(index);

    const displayName = eid
      .split(".")
      .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
      .join(" ");

    const email       = `${eid}@capakraken.example`;
    const lcrCents    = Math.round(lcr * 100);
    const ucrCents    = Math.round(ucr * 100);
    const availability = computeAvailability(fraction, availDays);
    const skills       = computeSkills(chapter, typeOfWork, lcr);

    // Dispo v2: resolve FKs
    const resCountryId = countryIdByCode.get(holidayProfile.countryCode) ?? countryDE.id;
    const resMetroCityId = cityMap.get(holidayProfile.cityName) ?? null;

    // chapter → orgUnit mapping
    const chapterToOrgUnit: Record<string, string> = {
      "Project Management": "Project Management",
      "Digital Content Production": "3D Visualization",
      "Art Direction": "Art Direction",
      "Product Data Management": "Product Data Management",
      "CGI-Dev": "CGI Development",
    };
    const resOrgUnitId = orgUnitMap.get(chapterToOrgUnit[chapter] ?? "") ?? null;

    // lcr → management level mapping
    let resMgmtGroupName: string;
    let resMgmtLevelName: string;
    if (lcr >= 130) {
      resMgmtGroupName = "Consultant"; resMgmtLevelName = "CL6-Consultant";
    } else if (lcr >= 115) {
      resMgmtGroupName = "Manager"; resMgmtLevelName = "CL7-Manager";
    } else if (lcr >= 90) {
      resMgmtGroupName = "Consultant"; resMgmtLevelName = "CL5-Senior Analyst";
    } else if (lcr >= 75) {
      resMgmtGroupName = "Analyst"; resMgmtLevelName = "CL4-Analyst";
    } else {
      resMgmtGroupName = "Associate"; resMgmtLevelName = "CL3-Associate";
    }
    const resMgmtGroupId = mgmtGroupMap.get(resMgmtGroupName) ?? null;
    const resMgmtLevelId = mgmtLevelMap.get(resMgmtLevelName) ?? null;

    // resourceType
    const resResourceType = employeeType === "Freelancer" ? ResourceType.FREELANCER : ResourceType.EMPLOYEE;

    // clientUnit → client mapping
    const clientUnitToClient: Record<string, string> = {
      "Porsche AG": "Porsche AG",
      "BMW": "BMW Group",
      "Daimler": "Daimler / Mercedes",
      "Jaguar Land Rover": "Jaguar Land Rover",
      "Moving Image": "Moving Image",
      "Cross-Unit": "Cross-Unit",
      "Italy (FER/MAS)": "Porsche AG", // mapped to Porsche AG (Porsche/Ferrari/Maserati group)
    };
    const resClientUnitId = clientMap.get(clientUnitToClient[clientUnit] ?? "") ?? null;

    const resource = await prisma.resource.create({
      data: {
        eid,
        displayName,
        email,
        chapter,
        lcrCents,
        ucrCents,
        currency: "EUR",
        chargeabilityTarget: chargeability * 100,
        availability: availability as unknown as Prisma.InputJsonValue,
        skills: skills as unknown as Prisma.InputJsonValue,
        dynamicFields: {
          clientUnit,
          workType: typeOfWork,
          city: holidayProfile.cityName,
          employeeType,
          holidayCountryCode: holidayProfile.countryCode,
          holidayStateCode: holidayProfile.stateCode,
        },
        blueprintId: resourceBlueprint.id,
        countryId: resCountryId,
        federalState: holidayProfile.stateCode,
        ...(resMetroCityId ? { metroCityId: resMetroCityId } : {}),
        ...(resOrgUnitId ? { orgUnitId: resOrgUnitId } : {}),
        ...(resMgmtGroupId ? { managementLevelGroupId: resMgmtGroupId } : {}),
        ...(resMgmtLevelId ? { managementLevelId: resMgmtLevelId } : {}),
        resourceType: resResourceType,
        fte: fraction,
        chgResponsibility: true,
        enterpriseId: eid,
        ...(resClientUnitId ? { clientUnitId: resClientUnitId } : {}),
      },
    });

    resourceMap.set(eid, resource);
  }

  console.warn(`Resources: ${resourceMap.size} created`);

  // ── 5. Create projects ─────────────────────────────────────────────────────
  const projectMap = new Map<string, Project>();

  for (const row of PROJECT_DATA) {
    const [shortCode, name, clientTag, , orderTypeStr, winProb, allocTypeStr, budgetCents] = row;

    const dates = PROJECT_DATES[shortCode];
    if (!dates) {
      console.warn(`WARNING: no dates for project ${shortCode}, skipping`);
      continue;
    }
    const [startDateStr, endDateStr, status] = dates;

    // Dispo v2: utilizationCategory mapping
    const orderTypeToUtilCat: Record<string, string> = {
      "CHARGEABLE": "Chg",
      "BD": "BD",
      "INTERNAL": "M&O",
      "OVERHEAD": "M&O",
    };
    const projUtilCatId = utilCatMap.get(orderTypeToUtilCat[orderTypeStr] ?? "") ?? null;

    // Dispo v2: client mapping
    const clientTagToClient: Record<string, string> = {
      "PAG": "Porsche AG",
      "BMW": "BMW Group",
      "DAI": "Daimler / Mercedes",
      "JLR": "Jaguar Land Rover",
      "INT": "Internal Projects",
    };
    const projClientId = clientMap.get(clientTagToClient[clientTag] ?? "") ?? null;

    const project = await prisma.project.create({
      data: {
        shortCode,
        name,
        orderType: parseOrderType(orderTypeStr),
        allocationType: parseAllocationType(allocTypeStr),
        winProbability: winProb,
        budgetCents,
        startDate: new Date(startDateStr),
        endDate:   new Date(endDateStr),
        status,
        staffingReqs: [],
        dynamicFields: { clientUnit: clientTag },
        blueprintId: projectBlueprint.id,
        ...(projUtilCatId ? { utilizationCategoryId: projUtilCatId } : {}),
        ...(projClientId ? { clientId: projClientId } : {}),
      },
    });

    projectMap.set(shortCode, project);
  }

  console.warn(`Projects: ${projectMap.size} created`);


  // ── 6. Create demand requirements + assignments ───────────────────────────
  // Seed planning data for active and draft projects

  // Helper: compute dailyCostCents from resource LCR and hoursPerDay
  function seedDailyCost(lcrCents: number, hoursPerDay: number): number {
    return Math.round(lcrCents * hoursPerDay);
  }

  // Demand requirements (open demand / placeholder roles)
  interface DemandSeed {
    projectCode: string;
    roleName: string;
    start: string;
    end: string;
    hoursPerDay: number;
    percentage: number;
    headcount: number;
    status: AllocationStatus;
  }

  const DEMAND_SEEDS: DemandSeed[] = [
    // PAG25G: Porsche Taycan Sport Film — needs 2 more 3D artists
    { projectCode: "PAG25G", roleName: "3D Artist",      start: "2026-03-16", end: "2026-03-31", hoursPerDay: 8, percentage: 100, headcount: 2, status: AllocationStatus.PROPOSED },
    // JLR26A: Jaguar EV Launch Film — open Art Director + PDM slot
    { projectCode: "JLR26A", roleName: "Art Director",   start: "2026-02-02", end: "2026-05-29", hoursPerDay: 8, percentage: 100, headcount: 1, status: AllocationStatus.CONFIRMED },
    { projectCode: "JLR26A", roleName: "PDM Specialist", start: "2026-03-02", end: "2026-06-30", hoursPerDay: 4, percentage: 50,  headcount: 1, status: AllocationStatus.PROPOSED },
    // DAI26B: AMG EV Reveal — needs Unreal Dev
    { projectCode: "DAI26B", roleName: "Unreal Dev",     start: "2026-02-16", end: "2026-04-17", hoursPerDay: 8, percentage: 100, headcount: 1, status: AllocationStatus.PROPOSED },
    // BMW26B: Draft — early demand planning
    { projectCode: "BMW26B", roleName: "3D Lead",        start: "2026-05-04", end: "2026-06-26", hoursPerDay: 8, percentage: 100, headcount: 1, status: AllocationStatus.PROPOSED },
    { projectCode: "BMW26B", roleName: "3D Artist",      start: "2026-05-04", end: "2026-06-26", hoursPerDay: 8, percentage: 100, headcount: 3, status: AllocationStatus.PROPOSED },
    { projectCode: "BMW26B", roleName: "Art Director",   start: "2026-05-04", end: "2026-06-26", hoursPerDay: 4, percentage: 50,  headcount: 1, status: AllocationStatus.PROPOSED },
    // JLR26B: Draft film — early demand
    { projectCode: "JLR26B", roleName: "Project Manager",start: "2026-06-01", end: "2026-11-30", hoursPerDay: 8, percentage: 100, headcount: 1, status: AllocationStatus.PROPOSED },
    { projectCode: "JLR26B", roleName: "3D Artist",      start: "2026-06-01", end: "2026-11-30", hoursPerDay: 8, percentage: 100, headcount: 4, status: AllocationStatus.PROPOSED },
    // DEV25B: Pipeline rebuild — open frontend dev slot
    { projectCode: "DEV25B", roleName: "Frontend Dev",   start: "2026-01-05", end: "2026-04-30", hoursPerDay: 8, percentage: 100, headcount: 1, status: AllocationStatus.PROPOSED },
  ];

  let demandCount = 0;
  for (const d of DEMAND_SEEDS) {
    const project = projectMap.get(d.projectCode);
    const roleId = roleMap.get(d.roleName);
    if (!project) { console.warn(`WARN: demand skip — project ${d.projectCode} not found`); continue; }

    await prisma.demandRequirement.create({
      data: {
        projectId: project.id,
        startDate: new Date(d.start),
        endDate: new Date(d.end),
        hoursPerDay: d.hoursPerDay,
        percentage: d.percentage,
        role: d.roleName,
        ...(roleId ? { roleId } : {}),
        headcount: d.headcount,
        status: d.status,
        metadata: {},
      },
    });
    demandCount++;
  }
  console.warn(`Demand requirements: ${demandCount} created`);

  // Assignments (resource-backed allocations)
  interface AssignmentSeed {
    eid: string;
    projectCode: string;
    roleName: string;
    start: string;
    end: string;
    hoursPerDay: number;
    percentage: number;
    status: AllocationStatus;
  }

  const ASSIGNMENT_SEEDS: AssignmentSeed[] = [
    // PAG25G: Porsche Taycan Sport Film
    { eid: "steve.rogers",    projectCode: "PAG25G", roleName: "Project Manager", start: "2025-10-01", end: "2026-03-31", hoursPerDay: 8, percentage: 100, status: AllocationStatus.ACTIVE },
    { eid: "tony.stark",      projectCode: "PAG25G", roleName: "3D Artist",       start: "2025-10-13", end: "2026-03-31", hoursPerDay: 8, percentage: 100, status: AllocationStatus.ACTIVE },
    { eid: "sam.wilson",      projectCode: "PAG25G", roleName: "3D Artist",       start: "2025-11-03", end: "2026-03-31", hoursPerDay: 8, percentage: 100, status: AllocationStatus.ACTIVE },
    { eid: "vision.vision",   projectCode: "PAG25G", roleName: "Art Director",    start: "2025-10-01", end: "2026-03-31", hoursPerDay: 4, percentage: 50,  status: AllocationStatus.ACTIVE },
    { eid: "hank.mccoy",      projectCode: "PAG25G", roleName: "PDM Specialist",  start: "2026-01-05", end: "2026-03-31", hoursPerDay: 8, percentage: 100, status: AllocationStatus.CONFIRMED },

    // JLR26A: Jaguar EV Launch Film
    { eid: "natasha.romanoff",projectCode: "JLR26A", roleName: "Project Manager", start: "2026-01-05", end: "2026-07-31", hoursPerDay: 8, percentage: 100, status: AllocationStatus.ACTIVE },
    { eid: "james.barnes",    projectCode: "JLR26A", roleName: "3D Artist",       start: "2026-01-05", end: "2026-07-31", hoursPerDay: 8, percentage: 100, status: AllocationStatus.ACTIVE },
    { eid: "peter.parker",    projectCode: "JLR26A", roleName: "3D Artist",       start: "2026-01-19", end: "2026-07-31", hoursPerDay: 8, percentage: 100, status: AllocationStatus.ACTIVE },
    { eid: "miles.morales",   projectCode: "JLR26A", roleName: "3D Artist",       start: "2026-02-02", end: "2026-07-31", hoursPerDay: 8, percentage: 100, status: AllocationStatus.CONFIRMED },
    { eid: "groot.groot",     projectCode: "JLR26A", roleName: "Art Director",    start: "2026-01-05", end: "2026-07-31", hoursPerDay: 8, percentage: 100, status: AllocationStatus.ACTIVE },
    { eid: "clint.barton",    projectCode: "JLR26A", roleName: "PDM Specialist",  start: "2026-02-16", end: "2026-06-30", hoursPerDay: 8, percentage: 100, status: AllocationStatus.CONFIRMED },

    // DEV25B: Asset Library & Pipeline Rebuild
    { eid: "matt.murdock",    projectCode: "DEV25B", roleName: "Unreal Dev",      start: "2025-11-03", end: "2026-04-30", hoursPerDay: 8, percentage: 100, status: AllocationStatus.ACTIVE },
    { eid: "jessica.jones",   projectCode: "DEV25B", roleName: "Unreal Dev",      start: "2026-01-05", end: "2026-04-30", hoursPerDay: 8, percentage: 100, status: AllocationStatus.CONFIRMED },
    { eid: "frank.castle",    projectCode: "DEV25B", roleName: "Frontend Dev",    start: "2025-11-03", end: "2026-04-30", hoursPerDay: 4, percentage: 50,  status: AllocationStatus.ACTIVE },

    // DAI26B: AMG EV Reveal Campaign Stills
    { eid: "bruce.banner",    projectCode: "DAI26B", roleName: "Project Manager", start: "2026-02-02", end: "2026-04-17", hoursPerDay: 4, percentage: 50,  status: AllocationStatus.ACTIVE },
    { eid: "thor.odinson",    projectCode: "DAI26B", roleName: "3D Artist",       start: "2026-02-02", end: "2026-04-17", hoursPerDay: 8, percentage: 100, status: AllocationStatus.ACTIVE },
    { eid: "erik.lehnsherr",  projectCode: "DAI26B", roleName: "3D Artist",       start: "2026-02-16", end: "2026-04-17", hoursPerDay: 8, percentage: 100, status: AllocationStatus.CONFIRMED },
    { eid: "drax.drax",       projectCode: "DAI26B", roleName: "Art Director",    start: "2026-02-02", end: "2026-04-17", hoursPerDay: 4, percentage: 50,  status: AllocationStatus.ACTIVE },
    { eid: "anna.marie",      projectCode: "DAI26B", roleName: "PDM Specialist",  start: "2026-03-02", end: "2026-04-17", hoursPerDay: 8, percentage: 100, status: AllocationStatus.CONFIRMED },

    // PAG26C: Porsche Carrera Grand Viz
    { eid: "charles.xavier",  projectCode: "PAG26C", roleName: "Project Manager", start: "2026-02-16", end: "2026-04-24", hoursPerDay: 8, percentage: 100, status: AllocationStatus.ACTIVE },
    { eid: "jean.grey",       projectCode: "PAG26C", roleName: "3D Artist",       start: "2026-02-16", end: "2026-04-24", hoursPerDay: 8, percentage: 100, status: AllocationStatus.ACTIVE },
    { eid: "stephen.strange", projectCode: "PAG26C", roleName: "3D Artist",       start: "2026-02-16", end: "2026-04-24", hoursPerDay: 8, percentage: 100, status: AllocationStatus.CONFIRMED },
    { eid: "jessica.drew",    projectCode: "PAG26C", roleName: "3D Artist",       start: "2026-03-02", end: "2026-04-24", hoursPerDay: 8, percentage: 100, status: AllocationStatus.CONFIRMED },
    { eid: "tchalla.tchalla", projectCode: "PAG26C", roleName: "Art Director",    start: "2026-02-16", end: "2026-04-24", hoursPerDay: 8, percentage: 100, status: AllocationStatus.ACTIVE },
    { eid: "peter.quill",     projectCode: "PAG26C", roleName: "PDM Specialist",  start: "2026-03-02", end: "2026-04-24", hoursPerDay: 4, percentage: 50,  status: AllocationStatus.PROPOSED },

    // Cross-project partial allocations
    { eid: "wanda.maximoff",  projectCode: "DAI26B", roleName: "3D Artist",       start: "2026-03-03", end: "2026-04-17", hoursPerDay: 6, percentage: 75,  status: AllocationStatus.PROPOSED },
    { eid: "logan.howlett",   projectCode: "PAG26C", roleName: "3D Artist",       start: "2026-03-16", end: "2026-04-24", hoursPerDay: 8, percentage: 100, status: AllocationStatus.PROPOSED },
    { eid: "wong.wong",       projectCode: "PAG25G", roleName: "3D Artist",       start: "2026-01-05", end: "2026-03-31", hoursPerDay: 4, percentage: 50,  status: AllocationStatus.CONFIRMED },
    { eid: "danny.rand",      projectCode: "JLR26A", roleName: "Unreal Dev",      start: "2026-03-02", end: "2026-07-31", hoursPerDay: 8, percentage: 100, status: AllocationStatus.PROPOSED },
    { eid: "scott.lang",      projectCode: "PAG25G", roleName: "3D Generalist",   start: "2026-01-19", end: "2026-03-31", hoursPerDay: 4, percentage: 50,  status: AllocationStatus.CONFIRMED },

    // Draft project pre-allocations
    { eid: "carol.danvers",   projectCode: "DEV26A", roleName: "Frontend Dev",    start: "2026-05-04", end: "2026-08-28", hoursPerDay: 8, percentage: 100, status: AllocationStatus.PROPOSED },
    { eid: "kamala.khan",     projectCode: "DEV26A", roleName: "Frontend Dev",    start: "2026-05-04", end: "2026-08-28", hoursPerDay: 8, percentage: 100, status: AllocationStatus.PROPOSED },
  ];

  let assignmentCount = 0;
  for (const a of ASSIGNMENT_SEEDS) {
    const resource = resourceMap.get(a.eid);
    const project = projectMap.get(a.projectCode);
    const roleId = roleMap.get(a.roleName);
    if (!resource || !project) {
      console.warn(`WARN: assignment skip — ${a.eid}/${a.projectCode} not found`);
      continue;
    }

    const dailyCost = seedDailyCost(resource.lcrCents, a.hoursPerDay);

    await prisma.assignment.create({
      data: {
        resourceId: resource.id,
        projectId: project.id,
        startDate: new Date(a.start),
        endDate: new Date(a.end),
        hoursPerDay: a.hoursPerDay,
        percentage: a.percentage,
        role: a.roleName,
        ...(roleId ? { roleId } : {}),
        dailyCostCents: dailyCost,
        status: a.status,
        metadata: {},
      },
    });
    assignmentCount++;
  }
  console.warn(`Assignments: ${assignmentCount} created`);

  // ── Vacations ──────────────────────────────────────────────────────────────
  const vacationEntries: Array<{
    eid: string;
    type: VacationType;
    status: VacationStatus;
    start: string;
    end: string;
    note?: string;
  }> = [
    { eid: "steve.rogers",     type: VacationType.ANNUAL,         status: VacationStatus.APPROVED, start: "2026-04-07", end: "2026-04-11", note: "Easter break" },
    { eid: "tony.stark",       type: VacationType.ANNUAL,         status: VacationStatus.APPROVED, start: "2026-05-25", end: "2026-06-06", note: "Summer vacation" },
    { eid: "natasha.romanoff", type: VacationType.SICK,           status: VacationStatus.APPROVED, start: "2026-03-10", end: "2026-03-12" },
    { eid: "bruce.banner",     type: VacationType.ANNUAL,         status: VacationStatus.PENDING,  start: "2026-06-15", end: "2026-06-26", note: "Conference + holiday" },
    { eid: "thor.odinson",     type: VacationType.PUBLIC_HOLIDAY, status: VacationStatus.APPROVED, start: "2026-05-01", end: "2026-05-01", note: "Labour Day" },
    { eid: "sam.wilson",       type: VacationType.ANNUAL,         status: VacationStatus.APPROVED, start: "2026-07-20", end: "2026-08-07", note: "Summer vacation" },
    { eid: "peter.parker",     type: VacationType.SICK,           status: VacationStatus.APPROVED, start: "2026-03-18", end: "2026-03-19" },
    { eid: "wanda.maximoff",   type: VacationType.ANNUAL,         status: VacationStatus.APPROVED, start: "2026-04-14", end: "2026-04-17", note: "Long weekend" },
    { eid: "scott.lang",       type: VacationType.ANNUAL,         status: VacationStatus.PENDING,  start: "2026-08-17", end: "2026-08-28", note: "Family trip" },
    { eid: "james.barnes",     type: VacationType.OTHER,          status: VacationStatus.APPROVED, start: "2026-03-26", end: "2026-03-27", note: "Personal day" },
  ];

  let vacationCount = 0;
  for (const v of vacationEntries) {
    const res = resourceMap.get(v.eid);
    if (!res) continue;
    const isApproved = v.status === VacationStatus.APPROVED;
    await prisma.vacation.create({
      data: {
        resourceId:  res.id,
        type:        v.type,
        status:      v.status,
        startDate:   new Date(v.start),
        endDate:     new Date(v.end),
        ...(v.note ? { note: v.note } : {}),
        requestedById: manager.id,
        ...(isApproved ? { approvedById: manager.id, approvedAt: new Date() } : {}),
      },
    });
    vacationCount++;
  }
  console.warn(`Vacations: ${vacationCount} created`);

  // ── Calculation Rules (default set) ──────────────────────────────────────────
  await prisma.calculationRule.createMany({
    data: [
      {
        name: "Urlaub — Person chargeable, Projekt nicht belastet",
        description: "Vacation days count toward chargeability but are not charged to the project.",
        triggerType: "VACATION",
        costEffect: "ZERO",
        chargeabilityEffect: "COUNT",
        priority: 0,
        isActive: true,
      },
      {
        name: "Krankheit — Person chargeable, Projekt nicht belastet",
        description: "Sick days count toward chargeability but are not charged to the project.",
        triggerType: "SICK",
        costEffect: "ZERO",
        chargeabilityEffect: "COUNT",
        priority: 0,
        isActive: true,
      },
      {
        name: "Feiertag — kein Effekt",
        description: "Public holidays are neither chargeable nor charged to projects.",
        triggerType: "PUBLIC_HOLIDAY",
        costEffect: "ZERO",
        chargeabilityEffect: "SKIP",
        priority: 0,
        isActive: true,
      },
    ],
  });
  console.warn("Calculation rules: 3 default rules created");

  console.warn("Seed complete!");
}

main()
  .catch((e) => {
    console.error(e);
    process.exit(1);
  })
  .finally(() => {
    void prisma.$disconnect();
  });
