import '../../../../core/errors/exceptions.dart';
import '../../../../core/network/api_client.dart';
import '../../../../core/network/api_response.dart';
import '../models/warehouse_model.dart';

/// Abstract interface for warehouse remote data source
abstract class WarehouseRemoteDataSource {
  /// Get all warehouses from the API
  ///
  /// Returns [List<WarehouseModel>] on success
  /// Throws [ServerException] on API errors
  /// Throws [NetworkException] on network errors
  Future<List<WarehouseModel>> getWarehouses();
}

/// Implementation of warehouse remote data source
/// Uses ApiClient to make HTTP requests to the backend
class WarehouseRemoteDataSourceImpl implements WarehouseRemoteDataSource {
  final ApiClient apiClient;

  WarehouseRemoteDataSourceImpl(this.apiClient);

  @override
  Future<List<WarehouseModel>> getWarehouses() async {
    try {
      // Make POST request to /portalWareHouse/search endpoint
      final response = await apiClient.post(
        '/portalWareHouse/search',
        data: {
          'pageIndex': 0,
          'pageSize': 100,
          'Name': null,
          'Code': null,
          'sortExpression': null,
          'sortDirection': null,
        },
      );

      // Parse the API response wrapper
      final apiResponse = ApiResponse.fromJson(
        response.data,
        (json) {
          // Handle the list of warehouses
          if (json is List) {
            return json.map((e) => WarehouseModel.fromJson(e)).toList();
          }
          throw const ServerException('Invalid response format: expected List');
        },
      );

      // Check if API call was successful
      if (apiResponse.isSuccess && apiResponse.value != null) {
        return apiResponse.value!;
      } else {
        // Extract error message from API response
        final errorMessage = apiResponse.errors.isNotEmpty
            ? apiResponse.errors.first
            : 'Failed to get warehouses';

        throw ServerException(
          errorMessage,
          code: apiResponse.firstErrorCode,
        );
      }
    } on ServerException {
      rethrow;
    } on NetworkException {
      rethrow;
    } catch (e) {
      // Wrap any unexpected errors
      throw ServerException(
        'Unexpected error while fetching warehouses: ${e.toString()}',
      );
    }
  }
}
