import 'package:freezed_annotation/freezed_annotation.dart';
import '../../../models/user_model.dart';

part 'user_dto.freezed.dart';
part 'user_dto.g.dart';

/// 사용자 데이터 전송 객체 (서버 API v0.2.1 대응)
/// GET /api/v1/users/{id} 응답 형태
@freezed
class UserDto with _$UserDto {
  const UserDto._();

  const factory UserDto({
    /// 사용자 ID (자동 생성)
    required int id,
    
    /// 사용자명 (유니크, 필수)
    required String username,
    
    /// 이름 (필수)
    required String name,
    
    /// 이메일 (유니크, 필수)
    required String email,
    
    /// 전화번호 (선택)
    String? phone,
    
    /// 권한 (admin, manager, staff)
    required String role,
    
    /// 활성화 상태 (기본값: true)
    @JsonKey(name: 'is_active') required bool isActive,
    
    /// 생성일시 (자동 입력)
    @JsonKey(name: 'created_at') required DateTime createdAt,
    
    /// 수정일시 (자동 갱신, 선택적)
    @JsonKey(name: 'updated_at') DateTime? updatedAt,
  }) = _UserDto;

  factory UserDto.fromJson(Map<String, dynamic> json) =>
      _$UserDtoFromJson(json);
      
  /// DTO를 도메인 모델로 변환
  User toDomainModel() {
    return User(
      id: id,
      username: username,
      email: email,
      name: name,
      phone: phone,
      role: UserRole.fromString(role),
      isActive: isActive,
      createdAt: createdAt,
      updatedAt: updatedAt,
    );
  }
}

/// 사용자 생성 요청 DTO (POST /api/v1/users)
@freezed
class CreateUserRequest with _$CreateUserRequest {
  const factory CreateUserRequest({
    /// 사용자명 (필수, 유니크, 3자 이상)
    required String username,
    
    /// 이메일 (필수, 유니크, 이메일 형식)
    required String email,
    
    /// 비밀번호 (필수, 6자 이상)
    required String password,
    
    /// 이름 (필수)
    required String name,
    
    /// 전화번호 (선택, "010-1234-5678" 형태)
    String? phone,
    
    /// 권한 (필수: admin, manager, staff)
    required String role,
  }) = _CreateUserRequest;

  factory CreateUserRequest.fromJson(Map<String, dynamic> json) =>
      _$CreateUserRequestFromJson(json);
      
  /// 도메인 모델에서 생성 요청 DTO로 변환
  factory CreateUserRequest.fromDomain(User user, String password) {
    return CreateUserRequest(
      username: user.username,
      email: user.email,
      password: password,
      name: user.name,
      phone: user.phone,
      role: user.role.name,
    );
  }
}

/// 사용자 수정 요청 DTO (PUT /api/v1/users/{id})
@freezed
class UpdateUserRequest with _$UpdateUserRequest {
  const factory UpdateUserRequest({
    /// 이름 (선택)
    String? name,
    
    /// 이메일 (선택, 유니크, 이메일 형식)
    String? email,
    
    /// 비밀번호 (선택, 6자 이상)
    String? password,
    
    /// 전화번호 (선택)
    String? phone,
    
    /// 권한 (선택: admin, manager, staff)
    String? role,
  }) = _UpdateUserRequest;

  factory UpdateUserRequest.fromJson(Map<String, dynamic> json) =>
      _$UpdateUserRequestFromJson(json);
      
  /// 도메인 모델에서 수정 요청 DTO로 변환
  factory UpdateUserRequest.fromDomain(User user, {String? newPassword}) {
    return UpdateUserRequest(
      name: user.name,
      email: user.email,
      password: newPassword,
      phone: user.phone,
      role: user.role.name,
    );
  }
}

/// 사용자명 중복 확인 응답 DTO
@freezed
class CheckUsernameResponse with _$CheckUsernameResponse {
  const factory CheckUsernameResponse({
    required bool available,
    String? message,
  }) = _CheckUsernameResponse;

  factory CheckUsernameResponse.fromJson(Map<String, dynamic> json) =>
      _$CheckUsernameResponseFromJson(json);
}

/// 사용자 목록 응답 DTO (기존 PaginatedResponse 형태 유지)
@freezed
class UserListDto with _$UserListDto {
  const UserListDto._();

  const factory UserListDto({
    required List<UserDto> users,
    required int total,
    required int page,
    @JsonKey(name: 'per_page') required int perPage,
    @JsonKey(name: 'total_pages') required int totalPages,
  }) = _UserListDto;

  // 페이지네이션 응답과 호환성을 위한 getter들
  List<UserDto> get items => users;
  int get size => perPage;
  int get totalElements => total;
  bool get first => page <= 1;
  bool get last => page >= totalPages;

  factory UserListDto.fromJson(Map<String, dynamic> json) =>
      _$UserListDtoFromJson(json);
      
  /// DTO 목록을 도메인 모델 목록으로 변환
  List<User> toDomainModels() {
    return users.map((dto) => dto.toDomainModel()).toList();
  }
}

/// 사용자 상세 응답 DTO
@freezed
class UserDetailDto with _$UserDetailDto {
  const factory UserDetailDto({
    required UserDto user,
  }) = _UserDetailDto;

  factory UserDetailDto.fromJson(Map<String, dynamic> json) =>
      _$UserDetailDtoFromJson(json);
}

/// 일반적인 사용자 API 응답 DTO
@freezed
class UserResponse with _$UserResponse {
  const factory UserResponse({
    required UserDto user,
    String? message,
  }) = _UserResponse;

  factory UserResponse.fromJson(Map<String, dynamic> json) =>
      _$UserResponseFromJson(json);
}

