import { Injectable } from "@nestjs/common"
import { PermissionRepository } from "./repositories/permission.repository"
import { getAllPermissions } from "../../constants/permissions.constant"
import { Permission } from "./entities/permission.entity"

@Injectable()
export class PermissionsSyncService {
  constructor(private readonly permissionRepository: PermissionRepository) {}

  /**
   * Sync permissions from constants to database
   * This method can be called as a cron job or manually
   */
  async syncPermissions() {
    try {
      console.log("🔄 Starting permissions sync...")

      // Get all permissions from constants
      const permissionsData = getAllPermissions()

      let createdCount = 0
      let updatedCount = 0
      let skippedCount = 0

      for (const permissionData of permissionsData) {
        console.log(`Processing permission: ${permissionData.permission_key}`)

        // Check if permission already exists
        const existingPermission: any =
          await this.permissionRepository.getByParams({
            where: {
              group_key: permissionData.group_key,
              permission_key: permissionData.permission_key,
            },
            whereNull: ["deleted_at"],
            findOne: true,
          })

        if (!existingPermission) {
          // Create new permission
          const permission = new Permission()
          permission.group_key = permissionData.group_key
          permission.permission_key = permissionData.permission_key
          permission.label = permissionData.label
          permission.description = permissionData.description
          permission.group_name = permissionData.group_name
          permission.status = 1
          permission.created_by = null // System created

          await this.permissionRepository.save(permission)
          console.log(`✅ Created permission: ${permissionData.permission_key}`)
          createdCount++
        } else {
          // Update existing permission if needed (including group_name)
          let needsUpdate = false

          if (existingPermission.label !== permissionData.label) {
            existingPermission.label = permissionData.label
            needsUpdate = true
          }

          if (existingPermission.description !== permissionData.description) {
            existingPermission.description = permissionData.description
            needsUpdate = true
          }

          if (existingPermission.group_name !== permissionData.group_name) {
            existingPermission.group_name = permissionData.group_name
            needsUpdate = true
          }

          if (needsUpdate) {
            existingPermission.updated_by = null // System updated
            await this.permissionRepository.save(existingPermission)
            console.log(
              `🔄 Updated permission: ${permissionData.permission_key}`,
            )
            updatedCount++
          } else {
            console.log(
              `⏭️  Permission already up-to-date: ${permissionData.permission_key}`,
            )
            skippedCount++
          }
        }
      }

      console.log(`✅ Permissions sync completed!`)
      console.log(
        `📊 Summary: ${createdCount} created, ${updatedCount} updated, ${skippedCount} skipped`,
      )

      return {
        success: true,
        summary: {
          created: createdCount,
          updated: updatedCount,
          skipped: skippedCount,
          total: permissionsData.length,
        },
      }
    } catch (error) {
      console.error("❌ Error syncing permissions:", error)
      throw error
    }
  }

  /**
   * Sync permissions for all existing permissions to ensure group_name is populated
   * This is useful for migrating existing data
   */
  async syncExistingPermissions() {
    try {
      console.log("🔄 Starting sync for existing permissions...")

      // Get all permissions from database
      const existingPermissions: any =
        await this.permissionRepository.getByParams({
          whereNull: ["deleted_at"],
        })

      if (!existingPermissions || existingPermissions.length === 0) {
        console.log("No existing permissions found")
        return { success: true, updated: 0 }
      }

      // Get permissions from constants for reference
      const constantsPermissions = getAllPermissions()
      const permissionsMap = new Map()

      constantsPermissions.forEach((p) => {
        permissionsMap.set(`${p.group_key}_${p.permission_key}`, p)
      })

      let updatedCount = 0

      const permissions = Array.isArray(existingPermissions)
        ? existingPermissions
        : [existingPermissions]

      for (const permission of permissions) {
        const key = `${permission.group_key}_${permission.permission_key}`
        const constantPermission = permissionsMap.get(key)

        if (
          constantPermission &&
          (!permission.group_name ||
            permission.group_name !== constantPermission.group_name)
        ) {
          permission.group_name = constantPermission.group_name
          permission.updated_by = null // System updated
          await this.permissionRepository.save(permission)
          console.log(`🔄 Updated group_name for: ${permission.permission_key}`)
          updatedCount++
        }
      }

      console.log(
        `✅ Existing permissions sync completed! Updated: ${updatedCount}`,
      )

      return {
        success: true,
        updated: updatedCount,
      }
    } catch (error) {
      console.error("❌ Error syncing existing permissions:", error)
      throw error
    }
  }
}
