import mongoConnection from "$connections/mongo/mongo.connection.js";
import models from "$models/index.js";

/**
 * Complete Database Initialization Script
 * Auto-generates permissions from resources and creates roles
 */

// Define resources - permissions will be auto-generated
const RESOURCES = [
  {
    resource: "home",
    label: "داشبورد",
    description: "دسترسی به صفحه اصلی داشبورد",
  },
  {
    resource: "createOrder",
    label: "ثبت سفارش",
    description: "دسترسی به صفحه ثبت سفارش",
    actions: ["view"],
  },
  {
    resource: "users",
    label: "کاربران",
    description: "مدیریت کاربران سیستم و اطلاعات آنها",
  },
  {
    resource: "roles",
    label: "نقش‌ها",
    description: "مدیریت نقش‌ها و مجوزهای دسترسی",
  },
  {
    resource: "permissions",
    label: "مجوزها",
    description: "مدیریت مجوزهای سیستم",
  },
  {
    resource: "profile",
    label: "پروفایل کاربری",
    description: "مدیریت اطلاعات پروفایل کاربری",
  },
  {
    resource: "transactions",
    label: "تراکنش‌های امید",
    description: "مشاهده و مدیریت تراکنش‌های مالی",
  },
  {
    resource: "requests",
    label: "درخواست‌های امید",
    description: "مدیریت درخواست های امید",
  },
  {
    resource: "requestHistories",
    label: "تاریخچه درخواست‌ها",
    description: "مشاهده و مدیریت تاریخچه تغییرات درخواست‌ها",
  },
  {
    resource: "investHistories",
    label: "تاریخچه سرمایه‌گذاری مجدد",
    description: "مشاهده تاریخچه تغییرات سرمایه‌گذاری مجدد صندوق‌ها",
  },
  {
    resource: "paymentBatchCards",
    label: "بسته‌های کارت هدیه",
    description: "مدیریت بسته‌ها، ساخت کارت و دریافت خروجی اکسل کارت‌های هدیه",
  },
  {
    resource: "paymentCards",
    label: "کارت‌های هدیه",
    description: "مشاهده و لغو کارت‌های هدیه",
  },
  {
    resource: "paymentSlips",
    label: "فیش‌های پرداخت",
    description: "مشاهده و مدیریت فیش‌های پرداخت ثبت‌شده برای صدور",
  },
  {
    resource: "banks",
    label: "بانک‌ها",
    description: "مدیریت بانک‌ها و شناسه‌های بانک در سجام",
  },
  {
    resource: "balance",
    label: "موجودی",
    description: "مشاهده و مدیریت موجودی حساب",
  },
  {
    resource: "club",
    label: "باشگاه مشتریان",
    description: "دسترسی کاربر به داشبورد باشگاه مشتریان",
    actions: ["view"],
  },
  {
    resource: "clubRewards",
    label: "جوایز باشگاه",
    description: "مدیریت جوایز باشگاه مشتریان",
  },
  {
    resource: "clubLedger",
    label: "دفتر امتیاز باشگاه",
    description: "مشاهده تراکنش‌های امتیاز باشگاه",
    actions: ["view"],
  },
  {
    resource: "clubReferrals",
    label: "معرفی‌های باشگاه",
    description: "مشاهده معرفی‌ها و وضعیت آن‌ها",
    actions: ["view"],
  },
  {
    resource: "clubRedemptions",
    label: "بازخریدهای باشگاه",
    description: "مشاهده درخواست‌های دریافت جایزه باشگاه",
    actions: ["view"],
  },
  {
    resource: "clubAdjustments",
    label: "اصلاحات باشگاه",
    description: "ثبت اصلاحات دستی امتیاز باشگاه",
    actions: ["create"],
  },
  {
    resource: "news",
    label: "اخبار",
    description: "مدیریت اخبار، اطلاعیه‌ها و محتوای اطلاع‌رسانی",
  },
  {
    resource: "messages",
    label: "پیام‌ها",
    description: "مدیریت پیام‌های داخلی و اطلاع‌رسانی در داشبورد",
  },
  {
    resource: "externalRequests",
    label: "کلیه درخواست ها",
    description: "مشاهده کلیه درخواست ها دریافتی از سرویس تدبیر",
    actions: ["view"],
  },
  {
    resource: "certificates",
    label: "گواهی‌های سرمایه‌گذاری",
    description: "مشاهده و ایجاد گواهی‌های سرمایه‌گذاری",
    actions: ["view", "create"],
  },
  {
    resource: "investCardex",
    label: "کاردکس سرمایه‌گذار",
    description: "مشاهده کاردکس سرمایه‌گذار از سرویس تدبیر",
    actions: ["view"],
  },
  {
    resource: "turnoverAccount",
    label: "گردش حساب",
    description: "مشاهده گردش حساب سرمایه‌گذار",
    actions: ["view"],
  },
];

// Action labels in Persian
const ACTION_LABELS = {
  view: "مشاهده",
  create: "ایجاد",
  update: "ویرایش",
  delete: "حذف",
};

const BANKS = [
  { name: "بانک اقتصاد نوین", bankCode: "10102194601", sejamBankId: "123101" },
  { name: "بانک ایران زمین", bankCode: "10320503079", sejamBankId: "123103" },
  { name: "بانک آینده", bankCode: "10320894878", sejamBankId: "129" },
  { name: "بانک پارسیان", bankCode: "10102203401", sejamBankId: "122795" },
  { name: "بانک پاسارگاد", bankCode: "10102946956", sejamBankId: "123104" },
  { name: "بانک تجارت", bankCode: "10100834460", sejamBankId: "123105" },
  { name: "بانک توسعه تعاون", bankCode: "10104021538", sejamBankId: "123123" },
  { name: "بانک رفاه", bankCode: "10100334245", sejamBankId: "122718" },
  { name: "بانک سپه", bankCode: "10862064732", sejamBankId: "123110" },
  { name: "بانک سامان", bankCode: "10101972093", sejamBankId: "123109" },
  { name: "بانک سرمایه", bankCode: "10103798457", sejamBankId: "123116" },
  { name: "بانک سینا", bankCode: "10860246171", sejamBankId: "123118" },
  { name: "بانک شهر", bankCode: "10103886081", sejamBankId: "123111" },
  { name: "بانک صادرات", bankCode: "10861736062", sejamBankId: "128" },
  { name: "بانک صنعت و معدن", bankCode: "10100841160", sejamBankId: "123112" },
  {
    name: "بانک قرض الحسنه رسالت",
    bankCode: "10320730277",
    sejamBankId: "123122",
  },
  {
    name: "بانک قرض الحسنه مهر ايران",
    bankCode: "10103509868",
    sejamBankId: "123158",
  },
  { name: "بانک کارآفرین", bankCode: "10102006226", sejamBankId: "123114" },
  { name: "بانک کشاورزی", bankCode: "10100830184", sejamBankId: "123115" },
  { name: "بانک گردشگری", bankCode: "10320435268", sejamBankId: "123119" },
  { name: "بانک مرکزی", bankCode: "14002207985", sejamBankId: "123161" },
  { name: "بانک مسکن", bankCode: "10100687843", sejamBankId: "123113" },
  {
    name: "بانک مشترک ایران و ونزوئلا",
    bankCode: "10320162713",
    sejamBankId: "123162",
  },
  { name: "بانک ملت", bankCode: "10100834967", sejamBankId: "130" },
  { name: "بانک ملی", bankCode: "10861677542", sejamBankId: "127" },
  { name: "پست بانک", bankCode: "10101702747", sejamBankId: "123133" },
  {
    name: "توسعه صادرات ایران",
    bankCode: "10101313616",
    sejamBankId: "123106",
  },
  { name: "موسسه اعتباری ملل", bankCode: "10380252343", sejamBankId: "123160" },
  {
    name: "مؤسسه مالی و اعتباری توسعه",
    bankCode: "10101767219",
    sejamBankId: "123164",
  },
  {
    name: "موسسه مالی و اعتباری نور",
    bankCode: "14004932504",
    sejamBankId: "123163",
  },
];

async function clearAllCollections() {
  console.log("🧹 STEP 0: Clearing Existing Collection Data...");

  const collections = await mongoConnection.db.listCollections().toArray();
  let clearedCollections = 0;
  let clearedDocuments = 0;

  for (const collection of collections) {
    const collectionName = String(collection?.name || "").trim();
    if (!collectionName || collectionName.startsWith("system.")) {
      continue;
    }

    const dbCollection = mongoConnection.db.collection(collectionName);
    const existingCount = await dbCollection.countDocuments();

    if (existingCount > 0) {
      await dbCollection.deleteMany({});
      console.log(
        `🧹 Cleared ${existingCount} documents from ${collectionName}`,
      );
      clearedDocuments += existingCount;
    } else {
      console.log(`🧼 ${collectionName} was already empty`);
    }

    clearedCollections += 1;
  }

  console.log(
    `✅ Cleared data from ${clearedCollections} collections (${clearedDocuments} documents removed)\n`,
  );
}

const buildMockMessages = (createdBy) => [
  {
    title: "خوش‌آمدگویی به کاربران داشبورد",
    body: "به داشبورد تامین سرمایه امید خوش آمدید. در این بخش می‌توانید پیام‌های جدید، اطلاعیه‌های داخلی و موارد نیازمند پیگیری را مشاهده کنید.",
    audienceType: "all",
    targetRoles: [],
    status: "published",
    isActive: true,
    startsAt: new Date("2026-05-01T06:00:00.000Z"),
    expiresAt: null,
    priority: 10,
    createdBy,
  },
  {
    title: "راهنمای بررسی و انتشار اخبار",
    body: "کاربران دارای دسترسی محتوایی لطفا پیش از انتشار خبر، وضعیت محتوا، عنوان سئو، بازه نمایش و تصویر شاخص را بازبینی کنند تا خروجی نهایی در صفحات عمومی بدون خطا نمایش داده شود.",
    audienceType: "roles",
    targetRoles: ["superAdmin"],
    status: "published",
    isActive: true,
    startsAt: new Date("2026-05-02T07:30:00.000Z"),
    expiresAt: null,
    priority: 9,
    createdBy,
  },
  {
    title: "پیام پیش‌نویس برای برنامه‌ریزی کمپین",
    body: "این پیام به صورت پیش‌نویس ذخیره شده تا پس از نهایی شدن زمان‌بندی کمپین و تعیین مخاطبان هدف، منتشر شود.",
    audienceType: "roles",
    targetRoles: ["user"],
    status: "draft",
    isActive: true,
    startsAt: null,
    expiresAt: null,
    priority: 4,
    createdBy,
  },
  {
    title: "یادآوری بازبینی درخواست‌های در انتظار",
    body: "لطفا درخواست‌های دارای وضعیت در انتظار یا در حال بررسی را پیش از پایان روز کاری مرور کنید تا پاسخ‌گویی به کاربران با تاخیر انجام نشود.",
    audienceType: "all",
    targetRoles: [],
    status: "published",
    isActive: true,
    startsAt: new Date("2026-05-03T05:00:00.000Z"),
    expiresAt: new Date("2026-06-01T20:30:00.000Z"),
    priority: 8,
    createdBy,
  },
];

// Generate all permissions from resources
function generatePermissions() {
  const permissions = [];
  for (const resource of RESOURCES) {
    const actions = resource.actions || ["view", "create", "update", "delete"];
    for (const action of actions) {
      permissions.push({
        resource: resource.resource,
        resourceLabel: resource.label,
        action: action,
        key: `${resource.resource}:${action}`,
        label: `${ACTION_LABELS[action]} ${resource.label}`,
        description: `${ACTION_LABELS[action]} ${resource.description}`,
        isDangerous: action === "delete",
      });
    }
  }

  return permissions;
}

// Step 1: Seed Permissions
async function seedPermissions() {
  console.log("📋 STEP 1: Seeding Permissions...");

  // Generate and insert all permissions
  const PERMISSIONS = generatePermissions();
  const created = await models.permission.insertMany(PERMISSIONS);
  console.log(`✅ Created ${created.length} permissions`);

  // Group by resource for display
  const grouped = {};
  created.forEach((perm) => {
    if (!grouped[perm.resource]) grouped[perm.resource] = [];
    grouped[perm.resource].push(perm);
  });

  Object.entries(grouped).forEach(([resource, perms]) => {
    console.log(`   📁 ${resource}: ${perms.length} permissions`);
  });

  console.log(
    `   🔴 Dangerous operations: ${
      created.filter((p) => p.isDangerous).length
    }\n`,
  );

  return created;
}

// Step 2: Create Roles
async function createRoles(allPermissionKeys) {
  console.log("🔑 STEP 2: Creating Roles...");

  // 1. Admin Role (Super Admin with all permissions)
  const superAdmin = new models.role({
    label: "مدیر کل",
    value: "superAdmin",
    permissions: allPermissionKeys,
    isSuperAdmin: true,
  });
  await superAdmin.save();
  console.log(
    `✅ Created superAdmin role with all ${allPermissionKeys.length} permissions`,
  );

  // 2. User Role (Limited permissions - dashboard and payment card tools)
  const userResources = [
    "home",
    "profile",
    "transactions",
    "requests",
    "paymentSlips",
    "banks",
    "balance",
    "messages",
    "externalRequests",
    "certificates",
    "investCardex",
    "turnoverAccount",
    "createOrder",
    "permissions",
    "club",
  ];
  const userPermissionSet = new Set(
    allPermissionKeys.filter((key) =>
      userResources.some((resource) => key === `${resource}:view`),
    ),
  );
  const userPermissions = Array.from(userPermissionSet);
  const userRole = new models.role({
    label: "کاربر عادی",
    value: "user",
    permissions: userPermissions,
    isSuperAdmin: false,
  });
  await userRole.save();
  console.log(
    `✅ Created user role with ${userPermissions.length} permissions (only :view of ${userResources.join(", ")})\n`,
  );

  return {
    superAdmin: superAdmin,
    user: userRole,
  };
}

// Step 3: Create Seed Users
async function seedUsers(roles) {
  console.log("👤 STEP 3: Creating Seed Users...");

  const superAdminUser = await models.user.create({
    nationalId: "0019431171",
    role: roles.superAdmin._id,
    fullName: "احسان وزیری",
    mobile: "09124375365",
    isSejamVerified: false,
  });
  console.log(`✅ Created SuperAdmin user (National ID: 0019431171)`);

  const regularUser = await models.user.create({
    nationalId: "3240309653",
    role: roles.user._id,
    fullName: "کاربر عادی",
    mobile: "09124375365",
    isSejamVerified: false,
  });
  console.log(`✅ Created regular user (National ID: 3240309653)\n`);

  return {
    superAdminUser,
    regularUser,
  };
}

// Step 4: Seed Messages
async function seedMessages(createdBy) {
  console.log("💬 STEP 4: Seeding Messages...");

  const created = await models.message.insertMany(buildMockMessages(createdBy));
  console.log(`✅ Created ${created.length} messages\n`);

  return created;
}

// Step 5: Seed Banks
async function seedBanks() {
  console.log("🏦 STEP 5: Seeding Banks...");

  const created = await models.bank.insertMany(BANKS);
  console.log(`✅ Created ${created.length} banks\n`);

  return created;
}

// Main initialization function
async function initializeDatabase() {
  return new Promise((resolve, reject) => {
    mongoConnection.once("open", async () => {
      try {
        console.log("✅ Connected to database successfully\n");
        console.log("╔═══════════════════════════════════════════════════╗");
        console.log("║     DATABASE INITIALIZATION SCRIPT                ║");
        console.log("║     Auto-generates permissions from resources     ║");
        console.log("╚═══════════════════════════════════════════════════╝\n");

        const startTime = Date.now();

        // Step 0: Clear all collection data
        await clearAllCollections();

        // Step 1: Seed all permissions
        const permissions = await seedPermissions();
        const allPermissionKeys = permissions.map((p) => p.key);

        // Step 2: Create roles
        const roles = await createRoles(allPermissionKeys);

        // Step 3: Create seed users
        const { superAdminUser, regularUser } = await seedUsers(roles);

        // Step 4: Seed messages mock data
        const messages = await seedMessages(superAdminUser._id);

        // Step 5: Seed banks initial data
        const banks = await seedBanks();

        const duration = ((Date.now() - startTime) / 1000).toFixed(2);

        // Final Summary
        console.log("╔═══════════════════════════════════════════════════╗");
        console.log("║              INITIALIZATION COMPLETE              ║");
        console.log("╚═══════════════════════════════════════════════════╝\n");
        console.log("📊 Summary:");
        console.log(`✅ Resources defined: ${RESOURCES.length}`);
        console.log(`✅ Permissions created: ${permissions.length}`);
        console.log(`✅ Roles created: 2 (superAdmin, user)`);
        console.log(`✅ Users upserted: 2 (SuperAdmin, Regular User)`);
        console.log(`✅ Messages created: ${messages.length}`);
        console.log(`✅ Banks created: ${banks.length}`);
        console.log(`⏱️  Duration: ${duration}s\n`);

        console.log("📋 Permission breakdown:");
        const breakdown = {};
        permissions.forEach((p) => {
          breakdown[p.resource] = (breakdown[p.resource] || 0) + 1;
        });
        Object.entries(breakdown).forEach(([resource, count]) => {
          console.log(`${resource}: ${count} permissions`);
        });

        console.log("\n👥 Roles created:");
        console.log(
          `🔐 superAdmin: Super Admin (${roles.superAdmin.permissions.length} permissions)`,
        );
        console.log(
          `👤 user: Regular User (${roles.user.permissions.length} permissions - profile, transactions, requests, payment cards, balance)`,
        );

        console.log("\n🔑 SuperAdmin Credentials:");
        console.log(`National ID: 0019431171`);
        console.log(`Name: ${superAdminUser.fullName}`);
        console.log(`Role: SuperAdmin (Full Access)`);
        console.log(`\n👤 Regular User Credentials:`);
        console.log(`National ID: 3240309653`);
        console.log(`Mobile: ${regularUser.mobile}`);
        console.log(`Role: user`);

        console.log("\n✨ Your database is ready to use!");
        console.log("🎯 Next: Login with the SuperAdmin credentials\n");

        process.exit(0);
      } catch (error) {
        console.error("\n❌ Initialization failed:", error);
        process.exit(1);
      }
    });

    mongoConnection.once("error", (error) => {
      console.error("❌ Database connection error:", error);
      process.exit(1);
    });
  });
}

// Run initialization
initializeDatabase();
