import { db } from '@/src/db/db_index'
import {
  units,
  productInfo,
  deliverySlotInfo,
  keyValStore,
  staffRoles,
  staffPermissions,
  staffRolePermissions,
} from '@/src/db/schema'
import { eq } from 'drizzle-orm'
import { minOrderValue, deliveryCharge } from '@/src/lib/env-exporter'
import { CONST_KEYS } from '@/src/lib/const-keys'

export async function seed() {
  console.log('Seeding database...')

  // Seed units individually
  const unitsToSeed = [
    { shortNotation: 'Kg', fullName: 'Kilogram' },
    { shortNotation: 'L', fullName: 'Litre' },
    { shortNotation: 'Dz', fullName: 'Dozen' },
    { shortNotation: 'Pc', fullName: 'Unit Piece' },
  ]

  for (const unit of unitsToSeed) {
    const existingUnit = await db.query.units.findFirst({
      where: eq(units.shortNotation, unit.shortNotation),
    })
    if (!existingUnit) {
      await db.insert(units).values(unit)
    }
  }

  // Seed staff roles individually
  const rolesToSeed = ['super_admin', 'admin', 'marketer', 'delivery_staff'] as const

  for (const roleName of rolesToSeed) {
    const existingRole = await db.query.staffRoles.findFirst({
      where: eq(staffRoles.roleName, roleName),
    })
    if (!existingRole) {
      await db.insert(staffRoles).values({ roleName })
    }
  }

  // Seed staff permissions individually
  const permissionsToSeed = ['crud_product', 'make_coupon', 'crud_staff_users'] as const

  for (const permissionName of permissionsToSeed) {
    const existingPermission = await db.query.staffPermissions.findFirst({
      where: eq(staffPermissions.permissionName, permissionName),
    })
    if (!existingPermission) {
      await db.insert(staffPermissions).values({ permissionName })
    }
  }

  // Seed role-permission assignments
  await db.transaction(async (tx) => {
    // Get role IDs
    const superAdminRole = await tx.query.staffRoles.findFirst({ where: eq(staffRoles.roleName, 'super_admin') })
    const adminRole = await tx.query.staffRoles.findFirst({ where: eq(staffRoles.roleName, 'admin') })
    const marketerRole = await tx.query.staffRoles.findFirst({ where: eq(staffRoles.roleName, 'marketer') })

    // Get permission IDs
    const crudProductPerm = await tx.query.staffPermissions.findFirst({ where: eq(staffPermissions.permissionName, 'crud_product') })
    const makeCouponPerm = await tx.query.staffPermissions.findFirst({ where: eq(staffPermissions.permissionName, 'make_coupon') })
    const crudStaffUsersPerm = await tx.query.staffPermissions.findFirst({ where: eq(staffPermissions.permissionName, 'crud_staff_users') })

    // Assign all permissions to super_admin
    ;[crudProductPerm, makeCouponPerm, crudStaffUsersPerm].forEach(async (perm) => {
      if (superAdminRole && perm) {
        const existingSuperAdminPerm = await tx.query.staffRolePermissions.findFirst({
          where: eq(staffRolePermissions.staffRoleId, superAdminRole.id) && eq(staffRolePermissions.staffPermissionId, perm.id),
        })
        if (!existingSuperAdminPerm) {
          await tx.insert(staffRolePermissions).values({
            staffRoleId: superAdminRole.id,
            staffPermissionId: perm.id,
          })
        }
      }
    })

    // Assign all permissions to admin
    ;[crudProductPerm, makeCouponPerm].forEach(async (perm) => {
      if (adminRole && perm) {
        const existingAdminPerm = await tx.query.staffRolePermissions.findFirst({
          where: eq(staffRolePermissions.staffRoleId, adminRole.id) && eq(staffRolePermissions.staffPermissionId, perm.id),
        })
        if (!existingAdminPerm) {
          await tx.insert(staffRolePermissions).values({
            staffRoleId: adminRole.id,
            staffPermissionId: perm.id,
          })
        }
      }
    })

    // Assign make_coupon to marketer
    if (marketerRole && makeCouponPerm) {
      const existingMarketerCoupon = await tx.query.staffRolePermissions.findFirst({
        where: eq(staffRolePermissions.staffRoleId, marketerRole.id) && eq(staffRolePermissions.staffPermissionId, makeCouponPerm.id),
      })
      if (!existingMarketerCoupon) {
        await tx.insert(staffRolePermissions).values({
          staffRoleId: marketerRole.id,
          staffPermissionId: makeCouponPerm.id,
        })
      }
    }
  })

  // Seed key-val store constants using CONST_KEYS
  const constantsToSeed = [
    { key: CONST_KEYS.readableOrderId, value: 0 },
    { key: CONST_KEYS.minRegularOrderValue, value: minOrderValue },
    { key: CONST_KEYS.freeDeliveryThreshold, value: minOrderValue },
    { key: CONST_KEYS.deliveryCharge, value: deliveryCharge },
    { key: CONST_KEYS.flashFreeDeliveryThreshold, value: 500 },
    { key: CONST_KEYS.flashDeliveryCharge, value: 69 },
    { key: CONST_KEYS.popularItems, value: [] },
    { key: CONST_KEYS.allItemsOrder, value: [] },
    { key: CONST_KEYS.versionNum, value: '1.1.0' },
    { key: CONST_KEYS.playStoreUrl, value: 'https://play.google.com/store/apps/details?id=in.freshyo.app' },
    { key: CONST_KEYS.appStoreUrl, value: 'https://apps.apple.com/in/app/freshyo/id6756889077' },
    { key: CONST_KEYS.isFlashDeliveryEnabled, value: false },
    { key: CONST_KEYS.supportMobile, value: '8688182552' },
    { key: CONST_KEYS.supportEmail, value: 'qushammohd@gmail.com' },
  ]

  for (const constant of constantsToSeed) {
    const existing = await db.query.keyValStore.findFirst({
      where: eq(keyValStore.key, constant.key),
    })
    if (!existing) {
      await db.insert(keyValStore).values({
        key: constant.key,
        value: constant.value,
      })
    }
  }

  console.log('Seeding completed.')
}
