import { HttpStatus } from '@nestjs/common';
import { BusinessException } from '@common/exceptions/business.exception';

// ==================== Manager Relationship Exceptions ====================

/**
 * Manager loop detected exception
 * Thrown when setting a manager would create a circular reporting chain
 */
export class IamManagerLoopException extends BusinessException {
  constructor() {
    super(
      '检测到汇报关系形成环路',
      'IAM_MANAGER_LOOP_DETECTED',
      HttpStatus.BAD_REQUEST,
    );
  }
}

/**
 * Manager self-reference exception
 * Thrown when a user tries to set themselves as their own manager
 */
export class IamManagerSelfReferenceException extends BusinessException {
  constructor() {
    super(
      '不能将自己设为自己的上级',
      'IAM_MANAGER_SELF_REFERENCE',
      HttpStatus.BAD_REQUEST,
    );
  }
}

// ==================== User Exceptions ====================

/**
 * User email already exists exception
 */
export class IamUserEmailExistsException extends BusinessException {
  constructor(email?: string) {
    super(
      email ? `邮箱 ${email} 已被使用` : '邮箱已被使用',
      'IAM_USER_EMAIL_EXISTS',
      HttpStatus.CONFLICT,
    );
  }
}

/**
 * Username already exists exception
 */
export class IamUsernameExistsException extends BusinessException {
  constructor(username?: string) {
    super(
      username ? `用户名 ${username} 已被使用` : '用户名已被使用',
      'IAM_USERNAME_EXISTS',
      HttpStatus.CONFLICT,
    );
  }
}

/**
 * Employee ID already exists exception
 */
export class IamEmployeeIdExistsException extends BusinessException {
  constructor(employeeId?: string) {
    super(
      employeeId ? `员工编号 ${employeeId} 已被使用` : '员工编号已被使用',
      'IAM_EMPLOYEE_ID_EXISTS',
      HttpStatus.CONFLICT,
    );
  }
}

/**
 * Password too weak exception
 */
export class IamPasswordTooWeakException extends BusinessException {
  constructor(requirements?: string[]) {
    super(
      '密码不符合复杂度要求',
      'IAM_PASSWORD_TOO_WEAK',
      HttpStatus.BAD_REQUEST,
      requirements
        ? { requirements }
        : { requirements: ['8位以上', '至少包含大写字母、小写字母、数字中的2种'] },
    );
  }
}

/**
 * User suspended exception
 */
export class IamUserSuspendedException extends BusinessException {
  constructor() {
    super(
      '账号被停用',
      'IAM_USER_SUSPENDED',
      HttpStatus.FORBIDDEN,
    );
  }
}

/**
 * User terminated exception
 */
export class IamUserTerminatedException extends BusinessException {
  constructor() {
    super(
      '账号已离职',
      'IAM_USER_TERMINATED',
      HttpStatus.FORBIDDEN,
    );
  }
}

/**
 * User locked exception (too many failed login attempts)
 */
export class IamUserLockedException extends BusinessException {
  constructor(unlockTime?: Date) {
    super(
      '用户因多次失败登录被锁定',
      'IAM_USER_LOCKED',
      HttpStatus.LOCKED,
      unlockTime ? { unlockTime: unlockTime.toISOString() } : undefined,
    );
  }
}

/**
 * User already active exception
 */
export class IamUserAlreadyActiveException extends BusinessException {
  constructor() {
    super(
      '用户已处于激活状态',
      'IAM_USER_ALREADY_ACTIVE',
      HttpStatus.BAD_REQUEST,
    );
  }
}

/**
 * Terminated user cannot be activated exception
 */
export class IamTerminatedUserCannotActivateException extends BusinessException {
  constructor() {
    super(
      '离职用户无法通过普通接口激活',
      'IAM_TERMINATED_USER_CANNOT_ACTIVATE',
      HttpStatus.FORBIDDEN,
    );
  }
}

/**
 * Invalid credentials exception
 */
export class IamInvalidCredentialsException extends BusinessException {
  constructor() {
    super(
      '用户名或密码错误',
      'IAM_INVALID_CREDENTIALS',
      HttpStatus.UNAUTHORIZED,
    );
  }
}

// ==================== Role Exceptions ====================

/**
 * System role protected exception
 * Thrown when trying to delete a built-in role
 */
export class IamSystemRoleProtectedException extends BusinessException {
  constructor(roleName?: string) {
    super(
      roleName ? `内置角色 ${roleName} 不可删除` : '内置角色不可删除',
      'IAM_SYSTEM_ROLE_PROTECTED',
      HttpStatus.FORBIDDEN,
    );
  }
}

/**
 * Role has users exception
 * Thrown when trying to delete a role that has users assigned
 */
export class IamRoleHasUsersException extends BusinessException {
  constructor(roleName?: string, userCount?: number) {
    super(
      roleName 
        ? `角色 ${roleName} 下有${userCount || ''}关联用户，无法删除`
        : '角色下有关联用户，无法删除',
      'IAM_ROLE_HAS_USERS',
      HttpStatus.BAD_REQUEST,
      userCount ? { userCount } : undefined,
    );
  }
}

// ==================== Department Exceptions ====================

/**
 * Department code exists exception
 */
export class IamDepartmentCodeExistsException extends BusinessException {
  constructor(code?: string) {
    super(
      code ? `部门编码 ${code} 已存在` : '部门编码已存在',
      'IAM_DEPARTMENT_CODE_EXISTS',
      HttpStatus.CONFLICT,
    );
  }
}

/**
 * Department has children exception
 * Thrown when trying to delete a department that has sub-departments
 */
export class IamDepartmentHasChildrenException extends BusinessException {
  constructor() {
    super(
      '部门下有子部门，无法删除',
      'IAM_DEPARTMENT_HAS_CHILDREN',
      HttpStatus.BAD_REQUEST,
    );
  }
}

/**
 * Department has users exception
 * Thrown when trying to delete a department that has members
 */
export class IamDepartmentHasUsersException extends BusinessException {
  constructor() {
    super(
      '部门下有成员，无法删除',
      'IAM_DEPARTMENT_HAS_USERS',
      HttpStatus.BAD_REQUEST,
    );
  }
}

// ==================== Workflow Role Exceptions ====================

/**
 * Workflow role resolve empty exception
 * Thrown when rule resolution returns no users and no fallback is configured
 */
export class IamWorkflowRoleResolveEmptyException extends BusinessException {
  constructor(roleCode?: string) {
    super(
      roleCode 
        ? `流程角色 ${roleCode} 解析结果为空且无兜底策略`
        : '规则解析结果为空且无兜底策略',
      'IAM_WORKFLOW_ROLE_RESOLVE_EMPTY',
      HttpStatus.UNPROCESSABLE_ENTITY,
    );
  }
}

// ==================== Sync Exceptions ====================

/**
 * Sync in progress exception
 * Thrown when a sync is already running
 */
export class IamSyncInProgressException extends BusinessException {
  constructor() {
    super(
      '已有同步任务正在进行',
      'IAM_SYNC_IN_PROGRESS',
      HttpStatus.CONFLICT,
    );
  }
}

/**
 * External ID mismatch exception
 * Thrown when externalId conflicts with existing record during sync
 */
export class IamExternalIdMismatchException extends BusinessException {
  constructor(externalId?: string) {
    super(
      externalId 
        ? `外部ID ${externalId} 与现有记录冲突`
        : 'externalId 与现有记录冲突',
      'IAM_EXTERNAL_ID_MISMATCH',
      HttpStatus.CONFLICT,
    );
  }
}

// ==================== Token Exceptions ====================

/**
 * Token expired exception
 */
export class IamTokenExpiredException extends BusinessException {
  constructor() {
    super(
      'Token 已过期，需重新登录',
      'IAM_TOKEN_EXPIRED',
      HttpStatus.UNAUTHORIZED,
    );
  }
}

/**
 * Token revoked exception
 */
export class IamTokenRevokedException extends BusinessException {
  constructor() {
    super(
      'Token 已被撤销',
      'IAM_TOKEN_REVOKED',
      HttpStatus.UNAUTHORIZED,
    );
  }
}

// ==================== Region Exceptions ====================

/**
 * Region code exists exception
 */
export class IamRegionCodeExistsException extends BusinessException {
  constructor(code?: string) {
    super(
      code ? `区域编码 ${code} 已存在` : '区域编码已存在',
      'IAM_REGION_CODE_EXISTS',
      HttpStatus.CONFLICT,
    );
  }
}

/**
 * Region has departments exception
 * Thrown when trying to delete a region that has associated departments
 */
export class IamRegionHasDepartmentsException extends BusinessException {
  constructor() {
    super(
      '区域下有关联组织，无法删除',
      'IAM_REGION_HAS_DEPARTMENTS',
      HttpStatus.BAD_REQUEST,
    );
  }
}

/**
 * Only root department can be default exception
 * Thrown when trying to set a non-root department as region default
 */
export class IamOnlyRootDepartmentCanBeDefaultException extends BusinessException {
  constructor() {
    super(
      '只有顶级部门（组织）才能设为区域默认组织',
      'IAM_ONLY_ROOT_DEPARTMENT_CAN_BE_DEFAULT',
      HttpStatus.BAD_REQUEST,
    );
  }
}

// ==================== Multi-Department Exceptions ====================

/**
 * User not in department exception
 * Thrown when a user is not a member of the specified department
 */
export class IamUserNotInDepartmentException extends BusinessException {
  constructor(departmentId?: string) {
    super(
      departmentId 
        ? `用户不属于部门 ${departmentId}`
        : '用户不属于指定部门',
      'IAM_USER_NOT_IN_DEPARTMENT',
      HttpStatus.NOT_FOUND,
    );
  }
}

/**
 * User already in department exception
 * Thrown when trying to add a user to a department they already belong to
 */
export class IamUserAlreadyInDepartmentException extends BusinessException {
  constructor() {
    super(
      '用户已属于该部门',
      'IAM_USER_ALREADY_IN_DEPARTMENT',
      HttpStatus.CONFLICT,
    );
  }
}

/**
 * Cannot remove primary department exception
 * Thrown when trying to remove a user's primary department without setting another
 */
export class IamCannotRemovePrimaryDepartmentException extends BusinessException {
  constructor() {
    super(
      '不能移除主部门，需先设置其他部门为主部门',
      'IAM_CANNOT_REMOVE_PRIMARY_DEPARTMENT',
      HttpStatus.BAD_REQUEST,
    );
  }
}

/**
 * Manager not in department exception
 * Thrown when trying to set a manager who is not a member of the same department
 */
export class IamManagerNotInDepartmentException extends BusinessException {
  constructor() {
    super(
      '上级不是该部门成员',
      'IAM_MANAGER_NOT_IN_DEPARTMENT',
      HttpStatus.BAD_REQUEST,
    );
  }
}

// ==================== Organization Exceptions ====================

/**
 * Organization code already exists exception
 * v2.1.1: 添加组织代码重复异常
 */
export class IamOrganizationCodeExistsException extends BusinessException {
  constructor(code?: string) {
    super(
      code ? `组织代码 ${code} 已被使用` : '组织代码已被使用',
      'IAM_ORGANIZATION_CODE_EXISTS',
      HttpStatus.CONFLICT,
    );
  }
}

/**
 * Organization name already exists exception
 * v2.1.1: 添加组织名称重复异常
 */
export class IamOrganizationNameExistsException extends BusinessException {
  constructor(name?: string) {
    super(
      name ? `组织名称 ${name} 已被使用` : '组织名称已被使用',
      'IAM_ORGANIZATION_NAME_EXISTS',
      HttpStatus.CONFLICT,
    );
  }
}

// ==================== AI Tool Grant Exceptions ====================

/**
 * AI tool grant already exists (role-level)
 * Thrown when the same (roleId, toolName) pair already has a grant
 */
export class IamAiToolGrantRoleExistsException extends BusinessException {
  constructor(roleId?: string, toolName?: string) {
    super(
      roleId && toolName
        ? `角色 ${roleId} 已拥有工具 ${toolName} 的授权`
        : '该角色已拥有此工具的授权',
      'IAM_AI_TOOL_GRANT_ROLE_EXISTS',
      HttpStatus.CONFLICT,
    );
  }
}

/**
 * AI tool grant already exists (user-level)
 * Thrown when the same (userId, toolName) pair already has a direct grant
 */
export class IamAiToolGrantUserExistsException extends BusinessException {
  constructor(userId?: string, toolName?: string) {
    super(
      userId && toolName
        ? `用户 ${userId} 已拥有工具 ${toolName} 的直接授权`
        : '该用户已拥有此工具的直接授权',
      'IAM_AI_TOOL_GRANT_USER_EXISTS',
      HttpStatus.CONFLICT,
    );
  }
}

/**
 * AI tool grant not found
 * Thrown when a grant id does not exist
 */
export class IamAiToolGrantNotFoundException extends BusinessException {
  constructor() {
    super(
      'AI 工具授权记录不存在',
      'IAM_AI_TOOL_GRANT_NOT_FOUND',
      HttpStatus.NOT_FOUND,
    );
  }
}

/**
 * AI tool unknown
 * Thrown when the requested toolName is not in the available-tools catalog
 */
export class IamAiToolUnknownException extends BusinessException {
  constructor(toolName?: string) {
    super(
      toolName
        ? `工具 ${toolName} 不在当前可用工具清单中`
        : '工具不在当前可用工具清单中',
      'IAM_AI_TOOL_UNKNOWN',
      HttpStatus.BAD_REQUEST,
    );
  }
}

export class IamAiToolLockedCannotRemoveException extends BusinessException {
  constructor(toolName: string) {
    super(
      `工具 ${toolName} 是系统锁定的核心对话工具，不可取消`,
      'IAM_AI_TOOL_LOCKED_CANNOT_REMOVE',
      HttpStatus.BAD_REQUEST,
    );
  }
}

export class IamAiToolGrantConflictException extends BusinessException {
  constructor() {
    super(
      '该角色/用户的授权已被其他管理员修改，请刷新后重试',
      'IAM_AI_TOOL_GRANT_CONFLICT',
      HttpStatus.CONFLICT,
    );
  }
}

