import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/generic_attachment_model.dart';
import 'package:test_sa/models/module_permissions_model.dart';
import 'package:test_sa/models/new_models/building.dart';
import 'package:test_sa/models/new_models/floor.dart';
import 'package:test_sa/models/new_models/room_model.dart';
import 'package:test_sa/modules/asset_delivery_module/models/asset_delivery_data_model.dart';
import 'package:test_sa/modules/asset_delivery_module/models/cost_center_model.dart';
import 'package:test_sa/modules/asset_delivery_module/models/cost_center_serial_no_form_model.dart';
import 'package:test_sa/modules/asset_delivery_module/models/delivery_inspection_form_model.dart';
import 'package:test_sa/modules/asset_delivery_module/models/delivery_line_model.dart';
import 'package:test_sa/modules/asset_delivery_module/models/end_user_asset_details_model.dart';
import 'package:test_sa/modules/asset_delivery_module/models/history_model.dart';
import 'package:test_sa/modules/asset_delivery_module/models/technical_inspection_asset_model.dart';
import 'package:test_sa/modules/asset_delivery_module/models/technical_inspection_form_model.dart';
import '../../../models/new_models/department.dart';
import '../../../models/new_models/site.dart';
import '../models/oracle_user_model.dart';

class AssetDeliveryProvider extends ChangeNotifier {
  final pageItemNumber = 10;
  final searchPageItemNumber = 10;
  int pageNo = 1;
  AssetDeliveryDataModel? assetDeliveryDataModel;
  List<AssetDeliveryTableModel> assetDeliveryTableList = [];
  List<DeliveryLineModel> deliveryLinesList = [];
  ModulesPermissionsModel? modelPermission;
  TechnicalInspectionAssetModel parentFormModel = TechnicalInspectionAssetModel();
  TechnicalInspectionAssetModel childFormModel = TechnicalInspectionAssetModel();

  void reset() {
    pageNo = 1;
    stateCode = null;
  }

  int? stateCode;
  bool isDetailLoading = false;
  bool nextPage = false;
  bool isLoading = false;
  bool isSiteLoading = false;
  bool isDeliveryTableListLoading = false;
  bool isDeliveryLineListLoading = false;
  bool isChildAssetDataLoading = false;

  void setParentModel(TechnicalInspectionAssetModel m) {
    parentFormModel = m;
    notifyListeners();
  }

  void setChildModel(TechnicalInspectionAssetModel m) {
    childFormModel = m;
    notifyListeners();
  }

  Future<AssetDeliveryDataModel?> getAssetDeliveryDetailById({int? requestId}) async {
    try {
      assetDeliveryDataModel = AssetDeliveryDataModel();
      isLoading = true;
      notifyListeners();
      final response = await ApiManager.instance.get(URLs.getAssetDeliveryDetailsById + "?Id=$requestId");
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        assetDeliveryDataModel = AssetDeliveryDataModel.fromJson(json.decode(response.body)["data"]);
      } else {
        assetDeliveryDataModel = null;
      }
      isLoading = false;
      notifyListeners();
      return assetDeliveryDataModel;
    } catch (e) {
      log("getdelivery details [error] : $e");
      isLoading = false;
      assetDeliveryDataModel = null;
      notifyListeners();
      return assetDeliveryDataModel;
    }
  }

  Future<void> getAssetDeliveryTableListById({int? requestId}) async {
    try {
      assetDeliveryTableList.clear();
      isDeliveryTableListLoading = true;
      notifyListeners();

      final response = await ApiManager.instance.get(
        "${URLs.getAssetDeliveryTableListById}?assetDeliveryExternalMasterId=$requestId",
      );
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        final jsonData = json.decode(response.body)["data"];
        if (jsonData is List) {
          assetDeliveryTableList = jsonData.map((e) => AssetDeliveryTableModel.fromJson(e)).toList();
        } else {
          assetDeliveryTableList = [];
        }
      } else {
        assetDeliveryTableList = [];
      }

      isDeliveryTableListLoading = false;
      notifyListeners();
    } catch (e) {
      log("get Delivery Table details [error] : $e");
      isDeliveryTableListLoading = false;
      assetDeliveryTableList = [];
      notifyListeners();
    }
  }

  Future<void> getDeliveryLinesListById({int? itemId}) async {
    try {
      deliveryLinesList.clear();
      isDeliveryLineListLoading = true;
      notifyListeners();
      final response = await ApiManager.instance.get(
        "${URLs.getLineFromExternalPo}?assetDeliveryExternalDeliveryId=$itemId",
      );
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        final jsonData = json.decode(response.body)["data"];
        if (jsonData is List) {
          deliveryLinesList = jsonData.map((e) => DeliveryLineModel.fromJson(e)).toList();
        } else {
          deliveryLinesList = [];
        }
      } else {
        deliveryLinesList = [];
      }
      isDeliveryLineListLoading = false;
      notifyListeners();
    } catch (e) {
      log("get Delivery Lines List [error] : $e");
      isDeliveryLineListLoading = false;
      deliveryLinesList = [];
      notifyListeners();
    }
  }

  Future<List<DeliveryLineModel>> getTechnicalInspectionLinesListById({int? itemId}) async {
    List<DeliveryLineModel> linesList = [];
    try {
      isLoading = true;
      notifyListeners();
      final response = await ApiManager.instance.get(
        "${URLs.getLineFromTechnicalInspection}?assetDeliveryExternalDeliveryId=$itemId",
      );
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        final jsonData = json.decode(response.body)["data"];
        if (jsonData is List) {
          linesList = jsonData.map((e) => DeliveryLineModel.fromJson(e)).toList();
        } else {
          assetDeliveryTableList = [];
        }
      } else {
        linesList = [];
      }
      isLoading = false;
      notifyListeners();
      return linesList;
    } catch (e) {
      log("get Delivery Lines List [error] : $e");
      isLoading = false;
      linesList = [];
      notifyListeners();
      return linesList;
    }
  }

  Future<CostCenterSerialNoFormModel> getAssetDeliveryCostCenterListForLines({
    int? lineId,
    int? tableItemId,
  }) async {
    CostCenterSerialNoFormModel costCenterSerialNoFormModel = CostCenterSerialNoFormModel();
    try {
      isLoading = true;
      notifyListeners();

      final response = await ApiManager.instance.get(
        "${URLs.getCostCenterAndSerialNoToLineDeliveryInspection}?AssetDeliveryExternalDetailId=$lineId&AssetDeliveryExternalDeliveryId=$tableItemId",
      );

      stateCode = response.statusCode;

      if (response.statusCode >= 200 && response.statusCode < 300) {
        final jsonData = json.decode(response.body)["data"];
        costCenterSerialNoFormModel = CostCenterSerialNoFormModel.fromJson(jsonData);
      } else {
        costCenterSerialNoFormModel.costCenters = [];
        costCenterSerialNoFormModel.serialNos = [];
      }
    } catch (e) {
      log("get Delivery Lines List [error] : $e");
      costCenterSerialNoFormModel.costCenters = [];
      costCenterSerialNoFormModel.serialNos = [];
    } finally {
      isLoading = false;
      notifyListeners();
    }

    return costCenterSerialNoFormModel;
  }

  Future<bool> addNewDelivery({
    int? requestId,
  }) async {
    isDeliveryTableListLoading = true;
    Map<String, dynamic> payload = {
      'assetDeliveryExternalMasterId': requestId,
    };
    try {
      final response = await ApiManager.instance.post(URLs.addNewDelivery, body: payload);
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isDeliveryTableListLoading = false;
        notifyListeners();
        return true;
      } else {
        isDeliveryTableListLoading = false;
        notifyListeners();
        return false;
      }
    } catch (error) {
      isDeliveryTableListLoading = false;
      notifyListeners();
      return false;
    }
  }

  Future<bool> saveTechnicalInspection({
    required TechnicalInspectionFormModel model,
  }) async {
    isLoading = true;
    try {
      final response = await ApiManager.instance.post(URLs.saveTechnicalInspection, body: model.toJson());
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isLoading = false;
        notifyListeners();
        return true;
      } else {
        isLoading = false;
        notifyListeners();
        return false;
      }
    } catch (error) {
      isLoading = false;
      notifyListeners();
      return false;
    }
  }

  Future<bool> saveCostCenterToLineDeliveryInspection({
    int? tableItemId,
    int? lineId,
    List<CostCenterModel>? list,
    List<SerialNoModel>? serialNoList,
  }) async {
    isLoading = true;
    Map<String, dynamic> payload = {
      "assetDeliveryExternalDeliveryId": tableItemId,
      "assetDeliveryExternalDetailId": lineId,
      "costCenters": list?.map((x) => x.toJson()).toList(),
      if (serialNoList != null && serialNoList.isNotEmpty) "serialNos": serialNoList.map((x) => x.toJson()).toList(),
    };
    try {
      final response = await ApiManager.instance.post(URLs.saveCostCenterAndSerialNoToLineDeliveryInspection, body: payload);
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isLoading = false;
        notifyListeners();
        return true;
      } else {
        isLoading = false;
        notifyListeners();
        return false;
      }
    } catch (error) {
      isLoading = false;
      notifyListeners();
      return false;
    }
  }

  Future<bool> changeDeliveryStatusToCancel({int? itemId}) async {
    isLoading = true;
    try {
      final response = await ApiManager.instance.get(
        "${URLs.changeDeliveryStatusToCancel}?assetDeliveryExternalDeliveryId=$itemId",
      );
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isLoading = false;
        notifyListeners();
        return true;
      } else {
        isLoading = false;
        notifyListeners();
        return false;
      }
    } catch (error) {
      isLoading = false;
      notifyListeners();
      return false;
    }
  }

  Future<bool> changeDeliveryStatus({
    int? itemId,
    Map<String, dynamic>? requestPayload,
  }) async {
    isLoading = true;
    Map<String, dynamic> payload = {
      'assetDeliveryExternalDeliveryId': itemId,
    };
    try {
      final response = await ApiManager.instance.post(URLs.changeDeliveryStatus, body: requestPayload ?? payload);
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isLoading = false;
        notifyListeners();
        return true;
      } else {
        isLoading = false;
        notifyListeners();
        return false;
      }
    } catch (error) {
      isLoading = false;
      notifyListeners();
      return false;
    }
  }

  Future<bool> saveMasterInfoDeliveryInspection({
    Map<String, dynamic>? requestPayload,
  }) async {
    isLoading = true;
    try {
      final response = await ApiManager.instance.post(URLs.saveMasterInfoDeliveryInspection, body: requestPayload??{});
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isLoading = false;
        notifyListeners();
        return true;
      } else {
        isLoading = false;
        notifyListeners();
        return false;
      }
    } catch (error) {
      isLoading = false;
      notifyListeners();
      return false;
    }
  }

  Future<bool> sendEmailToAddSignature({
    Map<String, dynamic>? requestPayload,
  }) async {
    isLoading = true;
    try {
      final response = await ApiManager.instance.post(URLs.sendEmailToAddSignature, body: requestPayload??{});
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isLoading = false;
        notifyListeners();
        return true;
      } else {
        isLoading = false;
        notifyListeners();
        return false;
      }
    } catch (error) {
      isLoading = false;
      notifyListeners();
      return false;
    }
  }

  Future<DeliveryInspectionFormModel> getAssetDeliveryInspectionData({int? itemId}) async {
    isLoading = true;
    DeliveryInspectionFormModel deliveryInspectionFormModel = DeliveryInspectionFormModel();
    try {
      final response = await ApiManager.instance.get(
        "${URLs.getAssetDeliveryInspectionData}?assetDeliveryExternalDeliveryId=$itemId",
      );
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        deliveryInspectionFormModel = DeliveryInspectionFormModel.fromJson(json.decode(response.body)["data"]);
      }
      isLoading = false;
      notifyListeners();
      return deliveryInspectionFormModel;
    } catch (e) {
      log("getAssetDeliveryInspectionData details [error] : $e");
      isLoading = false;
      notifyListeners();
      return deliveryInspectionFormModel;
    }
  }

  Future<TechnicalInspectionFormModel> getTechnicalInspectionData({int? lineId, int? tableId}) async {
    isLoading = true;
    TechnicalInspectionFormModel technicalInspectionFormModel = TechnicalInspectionFormModel();
    try {
      final response = await ApiManager.instance.get(
        "${URLs.getTechnicalInspectionByDetailId}?assetDeliveryExternalDetailId=$lineId&assetDeliveryExternalDeliveryId=$tableId",
      );
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        technicalInspectionFormModel = TechnicalInspectionFormModel.fromJson(json.decode(response.body)["data"]);
      }
      isLoading = false;
      notifyListeners();
      return technicalInspectionFormModel;
    } catch (e) {
      log("getTechnicalInspectionByDetailId details [error] : $e");
      isLoading = false;
      notifyListeners();
      return technicalInspectionFormModel;
    }
  }

  Future<DeliveryInspectionFormModel> getDeliveryHistories({int? itemId}) async {
    isLoading = true;
    DeliveryInspectionFormModel deliveryInspectionFormModel = DeliveryInspectionFormModel();
    try {
      final response = await ApiManager.instance.get(
        "${URLs.getAssetDeliveryInspectionData}?assetDeliveryExternalDeliveryId=$itemId",
      );
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        deliveryInspectionFormModel = DeliveryInspectionFormModel.fromJson(json.decode(response.body)["data"]);
      }
      isLoading = false;
      notifyListeners();
      return deliveryInspectionFormModel;
    } catch (e) {
      log("getAssetDeliveryInspectionData details [error] : $e");
      isLoading = false;
      notifyListeners();
      return deliveryInspectionFormModel;
    }
  }

  Future<List<OracleUserModel>> getOracleUserAutoCompleteDetails({
    String? query,
  }) async {
    try {
      isLoading = true;
      final response = await ApiManager.instance.post(URLs.getOracleUserList, body: {'employeeName': query});
      List<OracleUserModel> list = [];
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isLoading = false;
        notifyListeners();
        final data = json.decode(response.body)["data"];
        list = (data as List).map((e) => OracleUserModel.fromJson(e)).toList();
      }
      isLoading = false;
      notifyListeners();
      return list;
    } catch (error) {
      log('error $error');
      isLoading = false;
      notifyListeners();
      return [];
    }
  }

  Future<List<GenericAttachmentModel>> getAttachments({
    num? tableItemId,
    num? attachmentType,
  }) async {
    try {
      isLoading = true;
      final response = await ApiManager.instance.get("${URLs.getAttachments}?attachmentDocTypeValue=$attachmentType&assetDeliveryExternalDeliveryId=$tableItemId");
      List<GenericAttachmentModel> list = [];
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isLoading = false;
        notifyListeners();
        final data = json.decode(response.body)["data"];
        list = (data as List).map((e) => GenericAttachmentModel.fromJson(e)).toList();
      }
      isLoading = false;
      notifyListeners();
      return list;
    } catch (error) {
      log('error $error');
      isLoading = false;
      notifyListeners();
      return [];
    }
  }

  Future<List<TechnicalInspectionAssetModel>> getParentAssetList({int? costCenterId, int? tableItemId, int? lineId}) async {
    List<TechnicalInspectionAssetModel> parentAssetList = [];
    try {
      isLoading = true;
      notifyListeners();
      final response = await ApiManager.instance.get(
        "${URLs.getTechnicalInspectionParentData}?assetDeliveryExternalDeliveryId=$tableItemId&assetDeliveryExternalDetailId=$lineId&costCenterId=$costCenterId",
      );
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        final jsonData = json.decode(response.body)["data"];
        if (jsonData is List) {
          parentAssetList = jsonData.map((e) => TechnicalInspectionAssetModel.fromJson(e)).toList();
        }
      } else {
        parentAssetList = [];
      }
      isLoading = false;
      notifyListeners();
      return parentAssetList;
    } catch (e) {
      log("get parent List [error] : $e");
      isLoading = false;
      parentAssetList = [];
      notifyListeners();
      return parentAssetList;
    }
  }

  Future<TechnicalInspectionAssetModel> getSiteData({
    required num? siteId,
    required TechnicalInspectionAssetModel model,
  }) async {
    isSiteLoading = true;
    notifyListeners();

    try {
      final response = await ApiManager.instance.get(
        "${URLs.getSiteAutoCompleteWithoutConditionSites}?id=$siteId",
      );

      stateCode = response.statusCode;

      if (response.statusCode >= 200 && response.statusCode < 300) {
        final List? siteData = json.decode(response.body)["data"];

        if (siteData != null && siteData.isNotEmpty) {
          model.site = Site.fromJson(siteData.first);
        }

        model.building = model.site?.buildings?.firstWhere(
          (e) => e.value == model.building?.value,
          orElse: () => Building(),
        );

        model.floor = model.building?.floors?.firstWhere(
          (e) => e.value == model.floor?.value,
          orElse: () => Floor(),
        );

        model.department = model.floor?.departments?.firstWhere(
          (e) => e.departmentName == model.department?.departmentName,
          orElse: () => Department(),
        );

        model.room = model.department?.rooms?.firstWhere(
          (e) => e.value == model.room?.value,
          orElse: () => Rooms(),
        );
      }

      isSiteLoading = false;
      notifyListeners();
      return model;
    } catch (e) {
      isSiteLoading = false;
      stateCode = -1;
      notifyListeners();
      return model;
    }
  }

  Future<TechnicalInspectionAssetModel?> getAssetDetails({required num? assetId}) async {
    isLoading = true;
    notifyListeners();
    try {
      Response response = await ApiManager.instance.get(URLs.getAssetDetailsByAssetId + "?AssetDeliveryInternalDetailAssetId=$assetId");
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        final data = json.decode(response.body)["data"];
        TechnicalInspectionAssetModel assetModel = TechnicalInspectionAssetModel.fromJson(data);
        isLoading = false;
        notifyListeners();
        return assetModel;
      } else {
        return null;
      }
    } catch (error) {
      isLoading = false;
      stateCode = -1;
      notifyListeners();
      return null;
    }
  }

  Future<bool> saveTechnicalInspectionAssetData({
    required TechnicalInspectionAssetModel model,
  }) async {
    isLoading = true;
    try {
      final response = await ApiManager.instance.post(URLs.saveTechnicalInspectionAsset, body: model.toJson());
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isLoading = false;
        notifyListeners();
        return true;
      } else {
        isLoading = false;
        notifyListeners();
        return false;
      }
    } catch (error) {
      isLoading = false;
      notifyListeners();
      return false;
    }
  }

  Future<bool> saveAttachment({
    required Map<String, dynamic> payload,
  }) async {
    isLoading = true;
    try {
      final response = await ApiManager.instance.post(URLs.saveAttachments, body: payload);
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isLoading = false;
        notifyListeners();
        return true;
      } else {
        isLoading = false;
        notifyListeners();
        return false;
      }
    } catch (error) {
      isLoading = false;
      notifyListeners();
      return false;
    }
  }

  Future<List<AssetDeliveryHistoryModel>> getHistory({
    num? tableItemId,
  }) async {
    try {
      isLoading = true;
      notifyListeners();
      final response = await ApiManager.instance.get("${URLs.getDeliveryHistories}?assetDeliveryExternalDeliveryId=$tableItemId");
      List<AssetDeliveryHistoryModel> list = [];
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isLoading = false;
        notifyListeners();
        final data = json.decode(response.body)["data"];
        list = (data as List).map((e) => AssetDeliveryHistoryModel.fromJson(e)).toList();
      }
      isLoading = false;
      notifyListeners();
      return list;
    } catch (error) {
      log('error $error');
      isLoading = false;
      notifyListeners();
      return [];
    }
  }

  //End user

  Future<List<CostCenterModel>> getEndUserCostCenterList({int? tableItemId}) async {
    List<CostCenterModel> costCenterList = [];
    try {
      isLoading = true;
      notifyListeners();
      final response = await ApiManager.instance.get(
        "${URLs.getEndUserAcceptanceCostCenter}?assetDeliveryExternalDeliveryId=$tableItemId",
      );
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        final jsonData = json.decode(response.body)["data"];
        if (jsonData is List) {
          costCenterList = jsonData.map((e) => CostCenterModel.fromJson(e)).toList();
        }
      } else {
        costCenterList = [];
      }
      isLoading = false;
      notifyListeners();
      return costCenterList;
    } catch (e) {
      log("get costCenter for End user [error] : $e");
      isLoading = false;
      costCenterList = [];
      notifyListeners();
      return costCenterList;
    }
  }

  Future<List<EndUserAssetDetailsModel>> getEndUserAssetList({int? tableItemId, String? costCenterName}) async {
    List<EndUserAssetDetailsModel> assetList = [];
    try {
      isLoading = true;
      notifyListeners();
      final response = await ApiManager.instance.get(
        "${URLs.getCostCenterAssetList}?assetDeliveryExternalDeliveryId=$tableItemId&costCenterName=$costCenterName",
      );
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        final jsonData = json.decode(response.body)["data"];
        if (jsonData is List) {
          assetList = jsonData.map((e) => EndUserAssetDetailsModel.fromJson(e)).toList();
        }
      } else {
        assetList = [];
      }
      isLoading = false;
      notifyListeners();
      return assetList;
    } catch (e) {
      log("get End User AssetList [error] : $e");
      isLoading = false;
      assetList = [];
      notifyListeners();
      return assetList;
    }
  }

  Future<bool> saveEndUserFormData({
    required CostCenterModel model,
  }) async {
    isLoading = true;
    try {
      final response = await ApiManager.instance.post(URLs.saveEndUserFormData, body: model.toEndUserAcceptanceFormJson());
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isLoading = false;
        notifyListeners();
        return true;
      } else {
        isLoading = false;
        notifyListeners();
        return false;
      }
    } catch (error) {
      isLoading = false;
      notifyListeners();
      return false;
    }
  }

  Future<bool> saveEndUserAssetDataData({
    required EndUserAssetDetailsModel model,
  }) async {
    isLoading = true;
    try {
      final response = await ApiManager.instance.post(URLs.saveEndUserAssetData, body: model.toJson());
      stateCode = response.statusCode;
      if (response.statusCode >= 200 && response.statusCode < 300) {
        isLoading = false;
        notifyListeners();
        return true;
      } else {
        isLoading = false;
        notifyListeners();
        return false;
      }
    } catch (error) {
      isLoading = false;
      notifyListeners();
      return false;
    }
  }
}
