import 'package:equatable/equatable.dart';

/// Model representing a KTP (Kartu Tanda Penduduk) Indonesian ID card
class KtpModel extends Equatable {
  /// NIK (Nomor Induk Kependudukan) - National Identity Number
  final String nik;

  /// Full name as shown on the KTP
  final String name;

  /// Place of birth
  final String birthPlace;

  /// Date of birth in format dd-mm-yyyy
  final String birthDate;

  /// Gender (Male/Female)
  final String gender;

  /// Blood type
  final String? bloodType;

  /// Full address
  final String address;

  /// RT/RW (Neighborhood units)
  final String? rtRw;

  /// Kelurahan/Desa (Urban/Rural village)
  final String? kelurahan;

  /// Kecamatan (District)
  final String? kecamatan;

  /// Religion
  final String? religion;

  /// Marital status
  final String? maritalStatus;

  /// Occupation
  final String? occupation;

  /// Nationality
  final String nationality;

  /// URL to the person's photo on the card
  final String? photoUrl;

  /// Issue date of the KTP
  final String? issueDate;

  /// Additional details extracted from the KTP
  final Map<String, dynamic>? extraData;

  const KtpModel({
    required this.nik,
    required this.name,
    required this.birthPlace,
    required this.birthDate,
    required this.gender,
    required this.address,
    required this.nationality,
    this.bloodType,
    this.rtRw,
    this.kelurahan,
    this.kecamatan,
    this.religion,
    this.maritalStatus,
    this.occupation,
    this.photoUrl,
    this.issueDate,
    this.extraData,
  });

  /// Create a KTP model from a map/JSON
  factory KtpModel.fromJson(Map<String, dynamic> json) {
    return KtpModel(
      nik: json['nik'] ?? '',
      name: json['name'] ?? '',
      birthPlace: json['birth_place'] ?? '',
      birthDate: json['birth_date'] ?? '',
      gender: json['gender'] ?? '',
      address: json['address'] ?? '',
      nationality: json['nationality'] ?? 'WNI',
      bloodType: json['blood_type'],
      rtRw: json['rt_rw'],
      kelurahan: json['kelurahan'],
      kecamatan: json['kecamatan'],
      religion: json['religion'],
      maritalStatus: json['marital_status'],
      occupation: json['occupation'],
      photoUrl: json['photo_url'],
      issueDate: json['issue_date'],
      extraData: json['extra_data'] as Map<String, dynamic>?,
    );
  }

  /// Convert the KTP model to a map/JSON
  Map<String, dynamic> toJson() {
    return {
      'nik': nik,
      'name': name,
      'birth_place': birthPlace,
      'birth_date': birthDate,
      'gender': gender,
      'address': address,
      'nationality': nationality,
      'blood_type': bloodType,
      'rt_rw': rtRw,
      'kelurahan': kelurahan,
      'kecamatan': kecamatan,
      'religion': religion,
      'marital_status': maritalStatus,
      'occupation': occupation,
      'photo_url': photoUrl,
      'issue_date': issueDate,
      'extra_data': extraData,
    };
  }

  /// Create an empty KTP model
  factory KtpModel.empty() {
    return const KtpModel(
      nik: '',
      name: '',
      birthPlace: '',
      birthDate: '',
      gender: '',
      address: '',
      nationality: 'WNI',
    );
  }

  /// Parse the birth date into a DateTime object
  /// Expects format: DD-MM-YYYY
  DateTime? get parsedBirthDate {
    try {
      if (birthDate.isEmpty) return null;

      // Split the date string by '-'
      final parts = birthDate.split('-');
      if (parts.length != 3) return null;

      final day = int.tryParse(parts[0]);
      final month = int.tryParse(parts[1]);
      final year = int.tryParse(parts[2]);

      if (day == null || month == null || year == null) return null;

      return DateTime(year, month, day);
    } catch (e) {
      return null;
    }
  }

  /// Format the NIK with proper spacing for display
  /// e.g., "1234567890123456" becomes "1234 5678 9012 3456"
  String get formattedNik {
    if (nik.length != 16) return nik;

    return '${nik.substring(0, 4)} ${nik.substring(4, 8)} ${nik.substring(8, 12)} ${nik.substring(12)}';
  }

  /// Get the person's age based on birth date
  int? get age {
    final birthDateTime = parsedBirthDate;
    if (birthDateTime == null) return null;

    final today = DateTime.now();
    int age = today.year - birthDateTime.year;

    // Adjust age if birthday hasn't occurred yet this year
    if (today.month < birthDateTime.month ||
        (today.month == birthDateTime.month && today.day < birthDateTime.day)) {
      age--;
    }

    return age;
  }

  /// Check if the KTP model contains valid and complete information
  bool get isValid {
    return nik.length == 16 &&
        name.isNotEmpty &&
        birthPlace.isNotEmpty &&
        birthDate.isNotEmpty &&
        gender.isNotEmpty &&
        address.isNotEmpty;
  }

  /// Create a copy of this KTP model with modified fields
  KtpModel copyWith({
    String? nik,
    String? name,
    String? birthPlace,
    String? birthDate,
    String? gender,
    String? bloodType,
    String? address,
    String? rtRw,
    String? kelurahan,
    String? kecamatan,
    String? religion,
    String? maritalStatus,
    String? occupation,
    String? nationality,
    String? photoUrl,
    String? issueDate,
    Map<String, dynamic>? extraData,
  }) {
    return KtpModel(
      nik: nik ?? this.nik,
      name: name ?? this.name,
      birthPlace: birthPlace ?? this.birthPlace,
      birthDate: birthDate ?? this.birthDate,
      gender: gender ?? this.gender,
      bloodType: bloodType ?? this.bloodType,
      address: address ?? this.address,
      rtRw: rtRw ?? this.rtRw,
      kelurahan: kelurahan ?? this.kelurahan,
      kecamatan: kecamatan ?? this.kecamatan,
      religion: religion ?? this.religion,
      maritalStatus: maritalStatus ?? this.maritalStatus,
      occupation: occupation ?? this.occupation,
      nationality: nationality ?? this.nationality,
      photoUrl: photoUrl ?? this.photoUrl,
      issueDate: issueDate ?? this.issueDate,
      extraData: extraData ?? this.extraData,
    );
  }

  @override
  List<Object?> get props => [
    nik,
    name,
    birthPlace,
    birthDate,
    gender,
    bloodType,
    address,
    rtRw,
    kelurahan,
    kecamatan,
    religion,
    maritalStatus,
    occupation,
    nationality,
    photoUrl,
    issueDate,
  ];

  @override
  String toString() {
    return 'KtpModel(nik: $nik, name: $name, birthPlace: $birthPlace, birthDate: $birthDate, gender: $gender)';
  }
}
