import {
  IsString,
  IsEmail,
  IsNotEmpty,
  IsOptional,
  MinLength,
  IsArray,
  IsEnum,
  IsDateString,
  IsUUID,
  Matches,
  MaxLength,
  ValidateNested,
} from 'class-validator';
import { Type } from 'class-transformer';

export enum UserStatus {
  ACTIVE = 'ACTIVE',
  INACTIVE = 'INACTIVE',
  SUSPENDED = 'SUSPENDED',
  TERMINATED = 'TERMINATED',
}

export enum UserSource {
  LOCAL = 'LOCAL',
  LDAP = 'LDAP',
  ENTRA = 'ENTRA',
}

/**
 * 批量导入用户成员关系 - 单个用户信息
 * 注意：用户应已通过Entra ID同步创建，此DTO仅用于导入用户-部门关系
 */
export class ImportUserMembershipDto {
  @IsEmail()
  @IsNotEmpty()
  email: string; // 用于查找用户

  @IsString()
  @IsNotEmpty()
  departmentCode: string; // 部门编码

  @IsUUID()
  @IsNotEmpty()
  organizationId: string; // 组织ID

  @IsUUID()
  @IsOptional()
  positionId?: string; // 岗位ID

  @IsEmail()
  @IsOptional()
  managerEmail?: string; // 上级邮箱（用于查找上级）

  @IsString()
  @IsOptional()
  title?: string; // 部门内头衔

  @IsOptional()
  isPrimary?: boolean | string; // 是否主部门（boolean 或 'true'/'false' 字符串）
}

/**
 * 批量导入用户成员关系 - 批量请求DTO
 */
export class ImportUserMembershipsDto {
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => ImportUserMembershipDto)
  @IsNotEmpty()
  users: ImportUserMembershipDto[];
}

export class CreateUserDto {
  @IsString()
  @IsNotEmpty()
  @MinLength(3)
  username: string;

  @IsEmail()
  @IsNotEmpty()
  email: string;

  @IsString()
  @IsNotEmpty()
  @MinLength(8, { message: '密码至少需要8位' })
  @Matches(/^(?=.*[a-z])(?=.*[A-Z])|(?=.*[a-z])(?=.*\d)|(?=.*[A-Z])(?=.*\d)/, {
    message: '密码至少需要包含大写字母、小写字母、数字中的2种',
  })
  @IsOptional() // 外部用户（LDAP/ENTRA）不需要密码
  password?: string;

  @IsString()
  @IsNotEmpty()
  displayName: string;

  @IsEnum(UserSource)
  @IsOptional()
  source?: UserSource; // v2.1.1 身份源

  @IsString()
  @IsOptional()
  phone?: string;

  @IsString()
  @IsOptional()
  avatar?: string;

  @IsString()
  @IsOptional()
  employeeId?: string;

  @IsUUID()
  @IsOptional()
  departmentId?: string;

  @IsUUID()
  @IsOptional()
  positionId?: string;

  @IsUUID()
  @IsOptional()
  managerId?: string;

  @IsString()
  @IsOptional()
  title?: string; // ✅ 新增：部门内头衔

  @IsString()
  @IsOptional()
  region?: string;

  @IsDateString()
  @IsOptional()
  hiredAt?: string;
}

export class UpdateUserDto {
  @IsString()
  @IsOptional()
  displayName?: string;

  @IsEmail()
  @IsOptional()
  email?: string;

  @IsString()
  @IsOptional()
  phone?: string;

  @IsString()
  @IsOptional()
  avatar?: string;

  @IsString()
  @IsOptional()
  employeeId?: string;

  @IsUUID()
  @IsOptional()
  departmentId?: string | null;

  @IsUUID()
  @IsOptional()
  positionId?: string | null;

  @IsUUID()
  @IsOptional()
  managerId?: string | null;

  @IsString()
  @IsOptional()
  region?: string;

  @IsString()
  @IsOptional()
  @MaxLength(100)
  workCity?: string | null;

  @IsEnum(UserStatus)
  @IsOptional()
  status?: UserStatus;
}

/**
 * 角色分配项（v2.1 支持组织级角色）
 */
export class RoleAssignmentDto {
  @IsUUID('4')
  roleId: string;

  @IsUUID('4')
  @IsOptional()
  organizationId?: string | null; // v2.1: 组织 ID，null 表示全局角色
}

/**
 * 分配角色 DTO（v2.1 支持组织级角色分配）
 * 
 * 支持两种格式：
 * 1. 向后兼容：roleIds 数组（分配为全局角色）
 * 2. v2.1 新格式：assignments 数组（支持组织级角色）
 */
export class AssignRolesDto {
  // 向后兼容：角色 ID 数组（将分配为全局角色）
  @IsArray()
  @IsUUID('4', { each: true })
  @IsOptional()
  roleIds?: string[];

  // v2.1 新格式：角色分配项数组（支持组织级角色）
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => RoleAssignmentDto)
  @IsOptional()
  assignments?: RoleAssignmentDto[];
}

/**
 * 区域角色分配项
 */
export class RegionRoleItemDto {
  @IsUUID('4')
  roleId: string;

  @IsString()
  @IsOptional()
  region?: string; // null 或不传表示全局角色
}

/**
 * 分配区域角色 DTO
 * 支持一次性设置用户在所有区域的角色
 */
export class AssignRegionRolesDto {
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => RegionRoleItemDto)
  roles: RegionRoleItemDto[];
}

/**
 * 添加单个区域角色 DTO
 */
export class AddRegionRoleDto {
  @IsUUID('4')
  roleId: string;

  @IsString()
  @IsOptional()
  region?: string; // null 或不传表示全局角色
}

/**
 * 删除区域角色 DTO
 */
export class RemoveRegionRoleDto {
  @IsUUID('4')
  roleId: string;

  @IsString()
  @IsOptional()
  region?: string; // null 或不传表示全局角色
}

export class TerminateUserDto {
  @IsString()
  @IsOptional()
  reason?: string;

  @IsDateString()
  @IsOptional()
  terminatedAt?: string;
}

export class ActivateUserDto {
  @IsString()
  @IsOptional()
  reason?: string;
}

export class UpdateUserStatusDto {
  @IsEnum(UserStatus)
  @IsNotEmpty()
  status: UserStatus;

  @IsString()
  @IsOptional()
  reason?: string;
}

export class RestoreUserDto {
  @IsString()
  @IsOptional()
  reason?: string;
}

export class ResetPasswordDto {
  @IsString()
  @IsNotEmpty()
  @MinLength(8, { message: '密码至少需要8位' })
  @Matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/, {
    message: '密码必须包含大写字母、小写字母和数字',
  })
  newPassword: string;
}

export class UserQueryDto {
  @IsOptional()
  page?: number;

  @IsOptional()
  pageSize?: number;

  @IsString()
  @IsOptional()
  keyword?: string;

  @IsEnum(UserStatus)
  @IsOptional()
  status?: UserStatus;

  @IsUUID()
  @IsOptional()
  departmentId?: string;

  @IsString()
  @IsOptional()
  region?: string;

  @IsString()
  @IsOptional()
  sortBy?: string;

  @IsEnum(['asc', 'desc'])
  @IsOptional()
  sortOrder?: 'asc' | 'desc';

  @IsOptional()
  includeDeleted?: boolean; // ✅ 新增：是否包含已删除用户

  /**
   * 按 externalId 精确查找（通常是 AAD Object ID / LDAP DN 或其他外部系统主键）。
   * 由 OpenClaw 权限 MVP 同步脚本使用：从 agent 目录名提取 AAD GUID 反查 Workspace 用户。
   */
  @IsString()
  @IsOptional()
  externalId?: string;
}
