import { Injectable } from "@nestjs/common"
import { PermissionRepository } from "../repositories/permission.repository"
import { CreatePermissionDto } from "../dto/create-permission.dto"
import { isEmpty } from "src/utils/helpers"
import { failureResponse, successResponse } from "src/common/response/response"
import { Permission } from "../entities/permission.entity"
import { messageKey } from "src/constants/message-keys"
import { FindAllPermissionDto } from "../dto/find-all-permission.dto"
import { UpdatePermissionDto } from "../dto/update-permission.dto"
import { code } from "src/common/response/response.code"
import { messages } from "src/constants/messages"

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

  async chekPermissionExist(permission_type: string) {
    const permission = await this.permissionRepository.getByParams({
      where: { permission_type },
      findOne: true,
    })

    return !isEmpty(permission)
  }

  async createPermission(createPermissionDto: CreatePermissionDto) {
    try {
      const result = await this.permissionRepository.save(createPermissionDto)

      return successResponse(code.CREATED, messages.success.data_add, result)
    } catch (error) {
      return failureResponse(code.ERROR, messages.error.something_went_wrong)
    }
  }

  async findAllPermissions(params: FindAllPermissionDto) {
    const validSortColumns = [
      "id",
      "permission_type",
      "created_at",
      "updated_at",
    ]

    let sortColumn: string
    let sortOrder: "ASC" | "DESC"

    if (params.sortBy && validSortColumns.includes(params.sortBy)) {
      sortColumn = params.sortBy
      sortOrder = params.sortOrder || "ASC"
    } else {
      sortColumn = "created_at"
      sortOrder = "DESC"
    }

    const permissions = await this.permissionRepository.getByParams({
      take: Number(params.limit),
      skip: Number(params.skip),
      orderBy: {
        [sortColumn]: sortOrder,
      },
    })

    return permissions
  }

  async findOnePermission(id: number): Promise<Permission> {
    const permission = (await this.permissionRepository.getByParams({
      where: { id },
      findOne: true,
    })) as Permission

    if (!permission) {
      throw new Error(messageKey.data_not_found)
    }

    return permission
  }

  async updatePermission(id: number, updatePermissionDto: UpdatePermissionDto) {
    const permission = (await this.permissionRepository.getByParams({
      where: { id },
      findOne: true,
    })) as Permission

    if (!permission) {
      return failureResponse(404, messageKey.data_not_found)
    }

    Object.assign(permission, updatePermissionDto)
    return await this.permissionRepository.save(permission)
  }

  async remove(id: number) {
    const permission = await this.permissionRepository.getByParams({
      where: { id },
      findOne: true,
    })

    if (isEmpty(permission)) {
      return failureResponse(404, messageKey.data_not_found)
    }

    await this.permissionRepository.remove({ id })

    return { success: true, code: 200, message: messageKey.data_removed }
  }
}
