import 'wayz_common_models.dart';

class WzDistrictLocation {
  final double lat;
  final double lng;

  WzDistrictLocation({required this.lat, required this.lng});

  factory WzDistrictLocation.fromJson(Map<String, dynamic> json) {
    return WzDistrictLocation(
      lat: WzJson.toDouble(json['lat']) ?? 0,
      lng: WzJson.toDouble(json['lng']) ?? 0,
    );
  }

  Map<String, dynamic> toJson() => {
        'lat': lat,
        'lng': lng,
      };
}

/// Item used by `/districts/list` and `/districts/children` (flat/nested).
class WzDistrictItem {
  final String adcode;
  final String province;
  final String? city;
  final String? district;
  final int level;
  final WzDistrictLocation location;

  /// Optional polygon when `need_polygon=true`.
  final dynamic polygon;

  /// Only present in `nested` mode.
  final List<WzDistrictItem>? districts;

  WzDistrictItem({
    required this.adcode,
    required this.province,
    this.city,
    this.district,
    required this.level,
    required this.location,
    this.polygon,
    this.districts,
  });

  factory WzDistrictItem.fromJson(Map<String, dynamic> json) {
    return WzDistrictItem(
      adcode: WzJson.toStringOrNull(json['adcode']) ?? '',
      province: WzJson.toStringOrNull(json['province']) ?? '',
      city: WzJson.toStringOrNull(json['city']),
      district: WzJson.toStringOrNull(json['district']),
      level: WzJson.toInt(json['level']) ?? 0,
      location: WzDistrictLocation.fromJson(
        (json['location'] as Map).cast<String, dynamic>(),
      ),
      polygon: json['polygon'],
      districts: json['districts'] is List
          ? (json['districts'] as List)
              .map(
                (e) => WzDistrictItem.fromJson((e as Map).cast<String, dynamic>()),
              )
              .toList()
          : null,
    );
  }

  Map<String, dynamic> toJson() {
    final out = <String, dynamic>{
      'adcode': adcode,
      'province': province,
      'level': level,
      'location': location.toJson(),
    };
    if (city != null) out['city'] = city;
    if (district != null) out['district'] = district;
    if (polygon != null) out['polygon'] = polygon;
    if (districts != null) out['districts'] = districts!.map((e) => e.toJson()).toList();
    return out;
  }
}

class WzDistrictsListResponse {
  final int status;
  final String message;
  final String dataVersion;
  final List<WzDistrictItem> result;

  WzDistrictsListResponse({
    required this.status,
    required this.message,
    required this.dataVersion,
    required this.result,
  });

  factory WzDistrictsListResponse.fromJson(Map<String, dynamic> json) {
    return WzDistrictsListResponse(
      status: WzJson.toInt(json['status']) ?? 0,
      message: WzJson.toStringOrNull(json['message']) ?? '',
      dataVersion: WzJson.toStringOrNull(json['data_version']) ?? '',
      result: (json['result'] as List? ?? [])
          .map(
            (e) => WzDistrictItem.fromJson((e as Map).cast<String, dynamic>()),
          )
          .toList(),
    );
  }

  Map<String, dynamic> toJson() => {
        'status': status,
        'message': message,
        'data_version': dataVersion,
        'result': result.map((e) => e.toJson()).toList(),
      };
}

/// Item used by `/districts/search` (grouped by level, 2D array).
class WzDistrictSearchItem {
  final String adcode;
  final String name;
  final int level;
  final WzDistrictLocation location;
  final String address;

  WzDistrictSearchItem({
    required this.adcode,
    required this.name,
    required this.level,
    required this.location,
    required this.address,
  });

  factory WzDistrictSearchItem.fromJson(Map<String, dynamic> json) {
    return WzDistrictSearchItem(
      adcode: WzJson.toStringOrNull(json['adcode']) ?? '',
      name: WzJson.toStringOrNull(json['name']) ?? '',
      level: WzJson.toInt(json['level']) ?? 0,
      location: WzDistrictLocation.fromJson(
        (json['location'] as Map).cast<String, dynamic>(),
      ),
      address: WzJson.toStringOrNull(json['address']) ?? '',
    );
  }

  Map<String, dynamic> toJson() => {
        'adcode': adcode,
        'name': name,
        'level': level,
        'location': location.toJson(),
        'address': address,
      };
}

class WzDistrictSearchResponse {
  final int status;
  final String message;
  final String dataVersion;
  final List<List<WzDistrictSearchItem>> result;

  WzDistrictSearchResponse({
    required this.status,
    required this.message,
    required this.dataVersion,
    required this.result,
  });

  factory WzDistrictSearchResponse.fromJson(Map<String, dynamic> json) {
    return WzDistrictSearchResponse(
      status: WzJson.toInt(json['status']) ?? 0,
      message: WzJson.toStringOrNull(json['message']) ?? '',
      dataVersion: WzJson.toStringOrNull(json['data_version']) ?? '',
      result: (json['result'] as List? ?? [])
          .map(
            (group) => (group as List? ?? [])
                .map(
                  (e) => WzDistrictSearchItem.fromJson((e as Map).cast<String, dynamic>()),
                )
                .toList(),
          )
          .toList(),
    );
  }

  Map<String, dynamic> toJson() => {
        'status': status,
        'message': message,
        'data_version': dataVersion,
        'result': result
            .map((group) => group.map((e) => e.toJson()).toList())
            .toList(),
      };
}

