import 'package:sigap/src/features/auth/data/models/face_model.dart';
import 'package:sigap/src/features/auth/data/models/kta_model.dart';
import 'package:sigap/src/features/auth/data/models/ktp_model.dart';

class RegistrationDataModel {
  // User metadata
  final String? userId;
  final String? email;
  final String? roleId;
  final bool isOfficer;
  final String profileStatus;

  // Step 1: Personal Information
  final PersonalInfoData personalInfo;

  // Step 2: ID Card Verification
  final IdCardVerificationData idCardVerification;

  // Step 3: Selfie Verification
  final SelfieVerificationData selfieVerification;

  // Step 4: Identity Verification (for civilians) OR Officer Info (for officers)
  final IdentityVerificationData? identityVerification;
  final OfficerInfoData? officerInfo;

  // Step 5: Unit Information (for officers only)
  final UnitInfoData? unitInfo;

  // Additional metadata
  final Map<String, dynamic>? additionalData;

  const RegistrationDataModel({
    this.userId,
    this.email,
    this.roleId,
    this.isOfficer = false,
    this.profileStatus = 'incomplete',
    this.personalInfo = const PersonalInfoData(),
    this.idCardVerification = const IdCardVerificationData(),
    this.selfieVerification = const SelfieVerificationData(),
    this.identityVerification,
    this.officerInfo,
    this.unitInfo,
    this.additionalData,
  });

  RegistrationDataModel copyWith({
    String? userId,
    String? email,
    String? roleId,
    bool? isOfficer,
    String? profileStatus,
    PersonalInfoData? personalInfo,
    IdCardVerificationData? idCardVerification,
    SelfieVerificationData? selfieVerification,
    IdentityVerificationData? identityVerification,
    OfficerInfoData? officerInfo,
    UnitInfoData? unitInfo,
    Map<String, dynamic>? additionalData,
  }) {
    return RegistrationDataModel(
      userId: userId ?? this.userId,
      email: email ?? this.email,
      roleId: roleId ?? this.roleId,
      isOfficer: isOfficer ?? this.isOfficer,
      profileStatus: profileStatus ?? this.profileStatus,
      personalInfo: personalInfo ?? this.personalInfo,
      idCardVerification: idCardVerification ?? this.idCardVerification,
      selfieVerification: selfieVerification ?? this.selfieVerification,
      identityVerification: identityVerification ?? this.identityVerification,
      officerInfo: officerInfo ?? this.officerInfo,
      unitInfo: unitInfo ?? this.unitInfo,
      additionalData: additionalData ?? this.additionalData,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'userId': userId,
      'email': email,
      'roleId': roleId,
      'isOfficer': isOfficer,
      'profileStatus': profileStatus,
      'personalInfo': personalInfo.toJson(),
      'idCardVerification': idCardVerification.toJson(),
      'selfieVerification': selfieVerification.toJson(),
      'identityVerification': identityVerification?.toJson(),
      'officerInfo': officerInfo?.toJson(),
      'unitInfo': unitInfo?.toJson(),
      'additionalData': additionalData,
    };
  }

  factory RegistrationDataModel.fromJson(Map<String, dynamic> json) {
    return RegistrationDataModel(
      userId: json['userId'] as String?,
      email: json['email'] as String?,
      roleId: json['roleId'] as String?,
      isOfficer: json['isOfficer'] as bool? ?? false,
      profileStatus: json['profileStatus'] as String? ?? 'incomplete',
      personalInfo: PersonalInfoData.fromJson(json['personalInfo'] ?? {}),
      idCardVerification: IdCardVerificationData.fromJson(
        json['idCardVerification'] ?? {},
      ),
      selfieVerification: SelfieVerificationData.fromJson(
        json['selfieVerification'] ?? {},
      ),
      identityVerification:
          json['identityVerification'] != null
              ? IdentityVerificationData.fromJson(json['identityVerification'])
              : null,
      officerInfo:
          json['officerInfo'] != null
              ? OfficerInfoData.fromJson(json['officerInfo'])
              : null,
      unitInfo:
          json['unitInfo'] != null
              ? UnitInfoData.fromJson(json['unitInfo'])
              : null,
      additionalData: json['additionalData'] as Map<String, dynamic>?,
    );
  }
}

// Personal Information Data Model
class PersonalInfoData {
  final String firstName;
  final String lastName;
  final String fullName;
  final String phone;
  final String address;

  const PersonalInfoData({
    this.firstName = '',
    this.lastName = '',
    this.fullName = '',
    this.phone = '',
    this.address = '',
  });

  PersonalInfoData copyWith({
    String? firstName,
    String? lastName,
    String? fullName,
    String? phone,
    String? address,
  }) {
    return PersonalInfoData(
      firstName: firstName ?? this.firstName,
      lastName: lastName ?? this.lastName,
      fullName: fullName ?? this.fullName,
      phone: phone ?? this.phone,
      address: address ?? this.address,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'firstName': firstName,
      'lastName': lastName,
      'fullName': fullName,
      'phone': phone,
      'address': address,
    };
  }

  factory PersonalInfoData.fromJson(Map<String, dynamic> json) {
    return PersonalInfoData(
      firstName: json['firstName'] as String? ?? '',
      lastName: json['lastName'] as String? ?? '',
      fullName: json['fullName'] as String? ?? '',
      phone: json['phone'] as String? ?? '',
      address: json['address'] as String? ?? '',
    );
  }
}

// ID Card Verification Data Model
class IdCardVerificationData {
  final String? imagePath;
  final bool isValid;
  final bool isConfirmed;
  final String validationMessage;
  final Map<String, String> extractedInfo;
  final KtpModel? ktpModel;
  final KtaModel? ktaModel;
  final FaceModel? faceModel;

  const IdCardVerificationData({
    this.imagePath,
    this.isValid = false,
    this.isConfirmed = false,
    this.validationMessage = '',
    this.extractedInfo = const {},
    this.ktpModel,
    this.ktaModel,
    this.faceModel,
  });

  IdCardVerificationData copyWith({
    String? imagePath,
    bool? isValid,
    bool? isConfirmed,
    String? validationMessage,
    Map<String, String>? extractedInfo,
    KtpModel? ktpModel,
    KtaModel? ktaModel,
    FaceModel? faceModel,
  }) {
    return IdCardVerificationData(
      imagePath: imagePath ?? this.imagePath,
      isValid: isValid ?? this.isValid,
      isConfirmed: isConfirmed ?? this.isConfirmed,
      validationMessage: validationMessage ?? this.validationMessage,
      extractedInfo: extractedInfo ?? this.extractedInfo,
      ktpModel: ktpModel ?? this.ktpModel,
      ktaModel: ktaModel ?? this.ktaModel,
      faceModel: faceModel ?? this.faceModel,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'imagePath': imagePath,
      'isValid': isValid,
      'isConfirmed': isConfirmed,
      'validationMessage': validationMessage,
      'extractedInfo': extractedInfo,
      'ktpModel': ktpModel?.toJson(),
      'ktaModel': ktaModel?.toJson(),
      'faceModel': faceModel?.toJson(),
    };
  }

  factory IdCardVerificationData.fromJson(Map<String, dynamic> json) {
    return IdCardVerificationData(
      imagePath: json['imagePath'] as String?,
      isValid: json['isValid'] as bool? ?? false,
      isConfirmed: json['isConfirmed'] as bool? ?? false,
      validationMessage: json['validationMessage'] as String? ?? '',
      extractedInfo: Map<String, String>.from(json['extractedInfo'] ?? {}),
      ktpModel:
          json['ktpModel'] != null ? KtpModel.fromJson(json['ktpModel']) : null,
      ktaModel:
          json['ktaModel'] != null ? KtaModel.fromJson(json['ktaModel']) : null,
      faceModel:
          json['faceModel'] != null
              ? FaceModel.fromJson(json['faceModel'])
              : null,
    );
  }
}

// Selfie Verification Data Model
class SelfieVerificationData {
  final String? imagePath;
  final bool isSelfieValid;
  final bool isLivenessCheckPassed;
  final bool isMatchWithIDCard;
  final bool isConfirmed;
  final double matchConfidence;
  final FaceModel? faceModel;

  const SelfieVerificationData({
    this.imagePath,
    this.isSelfieValid = false,
    this.isLivenessCheckPassed = false,
    this.isMatchWithIDCard = false,
    this.isConfirmed = false,
    this.matchConfidence = 0.0,
    this.faceModel,
  });

  SelfieVerificationData copyWith({
    String? imagePath,
    bool? isSelfieValid,
    bool? isLivenessCheckPassed,
    bool? isMatchWithIDCard,
    bool? isConfirmed,
    double? matchConfidence,
    FaceModel? faceModel,
  }) {
    return SelfieVerificationData(
      imagePath: imagePath ?? this.imagePath,
      isSelfieValid: isSelfieValid ?? this.isSelfieValid,
      isLivenessCheckPassed:
          isLivenessCheckPassed ?? this.isLivenessCheckPassed,
      isMatchWithIDCard: isMatchWithIDCard ?? this.isMatchWithIDCard,
      isConfirmed: isConfirmed ?? this.isConfirmed,
      matchConfidence: matchConfidence ?? this.matchConfidence,
      faceModel: faceModel ?? this.faceModel,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'imagePath': imagePath,
      'isSelfieValid': isSelfieValid,
      'isLivenessCheckPassed': isLivenessCheckPassed,
      'isMatchWithIDCard': isMatchWithIDCard,
      'isConfirmed': isConfirmed,
      'matchConfidence': matchConfidence,
      'faceModel': faceModel?.toJson(),
    };
  }

  factory SelfieVerificationData.fromJson(Map<String, dynamic> json) {
    return SelfieVerificationData(
      imagePath: json['imagePath'] as String?,
      isSelfieValid: json['isSelfieValid'] as bool? ?? false,
      isLivenessCheckPassed: json['isLivenessCheckPassed'] as bool? ?? false,
      isMatchWithIDCard: json['isMatchWithIDCard'] as bool? ?? false,
      isConfirmed: json['isConfirmed'] as bool? ?? false,
      matchConfidence: (json['matchConfidence'] as num?)?.toDouble() ?? 0.0,
      faceModel:
          json['faceModel'] != null
              ? FaceModel.fromJson(json['faceModel'])
              : null,
    );
  }
}

// Identity Verification Data Model (for civilians)
class IdentityVerificationData {
  final String nik;
  final String fullName;
  final String placeOfBirth;
  final String birthDate;
  final String gender;
  final String address;

  const IdentityVerificationData({
    this.nik = '',
    this.fullName = '',
    this.placeOfBirth = '',
    this.birthDate = '',
    this.gender = '',
    this.address = '',
  });

  IdentityVerificationData copyWith({
    String? nik,
    String? fullName,
    String? placeOfBirth,
    String? birthDate,
    String? gender,
    String? address,
  }) {
    return IdentityVerificationData(
      nik: nik ?? this.nik,
      fullName: fullName ?? this.fullName,
      placeOfBirth: placeOfBirth ?? this.placeOfBirth,
      birthDate: birthDate ?? this.birthDate,
      gender: gender ?? this.gender,
      address: address ?? this.address,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'nik': nik,
      'fullName': fullName,
      'placeOfBirth': placeOfBirth,
      'birthDate': birthDate,
      'gender': gender,
      'address': address,
    };
  }

  factory IdentityVerificationData.fromJson(Map<String, dynamic> json) {
    return IdentityVerificationData(
      nik: json['nik'] as String? ?? '',
      fullName: json['fullName'] as String? ?? '',
      placeOfBirth: json['placeOfBirth'] as String? ?? '',
      birthDate: json['birthDate'] as String? ?? '',
      gender: json['gender'] as String? ?? '',
      address: json['address'] as String? ?? '',
    );
  }
}

// Officer Information Data Model
class OfficerInfoData {
  final String nrp;
  final String rank;
  final String name;

  const OfficerInfoData({this.nrp = '', this.rank = '', this.name = ''});

  OfficerInfoData copyWith({String? nrp, String? rank, String? name}) {
    return OfficerInfoData(
      nrp: nrp ?? this.nrp,
      rank: rank ?? this.rank,
      name: name ?? this.name,
    );
  }

  Map<String, dynamic> toJson() {
    return {'nrp': nrp, 'rank': rank, 'name': name};
  }

  factory OfficerInfoData.fromJson(Map<String, dynamic> json) {
    return OfficerInfoData(
      nrp: json['nrp'] as String? ?? '',
      rank: json['rank'] as String? ?? '',
      name: json['name'] as String? ?? '',
    );
  }
}

// Unit Information Data Model
class UnitInfoData {
  final String unitId;
  final String unitName;
  final String position;

  const UnitInfoData({
    this.unitId = '',
    this.unitName = '',
    this.position = '',
  });

  UnitInfoData copyWith({String? unitId, String? unitName, String? position}) {
    return UnitInfoData(
      unitId: unitId ?? this.unitId,
      unitName: unitName ?? this.unitName,
      position: position ?? this.position,
    );
  }

  Map<String, dynamic> toJson() {
    return {'unitId': unitId, 'unitName': unitName, 'position': position};
  }

  factory UnitInfoData.fromJson(Map<String, dynamic> json) {
    return UnitInfoData(
      unitId: json['unitId'] as String? ?? '',
      unitName: json['unitName'] as String? ?? '',
      position: json['position'] as String? ?? '',
    );
  }
}
