import 'package:rasadyar_chicken/data/models/request/conform_allocation/conform_allocation.dart';
import 'package:rasadyar_chicken/data/models/request/create_steward_free_bar/create_steward_free_bar.dart';
import 'package:rasadyar_chicken/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.dart';
import 'package:rasadyar_chicken/data/models/request/submit_steward_allocation/submit_steward_allocation.dart';
import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.dart';
import 'package:rasadyar_chicken/data/models/response/bar_information/bar_information.dart';
import 'package:rasadyar_chicken/data/models/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.dart';
import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart';
import 'package:rasadyar_chicken/data/models/response/guild_profile/guild_profile.dart';
import 'package:rasadyar_chicken/data/models/response/imported_loads_model/imported_loads_model.dart';
import 'package:rasadyar_chicken/data/models/response/inventory/inventory_model.dart';
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart';
import 'package:rasadyar_chicken/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart';
import 'package:rasadyar_chicken/data/models/response/pagination_model/pagination_model.dart';
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart';
import 'package:rasadyar_chicken/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart';
import 'package:rasadyar_chicken/data/models/response/steward_free_sale_bar/steward_free_sale_bar.dart';
import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart'
    hide ProductModel;
import 'package:rasadyar_core/core.dart';

import 'chicken_repository.dart';

class ChickenRepositoryImpl implements ChickenRepository {
  final DioRemote _httpClient;

  ChickenRepositoryImpl(this._httpClient);

  @override
  Future<List<InventoryModel>?> getInventory({required String token}) async {
    var res = await _httpClient.get(
      '/roles-products/?role=Steward',
      headers: {'Authorization': 'Bearer $token'},
      fromJsonList: (json) => (json)
          .map((item) => InventoryModel.fromJson(item as Map<String, dynamic>))
          .toList(),
    );

    return res.data;
  }

  @override
  Future<KillHouseDistributionInfo?> getKillHouseDistributionInfo({
    required String token,
  }) async {
    var res = await _httpClient.get(
      '/kill-house-distribution-info/?role=Steward',
      headers: {'Authorization': 'Bearer $token'},
      fromJson: KillHouseDistributionInfo.fromJson,
    );

    return res.data;
  }

  @override
  Future<BarInformation?> getGeneralBarInformation({
    required String token,
    Map<String, dynamic>? queryParameters,
  }) async {
    var res = await _httpClient.get(
      '/bars_for_kill_house_dashboard/?role=Steward',
      queryParameters: queryParameters,
      headers: {'Authorization': 'Bearer $token'},
      fromJson: BarInformation.fromJson,
    );
    return res.data;
  }

  @override
  Future<WaitingArrivalModel?> getWaitingArrivals({
    required String token,
    int? page,
  }) async {
    var res = await _httpClient.get(
      '/steward-allocation/?search=filter&value=&role=Steward&page=${page ?? 1}&page_size=10&type=not_entered',
      headers: {'Authorization': 'Bearer $token'},
      fromJson: WaitingArrivalModel.fromJson,
    );
    return res.data;
  }

  @override
  Future<void> setSateForArrivals({
    required String token,
    required Map<String, dynamic> request,
  }) async {
    await _httpClient.put(
      '/steward-allocation/0/',
      headers: {'Authorization': 'Bearer $token'},
      data: request,
    );
  }

  @override
  Future<ImportedLoadsModel?> getImportedLoadsModel({
    required String token,
    required int page,
  }) async {
    var res = await _httpClient.get(
      '/steward-allocation/?role=Steward&search=filter&page=$page&page_size=10&value=&type=entered',
      headers: {'Authorization': 'Bearer $token'},
      fromJson: ImportedLoadsModel.fromJson,
    );
    return res.data;
  }

  @override
  Future<PaginationModel<AllocatedMadeModel>?> getAllocatedMade({
    required String token,
    Map<String, dynamic>? queryParameters,
  }) async {
    var res = await _httpClient.get(
      '/steward-allocation/',
      queryParameters: queryParameters,
      headers: {'Authorization': 'Bearer $token'},
      fromJson: (json) => PaginationModel<AllocatedMadeModel>.fromJson(
        json,
        (json) => AllocatedMadeModel.fromJson(json as Map<String, dynamic>),
      ),
    );
    return res.data;
  }

  @override
  Future<void> confirmAllocation({
    required String token,
    required Map<String, dynamic> allocation,
  }) async {
    var res = await _httpClient.put(
      '/steward-allocation/0/',
      headers: {'Authorization': 'Bearer $token'},
      data: allocation,
    );
  }

  @override
  Future<void> denyAllocation({
    required String token,
    required String allocationToken,
  }) async {
    await _httpClient.delete(
      '/steward-allocation/0/?steward_allocation_key=$allocationToken',
      headers: {'Authorization': 'Bearer $token'},
    );
  }

  @override
  Future<void> confirmAllAllocation({
    required String token,
    required List<String> allocationTokens,
  }) async {
    await _httpClient.put(
      '/steward-allocation/0/',
      headers: {'Authorization': 'Bearer $token'},
      data: {'steward_allocation_list': allocationTokens},
    );
  }

  @override
  Future<List<ProductModel>?> getRolesProducts({required String token}) async {
    var res = await _httpClient.get(
      '/roles-products/?role=Steward',
      headers: {'Authorization': 'Bearer $token'},
      fromJsonList: (json) => json
          .map((item) => ProductModel.fromJson(item as Map<String, dynamic>))
          .toList(),
    );
    return res.data;
  }

  @override
  Future<List<GuildModel>?> getGuilds({
    required String token,
    Map<String, dynamic>? queryParameters,
  }) async {
    var res = await _httpClient.get(
      '/guilds/?',
      queryParameters: queryParameters,
      headers: {'Authorization': 'Bearer $token'},
      fromJsonList: (json) => json
          .map((item) => GuildModel.fromJson(item as Map<String, dynamic>))
          .toList(),
    );
    return res.data;
  }

  @override
  Future<GuildProfile?> getProfile({required String token}) async {
    var res = await _httpClient.get(
      '/guilds/0/?profile',
      headers: {'Authorization': 'Bearer $token'},
      fromJson: GuildProfile.fromJson,
    );
    return res.data;
  }

  @override
  Future<void> postSubmitStewardAllocation({
    required String token,
    required SubmitStewardAllocation request,
  }) async {
    await _httpClient.post(
      '/steward-allocation/',
      headers: {'Authorization': 'Bearer $token'},
      data: request.toJson(),
    );
  }

  @override
  Future<void> deleteStewardAllocation({
    required String token,
    Map<String, dynamic>? queryParameters,
  }) async {
    await _httpClient.delete(
      '/steward-allocation/0/',
      headers: {'Authorization': 'Bearer $token'},
      queryParameters: queryParameters,
    );
  }

  @override
  Future<void> updateStewardAllocation({
    required String token,
    required ConformAllocation request,
  }) async {
    await _httpClient.put(
      '/steward-allocation/0/',
      headers: {'Authorization': 'Bearer $token'},
      queryParameters: request.toJson(),
    );
  }

  @override
  Future<StewardFreeBarDashboard?> getStewardDashboard({
    required String token,
    required String stratDate,
    required String endDate,
  }) async {
    var res = await _httpClient.get(
      '/steward_free_bar_dashboard/?date1=$stratDate&date2=$endDate&search=filter',
      headers: {'Authorization': 'Bearer $token'},
      fromJson: StewardFreeBarDashboard.fromJson,
    );
    return res.data;
  }

  @override
  Future<DashboardKillHouseFreeBar?> getDashboardKillHouseFreeBar({
    required String token,
    required String stratDate,
    required String endDate,
  }) async {
    var res = await _httpClient.get(
      '/dashboard_kill_house_free_bar/?date1=$stratDate&date2=$endDate&search=filter',
      headers: {'Authorization': 'Bearer $token'},
      fromJson: DashboardKillHouseFreeBar.fromJson,
    );
    return res.data;
  }

  @override
  Future<PaginationModel<StewardFreeBar>?>
  getStewardPurchasesOutSideOfTheProvince({
    required String token,
    Map<String, dynamic>? queryParameters,
  }) async {
    var res = await _httpClient.get(
      '/steward_free_bar/?',
      queryParameters: queryParameters,
      headers: {'Authorization': 'Bearer $token'},
      fromJson: (json) => PaginationModel<StewardFreeBar>.fromJson(
        json,
        (json) => StewardFreeBar.fromJson(json as Map<String, dynamic>),
      ),
    );
    return res.data;
  }

  @override
  Future<List<IranProvinceCityModel>?> getCity({
    required String provinceName,
  }) async {
    var res = await _httpClient.get(
      '/iran_city/?',
      queryParameters: {'name': provinceName},
      fromJsonList: (json) => json
          .map(
            (item) =>
                IranProvinceCityModel.fromJson(item as Map<String, dynamic>),
          )
          .toList(),
    );
    return res.data;
  }

  @override
  Future<List<IranProvinceCityModel>?> getProvince() async {
    var res = await _httpClient.get(
      '/iran_province/',
      fromJsonList: (json) => json
          .map(
            (item) =>
                IranProvinceCityModel.fromJson(item as Map<String, dynamic>),
          )
          .toList(),
    );
    return res.data;
  }

  @override
  Future<void> createStewardPurchasesOutSideOfTheProvince({
    required String token,
    required CreateStewardFreeBar body,
  }) async {
    var res = await _httpClient.post(
      '/steward_free_bar/',
      headers: {'Authorization': 'Bearer $token'},
      data: body.toJson(),
    );
  }

  @override
  Future<void> deleteStewardPurchasesOutSideOfTheProvince({
    required String token,
    required String stewardFreeBarKey,
  }) async {
    await _httpClient.delete(
      '/steward_free_bar/0/?',
      headers: {'Authorization': 'Bearer $token'},
      queryParameters: {'key': stewardFreeBarKey},
    );
  }

  @override
  Future<PaginationModel<OutProvinceCarcassesBuyer>?>
  getOutProvinceCarcassesBuyer({
    required String token,
    Map<String, dynamic>? queryParameters,
  }) async {
    var res = await _httpClient.get(
      '/out-province-carcasses-buyer/?',
      queryParameters: queryParameters,
      headers: {'Authorization': 'Bearer $token'},
      fromJson: (json) => PaginationModel<OutProvinceCarcassesBuyer>.fromJson(
        json,
        (json) =>
            OutProvinceCarcassesBuyer.fromJson(json as Map<String, dynamic>),
      ),
    );
    return res.data;
  }

  @override
  Future<void> createOutProvinceCarcassesBuyer({
    required String token,
    required OutProvinceCarcassesBuyer body,
  }) async {
    await _httpClient.post(
      '/out-province-carcasses-buyer/',
      data: body.toJson()..removeWhere((key, value) => value == null),
      headers: {'Authorization': 'Bearer $token'},
    );
  }

  @override
  Future<PaginationModel<StewardFreeSaleBar>?> getStewardFreeSaleBar({
    required String token,
    Map<String, dynamic>? queryParameters,
  }) async {
    var res = await _httpClient.get(
      '/steward_free_sale_bar/?',
      queryParameters: queryParameters,
      headers: {'Authorization': 'Bearer $token'},
      fromJson: (json) => PaginationModel<StewardFreeSaleBar>.fromJson(
        json,
        (json) => StewardFreeSaleBar.fromJson(json as Map<String, dynamic>),
      ),
    );
    return res.data;
  }

  @override
  Future<void> createOutProvinceStewardFreeBar({
    required String token,
    required StewardFreeSaleBarRequest body,
  }) async {
    await _httpClient.post(
      '/steward_free_sale_bar/',
      data: body.toJson()..removeWhere((key, value) => value == null),
      headers: {'Authorization': 'Bearer $token'},
    );
  }

  @override
  Future<void> updateOutProvinceStewardFreeBar({
    required String token,
    required StewardFreeSaleBarRequest body,
  }) async {
    await _httpClient.put(
      '/steward_free_sale_bar/0/',
      data: body.toJson()
        ..removeWhere((key, value) => value == null)
        ..addAll({
          'carcassWeight': body.weightOfCarcasses,
          'carcassCount': body.numberOfCarcasses,
        }),
      headers: {'Authorization': 'Bearer $token'},
    );
  }
}
