import 'package:sigap/src/features/map/data/models/models/districts_model.dart';
import 'package:sigap/src/features/panic-button/data/models/models/crime_incidents_model.dart';

enum CrimeRates { low, medium, high, critical }

class CrimeModel {
  final String id;
  final String districtId;
  final DateTime? createdAt;
  final CrimeRates level;
  final String? method;
  final int? month;
  final int numberOfCrime;
  final double score;
  final DateTime? updatedAt;
  final int? year;
  final String? sourceType;
  final int crimeCleared;
  final double avgCrime;
  final List<CrimeIncidentModel>? crimeIncidents;
  final DistrictModel? district;

  CrimeModel({
    required this.id,
    required this.districtId,
    this.createdAt,
    required this.level,
    this.method,
    this.month,
    required this.numberOfCrime,
    required this.score,
    this.updatedAt,
    this.year,
    this.sourceType,
    required this.crimeCleared,
    required this.avgCrime,
    this.crimeIncidents,
    this.district,
  });

  // Create a CrimeModel instance from a JSON object
  factory CrimeModel.fromJson(Map<String, dynamic> json) {
    return CrimeModel(
      id: json['id'] as String,
      districtId: json['district_id'] as String,
      createdAt:
          json['created_at'] != null
              ? DateTime.parse(json['created_at'])
              : null,
      level: _parseCrimeRate(json['level'] as String),
      method: json['method'] as String?,
      month: json['month'] as int?,
      numberOfCrime: json['number_of_crime'] as int,
      score: json['score'].toDouble(),
      updatedAt:
          json['updated_at'] != null
              ? DateTime.parse(json['updated_at'])
              : null,
      year: json['year'] as int?,
      sourceType: json['source_type'] as String?,
      crimeCleared: json['crime_cleared'] as int,
      avgCrime: json['avg_crime'].toDouble(),
      crimeIncidents:
          json['crime_incidents'] != null
              ? (json['crime_incidents'] as List)
                  .map(
                    (e) =>
                        CrimeIncidentModel.fromJson(e as Map<String, dynamic>),
                  )
                  .toList()
              : null,
      district:
          json['districts'] != null
              ? DistrictModel.fromJson(
                json['districts'] as Map<String, dynamic>,
              )
              : null,
    );
  }

  // Convert a CrimeModel instance to a JSON object
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'district_id': districtId,
      'created_at': createdAt?.toIso8601String(),
      'level': level.name,
      'method': method,
      'month': month,
      'number_of_crime': numberOfCrime,
      'score': score,
      'updated_at': updatedAt?.toIso8601String(),
      'year': year,
      'source_type': sourceType,
      'crime_cleared': crimeCleared,
      'avg_crime': avgCrime,
    };
  }

  // Create a copy of the CrimeModel with updated fields
  CrimeModel copyWith({
    String? id,
    String? districtId,
    DateTime? createdAt,
    CrimeRates? level,
    String? method,
    int? month,
    int? numberOfCrime,
    double? score,
    DateTime? updatedAt,
    int? year,
    String? sourceType,
    int? crimeCleared,
    double? avgCrime,
    List<CrimeIncidentModel>? crimeIncidents,
    DistrictModel? district,
  }) {
    return CrimeModel(
      id: id ?? this.id,
      districtId: districtId ?? this.districtId,
      createdAt: createdAt ?? this.createdAt,
      level: level ?? this.level,
      method: method ?? this.method,
      month: month ?? this.month,
      numberOfCrime: numberOfCrime ?? this.numberOfCrime,
      score: score ?? this.score,
      updatedAt: updatedAt ?? this.updatedAt,
      year: year ?? this.year,
      sourceType: sourceType ?? this.sourceType,
      crimeCleared: crimeCleared ?? this.crimeCleared,
      avgCrime: avgCrime ?? this.avgCrime,
      crimeIncidents: crimeIncidents ?? this.crimeIncidents,
      district: district ?? this.district,
    );
  }

  static CrimeRates _parseCrimeRate(String rate) {
    switch (rate.toLowerCase()) {
      case 'low':
        return CrimeRates.low;
      case 'medium':
        return CrimeRates.medium;
      case 'high':
        return CrimeRates.high;
      case 'critical':
        return CrimeRates.critical;
      default:
        return CrimeRates.low;
    }
  }

  @override
  String toString() {
    return 'CrimeModel(id: $id, districtId: $districtId, level: ${level.name}, year: $year, month: $month)';
  }
}
