import 'package:json_annotation/json_annotation.dart';
import 'package:networks_sdk/networks_sdk.dart';

import '../../../core/foundation/api_paths.dart';
import '../../../domain/entities/user.dart';

part 'login_request.g.dart';

/// # /auth/login — 登录接口
///
/// ## 数据流位置
///
/// ```
/// AuthRepositoryImpl.login(email, password)
///   → _client.executeRequest( ★ LoginRequest ★ )     ← 你在这里
///     → 服务端 POST /auth/login
///     → 响应 JSON → ★ LoginResponse ★                ← 也在这里
///       → LoginResponse.toEntity() → User
/// ```

// ─────────────────────────────────────────────
//  Response DTO
// ─────────────────────────────────────────────

@JsonSerializable(createToJson: false)
class LoginProfile {
  final int uid;
  final String uuid;
  @JsonKey(name: 'last_online')
  final int lastOnline;
  @JsonKey(name: 'profile_pic')
  final String profilePic;
  @JsonKey(name: 'profile_pic_gaussian')
  final String profilePicGaussian;
  final String nickname;
  final String contact;
  @JsonKey(name: 'country_code')
  final String countryCode;
  final String email;
  @JsonKey(name: 'recovery_email')
  final String recoveryEmail;
  final String username;
  final String bio;
  final int relationship;
  @JsonKey(name: 'user_alias')
  final String? userAlias;
  @JsonKey(name: 'channel_id')
  final int channelId;
  @JsonKey(name: 'channel_group_id')
  final int channelGroupId;
  final String hint;

  const LoginProfile({
    required this.uid,
    required this.uuid,
    required this.lastOnline,
    required this.profilePic,
    required this.profilePicGaussian,
    required this.nickname,
    required this.contact,
    required this.countryCode,
    required this.email,
    required this.recoveryEmail,
    required this.username,
    required this.bio,
    required this.relationship,
    this.userAlias,
    required this.channelId,
    required this.channelGroupId,
    required this.hint,
  });

  factory LoginProfile.fromJson(Map<String, dynamic> json) =>
      _$LoginProfileFromJson(json);

  User toEntity() => User(
    uid: uid,
    uuid: uuid,
    lastOnline: lastOnline,
    profilePic: profilePic,
    profilePicGaussian: profilePicGaussian,
    nickname: nickname,
    contact: contact,
    countryCode: countryCode,
    email: email,
    recoveryEmail: recoveryEmail,
    username: username,
    bio: bio,
    relationship: relationship,
    userAlias: userAlias,
    hint: hint,
  );
}

@JsonSerializable(createToJson: false, explicitToJson: true)
class LoginData {
  @JsonKey(name: 'account_id')
  final String accountId;
  final LoginProfile profile;
  final String nonce;
  @JsonKey(name: 'access_token')
  final String accessToken;
  @JsonKey(name: 'refresh_token')
  final String refreshToken;
  @JsonKey(name: 'device_id')
  final String deviceId;
  @JsonKey(name: 'login_data')
  final String loginData;

  const LoginData({
    required this.accountId,
    required this.profile,
    required this.nonce,
    required this.accessToken,
    required this.refreshToken,
    required this.deviceId,
    required this.loginData,
  });

  factory LoginData.fromJson(Map<String, dynamic> json) =>
      _$LoginDataFromJson(json);

  User toEntity() => profile.toEntity();
}

/// Top-level envelope: { "code": 0, "message": "OK", "data": { ... } }
@JsonSerializable(createToJson: false, explicitToJson: true)
class LoginResponse {
  final int code;
  final String message;
  final LoginData data;

  const LoginResponse({
    required this.code,
    required this.message,
    required this.data,
  });

  factory LoginResponse.fromJson(Map<String, dynamic> json) =>
      _$LoginResponseFromJson(json);

  User toEntity() => data.toEntity();
}

// ─────────────────────────────────────────────
//  Request
// ─────────────────────────────────────────────

@ApiRequest(
  path: ApiPaths.authLogin,
  method: HttpMethod.post,
  responseType: LoginResponse,
  requestType: ApiRequestType.login,
)
@JsonSerializable()
class LoginRequest extends ApiRequestable<LoginResponse>
    with _$LoginRequestApi {
  final String email;
  final String password;

  LoginRequest({required this.email, required this.password});

  factory LoginRequest.fromJson(Map<String, dynamic> json) =>
      _$LoginRequestFromJson(json);

  @override
  Map<String, dynamic> toJson() => _$LoginRequestToJson(this);
}
