import { Injectable } from "@nestjs/common"
import { AuthService } from "../../../modules/auth/auth.service"
import { RoleService } from "../../../modules/role/role.service"
import { defaultAdmins } from "../../../config/app.config"
import { Auth } from "../../../modules/auth/entities/auth.entity"
import { PermissionsService } from "../../../modules/permissions/permissions.service"
import { RolePermissionRepository } from "../../../modules/role-permissions/repositories/role-permission.repository"
import { RolePermission } from "../../../modules/role-permissions/entities/role-permission.entity"
import { PERMISSIONS } from "../../../constants/permissions.constant"
import { AuthRepository } from "src/modules/auth/repositories/auth.repository"

@Injectable()
export class AdminSeedService {
  constructor(
    private readonly authService: AuthService,
    private readonly roleService: RoleService,
    private readonly permissionsService: PermissionsService,
    private readonly rolePermissionRepository: RolePermissionRepository,
    private readonly authRepository: AuthRepository,
  ) {}

  async run() {
    try {
      // First, find the master_admin role (without company_id since it's a global role)
      const masterAdminRole =
        await this.roleService.findRoleByNameAndCompany("master_admin")

      if (!masterAdminRole) {
        console.error(
          "❌ master_admin role not found. Please run RoleSeedService first.",
        )
        return
      }

      for (const admin of defaultAdmins) {
        const isAdminExist: any = await this.authService.checkAdminExist(
          admin.email,
        )

        if (isAdminExist && !isAdminExist.slug) {
          const existingAdmin: any = await this.authRepository.getByParams({
            where: {
              email: admin.email,
            },
            findOne: true,
          })
          if (existingAdmin) {
            existingAdmin.slug = admin.slug
            await this.authRepository.save(existingAdmin)
            console.log(`🔄 Slug updated for admin: ${admin.email}`)
          }
        }

        if (!isAdminExist) {
          const user = new Auth()
          user.first_name = admin.first_name
          user.last_name = admin.last_name
          user.email = admin.email
          user.password = admin.password
          user.role_id = masterAdminRole.id // Use dynamic role ID
          user.status = 1
          user.slug = admin.slug

          await this.authService.create(user)

          console.log(
            `✅ Admin user created: ${admin.email} with role_id: ${masterAdminRole.id}`,
          )
        } else {
          console.log("Admins already exist, seeding skipped.")
        }
      }

      // Assign COMPANY permissions to master_admin role
      await this.assignCompanyPermissionsToMasterAdmin(masterAdminRole.id)
    } catch (error) {
      console.error("Error running Admin seeder:", error)
      throw error
    }
  }

  private async assignCompanyPermissionsToMasterAdmin(
    masterAdminRoleId: number,
  ) {
    try {
      console.log("🔐 Assigning COMPANY permissions to master_admin role...")

      // Get COMPANY permissions specifically
      const companyPermissions = [
        PERMISSIONS.COMPANY.VIEW,
        PERMISSIONS.COMPANY.MANAGE,
      ]

      for (const permissionKey of companyPermissions) {
        // Find the permission in database
        const permission: any =
          await this.permissionsService.findByPermissionKey(permissionKey)

        if (!permission) {
          console.log(`⚠️  Permission not found: ${permissionKey}`)
          continue
        }

        // Check if role-permission already exists
        const existingRolePermission: any =
          await this.rolePermissionRepository.getByParams({
            where: {
              role_id: masterAdminRoleId,
              permission_id: permission.id,
            },
            whereNull: ["deleted_at"],
            findOne: true,
          })

        if (!existingRolePermission) {
          // Create new role-permission assignment (no company_id for master admin)
          const rolePermission = new RolePermission()
          rolePermission.role_id = masterAdminRoleId
          rolePermission.permission_id = permission.id
          rolePermission.company_id = null // Master admin has global permissions
          rolePermission.status = 1
          rolePermission.created_by = null // System user

          await this.rolePermissionRepository.save(rolePermission)
          console.log(
            `✅ Assigned permission: ${permissionKey} to master_admin`,
          )
        } else {
          // Update status if it's inactive
          if (existingRolePermission.status !== 1) {
            existingRolePermission.status = 1
            await this.rolePermissionRepository.save(existingRolePermission)
            console.log(
              `🔄 Activated permission: ${permissionKey} for master_admin`,
            )
          } else {
            console.log(`⏭️  Permission already assigned: ${permissionKey}`)
          }
        }
      }

      console.log(
        "✅ COMPANY permissions assignment completed for master_admin",
      )
    } catch (error) {
      console.error(
        "❌ Error assigning COMPANY permissions to master_admin:",
        error,
      )
      throw error
    }
  }
}
