const { PrismaClient } = require('../prisma-generated/client');

const prisma = new PrismaClient();
const MODEL_NAMES = ["account_user", "delivery_order", "delivery_order_status_history"];
const modelIdMap = {
  "account_user": new Map(),
  "delivery_order": new Map(),
  "delivery_order_status_history": new Map()
};

// === Seed Functions Start ===
async function seedaccount_user(prisma: any, modelIdMap: any): Promise<void> {
  const now = new Date();
  const addDays = (d: Date, n: number) => new Date(d.getTime() + n * 86400000);

  const account_userData = [
    {
      account: "ali_ahmed",
      password: "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
      email: "ali.ahmed@meshwar.iq",
      role: "ADMIN",
      timeAnchor: -45,
      updateAnchor: -15
    },
    {
      account: "fatima.hassan",
      password: "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
      email: "fatima.hassan@meshwar.iq",
      role: "ADMIN",
      timeAnchor: -60,
      updateAnchor: -2
    },
    {
      account: "omar_farooq",
      password: "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
      email: "omar.farooq@meshwar.iq",
      role: "ADMIN",
      timeAnchor: -10,
      updateAnchor: -5
    },
    {
      account: "zainab_kareem",
      password: "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
      email: "zainab.kareem@meshwar.iq",
      role: "ADMIN",
      timeAnchor: -5,
      updateAnchor: -1
    }
  ];

  modelIdMap["account_user"] = new Map<number, string>();

  for (let i = 0; i < account_userData.length; i++) {
    const data = account_userData[i];
    const createdAt = addDays(now, data.timeAnchor);
    const updatedAt = addDays(now, data.updateAnchor);

    const record = await prisma.account_user.create({
      data: {
        account: data.account,
        password: data.password,
        email: data.email,
        role: data.role as any,
        createdAt: createdAt,
        updatedAt: updatedAt
      }
    });

    modelIdMap["account_user"].set(i, record.id);
  }
}
async function seeddelivery_order(prisma: any, modelIdMap: any): Promise<void> {
  const now = new Date();
  const addDays = (d: Date, n: number) => new Date(d.getTime() + n * 86400000);

  const deliveryOrderData = [
    {
      orderNo: "ORD-2023-1001",
      governorateName: "بغداد",
      areaName: "المنصور",
      nearestLandmark: "مول المنصور",
      customerName: "علي محمد",
      customerPhone: "07901234567",
      driverName: "أحمد حسن",
      orderType: "توصيل سريع",
      status: "PENDING",
      timeAnchor: -2,
      updatedAnchor: -1
    },
    {
      orderNo: "ORD-2023-1002",
      governorateName: "البصرة",
      areaName: "العشار",
      nearestLandmark: "شارع الوطن",
      customerName: "سارة جاسم",
      customerPhone: "07801234567",
      driverName: "حسين علي",
      orderType: "توصيل عادي",
      status: "IN_PROGRESS",
      timeAnchor: -15,
      updatedAnchor: -5
    },
    {
      orderNo: "ORD-2023-1003",
      governorateName: "أربيل",
      areaName: "عينكاوة",
      nearestLandmark: "كنيسة مار يوسف",
      customerName: "نور ستار",
      customerPhone: "07701234567",
      driverName: "عمر خالد",
      orderType: "توصيل طعام",
      status: "DELIVERED",
      timeAnchor: -40,
      updatedAnchor: -35
    },
    {
      orderNo: "ORD-2023-1004",
      governorateName: "النجف",
      areaName: "الكوفة",
      nearestLandmark: "مسجد الكوفة",
      customerName: "محمد مهدي",
      customerPhone: "07501234567",
      driverName: "مصطفى كامل",
      orderType: "توصيل طرود",
      status: "CANCELLED",
      timeAnchor: -6,
      updatedAnchor: -4
    },
    {
      orderNo: "ORD-2023-1005",
      governorateName: "كربلاء",
      areaName: "حي الحسين",
      nearestLandmark: "مستشفى الحسين",
      customerName: "زينب علي",
      customerPhone: "07907654321",
      driverName: "رائد سامي",
      orderType: "توصيل وثائق",
      status: "PENDING",
      timeAnchor: -20,
      updatedAnchor: -10
    },
    {
      orderNo: "ORD-2023-1006",
      governorateName: "الموصل",
      areaName: "الزهور",
      nearestLandmark: "جامعة الموصل",
      customerName: "فهد عبدالله",
      customerPhone: "07807654321",
      driverName: "سالم محمود",
      orderType: "توصيل سريع",
      status: "IN_PROGRESS",
      timeAnchor: -1,
      updatedAnchor: 0
    },
    {
      orderNo: "ORD-2023-1007",
      governorateName: "بغداد",
      areaName: "الكرادة",
      nearestLandmark: "المسرح الوطني",
      customerName: "فاطمة زهراء",
      customerPhone: "07707654321",
      driverName: "أحمد حسن",
      orderType: "توصيل هدايا",
      status: "DELIVERED",
      timeAnchor: -45,
      updatedAnchor: -42
    },
    {
      orderNo: "ORD-2023-1008",
      governorateName: "البصرة",
      areaName: "الجزائر",
      nearestLandmark: "شارع الاستقلال",
      customerName: "يوسف ناصر",
      customerPhone: "07507654321",
      driverName: "حسين علي",
      orderType: "توصيل عادي",
      status: "PENDING",
      timeAnchor: -25,
      updatedAnchor: -18
    },
    {
      orderNo: "ORD-2023-1009",
      governorateName: "الأنبار",
      areaName: "الرمادي",
      nearestLandmark: "جامعة الأنبار",
      customerName: "عمر فاروق",
      customerPhone: "07901112233",
      driverName: "ياسر قاسم",
      orderType: "توصيل طعام",
      status: "IN_PROGRESS",
      timeAnchor: -12,
      updatedAnchor: -8
    },
    {
      orderNo: "ORD-2023-1010",
      governorateName: "بابل",
      areaName: "الحلة",
      nearestLandmark: "منتجع بابل",
      customerName: "هدى جبار",
      customerPhone: "07801112233",
      driverName: "عمار سعد",
      orderType: "توصيل طرود",
      status: "DELIVERED",
      timeAnchor: -3,
      updatedAnchor: -2
    },
    {
      orderNo: "ORD-2023-1011",
      governorateName: "ذي قار",
      areaName: "الناصرية",
      nearestLandmark: "زقورة أور",
      customerName: "حيدر سالم",
      customerPhone: "07701112233",
      driverName: "ماجد نعيم",
      orderType: "توصيل سريع",
      status: "PENDING",
      timeAnchor: -35,
      updatedAnchor: -20
    },
    {
      orderNo: "ORD-2023-1012",
      governorateName: "السليمانية",
      areaName: "بختياري",
      nearestLandmark: "حديقة آزادي",
      customerName: "شيرين كمال",
      customerPhone: "07501112233",
      driverName: "عمر خالد",
      orderType: "توصيل وثائق",
      status: "PENDING",
      timeAnchor: -5,
      updatedAnchor: -1
    }
  ];

  modelIdMap["delivery_order"] = new Map<number, string>();

  for (let i = 0; i < deliveryOrderData.length; i++) {
    const data = deliveryOrderData[i];
    const createdAt = addDays(now, data.timeAnchor);
    const updatedAt = addDays(now, data.updatedAnchor);

    const record = await prisma.delivery_order.create({
      data: {
        orderNo: data.orderNo,
        governorateName: data.governorateName,
        areaName: data.areaName,
        nearestLandmark: data.nearestLandmark,
        customerName: data.customerName,
        customerPhone: data.customerPhone,
        driverName: data.driverName,
        orderType: data.orderType,
        status: data.status as any,
        createdAt: createdAt,
        updatedAt: updatedAt
      }
    });
    
    modelIdMap["delivery_order"].set(i, record.id);
  }
}
async function seeddelivery_order_status_history(prisma: any, modelIdMap: any): Promise<void> {
  const now = new Date();
  const addDays = (d: Date, n: number) => new Date(d.getTime() + n * 86400000);

  const historyData = [
    { deliveryOrderIndex: 0, fromStatus: null, toStatus: "PENDING", changedByIndex: 0, timeAnchor: -2 },
    { deliveryOrderIndex: 1, fromStatus: null, toStatus: "PENDING", changedByIndex: 1, timeAnchor: -15 },
    { deliveryOrderIndex: 1, fromStatus: "PENDING", toStatus: "IN_PROGRESS", changedByIndex: 0, timeAnchor: -14 },
    { deliveryOrderIndex: 2, fromStatus: null, toStatus: "PENDING", changedByIndex: 2, timeAnchor: -40 },
    { deliveryOrderIndex: 2, fromStatus: "PENDING", toStatus: "IN_PROGRESS", changedByIndex: 0, timeAnchor: -39 },
    { deliveryOrderIndex: 2, fromStatus: "IN_PROGRESS", toStatus: "DELIVERED", changedByIndex: 3, timeAnchor: -38 },
    { deliveryOrderIndex: 3, fromStatus: null, toStatus: "PENDING", changedByIndex: 1, timeAnchor: -6 },
    { deliveryOrderIndex: 3, fromStatus: "PENDING", toStatus: "CANCELLED", changedByIndex: 0, timeAnchor: -5 },
    { deliveryOrderIndex: 4, fromStatus: null, toStatus: "PENDING", changedByIndex: 2, timeAnchor: -20 },
    { deliveryOrderIndex: 5, fromStatus: null, toStatus: "PENDING", changedByIndex: 3, timeAnchor: -1 },
    { deliveryOrderIndex: 5, fromStatus: "PENDING", toStatus: "IN_PROGRESS", changedByIndex: 0, timeAnchor: 0 },
    { deliveryOrderIndex: 6, fromStatus: null, toStatus: "PENDING", changedByIndex: 1, timeAnchor: -45 },
    { deliveryOrderIndex: 6, fromStatus: "PENDING", toStatus: "IN_PROGRESS", changedByIndex: 2, timeAnchor: -44 },
    { deliveryOrderIndex: 6, fromStatus: "IN_PROGRESS", toStatus: "DELIVERED", changedByIndex: 0, timeAnchor: -43 },
    { deliveryOrderIndex: 7, fromStatus: null, toStatus: "PENDING", changedByIndex: 3, timeAnchor: -25 },
    { deliveryOrderIndex: 8, fromStatus: null, toStatus: "PENDING", changedByIndex: 0, timeAnchor: -12 },
    { deliveryOrderIndex: 8, fromStatus: "PENDING", toStatus: "IN_PROGRESS", changedByIndex: 1, timeAnchor: -11 },
    { deliveryOrderIndex: 9, fromStatus: null, toStatus: "PENDING", changedByIndex: 2, timeAnchor: -3 },
    { deliveryOrderIndex: 9, fromStatus: "PENDING", toStatus: "IN_PROGRESS", changedByIndex: 0, timeAnchor: -2 },
    { deliveryOrderIndex: 9, fromStatus: "IN_PROGRESS", toStatus: "DELIVERED", changedByIndex: 3, timeAnchor: -1 },
    { deliveryOrderIndex: 10, fromStatus: null, toStatus: "PENDING", changedByIndex: 1, timeAnchor: -35 },
    { deliveryOrderIndex: 11, fromStatus: null, toStatus: "PENDING", changedByIndex: 0, timeAnchor: -5 }
  ];

  modelIdMap["delivery_order_status_history"] = new Map<number, string>();

  for (let i = 0; i < historyData.length; i++) {
    const data = historyData[i];
    const deliveryOrderId = modelIdMap["delivery_order"].get(data.deliveryOrderIndex);
    const changedById = modelIdMap["account_user"].get(data.changedByIndex);
    const createdAt = addDays(now, data.timeAnchor);

    if (!deliveryOrderId) continue;

    const record = await prisma.delivery_order_status_history.create({
      data: {
        deliveryOrderId: deliveryOrderId,
        fromStatus: data.fromStatus as any,
        toStatus: data.toStatus as any,
        changedById: changedById,
        createdAt: createdAt
      }
    });

    modelIdMap["delivery_order_status_history"].set(i, record.id);
  }
}
// === Seed Functions End ===

async function runSeedStep(stepName, fn) {
  try {
    await fn();
  } catch (error) {
    const err = error instanceof Error ? error : new Error(String(error));
    console.error(`[SEED_STEP_FAILED] ${stepName}`);
    throw err;
  }
}

async function main() {
  // Delete all data once in reverse topology order before inserts.
  await prisma.$executeRawUnsafe('SET FOREIGN_KEY_CHECKS = 0');
  try {
    await prisma.delivery_order_status_history.deleteMany();
    await prisma.account_user.deleteMany();
    await prisma.delivery_order.deleteMany();
  } finally {
    await prisma.$executeRawUnsafe('SET FOREIGN_KEY_CHECKS = 1');
  }

  await runSeedStep('seedaccount_user', () => seedaccount_user(prisma, modelIdMap));
  await runSeedStep('seeddelivery_order', () => seeddelivery_order(prisma, modelIdMap));
  await runSeedStep('seeddelivery_order_status_history', () => seeddelivery_order_status_history(prisma, modelIdMap));
}

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