/// Location Remote Data Source
///
/// Handles API calls for cities and wards using Frappe ERPNext client.get_list.
library;

import 'package:dio/dio.dart';
import 'package:worker/core/errors/exceptions.dart';
import 'package:worker/features/account/data/models/city_model.dart';
import 'package:worker/features/account/data/models/ward_model.dart';

/// Location Remote Data Source
///
/// Provides methods to fetch cities and wards from API.
class LocationRemoteDataSource {
  final Dio _dio;

  LocationRemoteDataSource(this._dio);

  /// Get all cities
  ///
  /// API: POST /api/method/frappe.client.get_list
  Future<List<CityModel>> getCities() async {
    try {
      final response = await _dio.post(
        '/api/method/frappe.client.get_list',
        data: {
          'doctype': 'City',
          'fields': ['city_name', 'name', 'code'],
          'limit_page_length': 0,
        },
      );

      if (response.statusCode == 200) {
        final data = response.data;

        if (data is Map<String, dynamic> && data.containsKey('message')) {
          final message = data['message'];

          if (message is List) {
            final cities = message
                .map((item) => CityModel.fromJson(item as Map<String, dynamic>))
                .toList();

            return cities;
          }
        }

        throw const ServerException('Invalid response format');
      } else {
        throw ServerException('Failed to fetch cities: ${response.statusCode}');
      }
    } catch (e) {
      rethrow;
    }
  }

  /// Get wards for a specific city
  ///
  /// API: POST /api/method/frappe.client.get_list
  /// [cityCode] - The city code to filter wards
  Future<List<WardModel>> getWards(String cityCode) async {
    try {
      final response = await _dio.post(
        '/api/method/frappe.client.get_list',
        data: {
          'doctype': 'Ward',
          'fields': ['ward_name', 'name', 'code'],
          'filters': {'city': cityCode},
          'limit_page_length': 0,
        },
      );

      if (response.statusCode == 200) {
        final data = response.data;

        if (data is Map<String, dynamic> && data.containsKey('message')) {
          final message = data['message'];

          if (message is List) {
            final wards = message
                .map((item) => WardModel.fromJson(item as Map<String, dynamic>))
                .toList();

            return wards;
          }
        }

        throw const ServerException('Invalid response format');
      } else {
        throw ServerException('Failed to fetch wards: ${response.statusCode}');
      }
    } catch (e) {
      rethrow;
    }
  }
}
