using FruitBank.Common.Dtos;
using FruitBank.Common.Entities;
using FruitBank.Common.Models;
using FruitBank.Common.SignalRs;
using Mango.Nop.Core.Dtos;
using Mango.Nop.Core.Entities;
using Mango.Nop.Core.Models;
using Nop.Core.Domain.Customers;

namespace FruitBank.Common.Interfaces;

public interface IFruitBankDataControllerCommon
{
    public Task<List<MeasuringModel>?> GetMeasuringModels();

    #region Partner
    public Task<List<Partner>?> GetPartners();
    public Task<Partner?> GetPartnerById(int id);
    public Task<Partner?> AddPartner(Partner partner);
    public Task<Partner?> UpdatePartner(Partner partner);
    #endregion Partner

    #region PartnerDepot
    public Task<List<PartnerDepot>?> GetPartnerDepots();
    public Task<PartnerDepot?> GetPartnerDepotById(int id);
    public Task<List<PartnerDepot>?> GetPartnerDepotsByPartnerId(int partnerId);
    public Task<PartnerDepot?> AddPartnerDepot(PartnerDepot partnerDepot);
    public Task<PartnerDepot?> UpdatePartnerDepot(PartnerDepot partnerDepot);
    #endregion PartnerDepot

    #region EkaerHistory
    public Task<List<EkaerHistory>?> GetEkaerHistories(EkaerHistoryFilter filter);
    public Task<EkaerHistory?> GetEkaerHistoryById(int id);
    public Task<List<EkaerHistory>?> GetEkaerHistoriesByForeignKey(int foreignKey);
    public Task<EkaerHistory?> AddEkaerHistory(EkaerHistory ekaerHistory);
    public Task<EkaerHistory?> UpdateEkaerHistory(EkaerHistory ekaerHistory);
    public Task<EkaerHistory?> GenerateEkaerXmlDocument(int ekaerHistoryId);
    public Task<EkaerHistory?> CreateEkaerHistory(int foreignKey, bool isOutgoing);
    public Task<EkaerCreateResult?> CreateMissingEkaerHistories(DateTime fromDate);
    public Task<int> GetEkaerHistoryCount(EkaerHistoryFilter filter);
    #endregion EkaerHistory

    #region CargoPartner
    public Task<List<CargoPartner>?> GetCargoPartners();
    public Task<CargoPartner?> GetCargoPartnerById(int id);
    public Task<CargoPartner?> AddCargoPartner(CargoPartner cargoPartner);
    public Task<CargoPartner?> UpdateCargoPartner(CargoPartner cargoPartner);
    #endregion CargoPartner
    
    #region CargoTruck
    public Task<List<CargoTruck>?> GetCargoTrucks();
    public Task<CargoTruck?> GetCargoTruckById(int id);
    public Task<List<CargoTruck>?> GetCargoTrucksByCargoPartnerId(int cargoPartnerId);
    public Task<CargoTruck?> AddCargoTruck(CargoTruck cargoTruck);
    public Task<CargoTruck?> UpdateCargoTruck(CargoTruck cargoTruck);
    #endregion CargoTruck

    #region Shipping
    public Task<List<Shipping>?> GetShippings();
    Task<List<Shipping>?> GetNotMeasuredShippings();
    public Task<Shipping?> GetShippingById(int id);
    public Task<Shipping?> AddShipping(Shipping shipping);
    public Task<Shipping?> UpdateShipping(Shipping shipping);
    #endregion Shipping

    #region ShippingItem
    public Task<List<ShippingItem>?> GetShippingItems();
    public Task<List<ShippingItem>?> GetShippingItemsByPartnerId(int partnerId);
    public Task<List<ShippingItem>?> GetShippingItemsByShippingId(int shippingId);
    public Task<List<ShippingItem>?> GetShippingItemsByDocumentId(int shippingDocumentId);
    public Task<ShippingItem?> GetShippingItemById(int id);
    public Task<ShippingItem?> AddShippingItem(ShippingItem shippingItem);
    public Task<ShippingItem?> UpdateShippingItem(ShippingItem shippingItem);
    public Task<ShippingItem?> UpdateMeasuredShippingItem(ShippingItem shippingItem);
    #endregion ShippingItem

    #region ShippingItemPallet

    public Task<List<ShippingItemPallet>?> GetShippingItemPallets();
    public Task<ShippingItemPallet?> AddShippingItemPallet(ShippingItemPallet shippingItemPallet);
    public Task<ShippingItemPallet?> UpdateShippingItemPallet(ShippingItemPallet shippingItemPallet);
    public Task<ShippingItemPallet?> AddOrUpdateMeasuredShippingItemPallet(ShippingItemPallet shippingItemPallet);
    public Task<ShippingItem?> AddOrUpdateMeasuredShippingItemPallets(List<ShippingItemPallet> shippingItemPallets);
    #endregion ShippingItemPallet

    #region ShippingDocument
    public Task<List<ShippingDocument>?> GetShippingDocuments();
    public Task<ShippingDocument?> GetShippingDocumentById(int id);
    public Task<List<ShippingDocument>?> GetShippingDocumentsByShippingId(int shippingId);
    public Task<List<ShippingDocument>?> GetShippingDocumentsByProductId(int productId);
    public Task<List<ShippingDocument>?> GetShippingDocumentsByPartnerId(int partnerId);
    public Task<ShippingDocument?> AddShippingDocument(ShippingDocument shippingDocument);
    public Task<ShippingDocument?> UpdateShippingDocument(ShippingDocument shippingDocument);
    #endregion ShippingDocument

    #region Customer
    public Task<List<CustomerDto>?> GetMeasuringUsers();
    public Task<List<CustomerRole>?> GetCustomerRolesByCustomerId(int customerId);
    #endregion Customer

    #region Product
    public Task<List<ProductDto>?> GetProductDtos();
    //public Task<List<MeasuringProductDto>?> GetAllMeasuringProductDtos();
    public Task<ProductDto?> GetProductDtoById(int productId);

    public Task<List<StockQuantityHistoryDto>?> GetStockQuantityHistoryDtos();
    public Task<List<StockQuantityHistoryDto>?> GetStockQuantityHistoryDtosByProductId(int productId);

    #endregion Product

    Task<MgLoginModelResponse?> LoginMeasuringUser(MgLoginModelRequest loginModelRequest);
    Task<List<Partner>?> ProcessAndSaveFullShippingJson(string fullShippingJson, int customerId);

    public Task<List<GenericAttributeDto>?> GetGenericAttributeDtosByEntityIdAndKeyGroup(int productId, string keyGroup, int storeId);

    public Task<GenericAttributeDto?> AddGenericAttributeDto(GenericAttributeDto genericAttributeDto);

    public Task<GenericAttributeDto?> UpdateGenericAttributeDto(GenericAttributeDto genericAttributeDto);

    /// <summary>
    /// Returns the stored grid-layout JSON for the composite layout key, or null if none saved.
    /// </summary>
    public Task<string?> GetGridLayout(string key, int userId);

    /// <summary>
    /// Saves (upserts) the grid-layout JSON under the composite layout key for the given user.
    /// </summary>
    public Task<bool> SaveGridLayout(string key, string layoutJson, int userId);

    /// <summary>
    /// Deletes the stored grid layout for the composite layout key. Returns false if the user does not exist.
    /// </summary>
    public Task<bool> DeleteGridLayout(string key, int userId);
}