using Back.Common;
using Back.Data.Contracts;
using Back.Data.Models;
using Microsoft.EntityFrameworkCore;
using Shared.DTOs;
using Shared.DTOs.Serch;

namespace Back.Services
{
    public class ServOrders 
    {
        private readonly IAsyncRepository<PermissionPeriod> _repoPermissionPeriod;
        private readonly IAsyncRepository<Order> _repoOrder;
        private readonly IAsyncRepository<OrderItem> _repoOrderItem;


        public ServOrders(IAsyncRepository<Order> repoOrder, IAsyncRepository<OrderItem> repoOrderItem
                            , IAsyncRepository<PermissionPeriod> repoPermissionPeriod)
        {
            _repoOrder = repoOrder;
            _repoOrderItem = repoOrderItem;
            _repoPermissionPeriod = repoPermissionPeriod;
        }
        public async Task<PagingDto<OrderDto>> GetOrdersByCompanyID(int CompanyID, ItemSerachOrder itemSerach)
        {
            var request = _repoOrder.Get(w => w.CompanyID == CompanyID);

            if (itemSerach.Status.HasValue)
                request = request.Where(w => w.Status == itemSerach.Status);

            if (itemSerach.ID.HasValue)
                request = request.Where(w => w.ID == itemSerach.ID);

            request = request.Include(inc => inc.OrderItems);
            return await request
                  .Select(w => new OrderDto
                  {
                      ApprovalDate = w.ApprovalDate.ShamciToFormatShamci(),
                      DateCreate = w.DateCreate.ShamciToFormatShamci(),
                      ID = w.ID,
                      PreDiscount = w.PreDiscount,
                      Status = w.Status,
                      TDiscount = w.TDiscount,
                      TPrice = w.TPrice,
                      TTax = w.TTax,
                      lstDiscount = w.lstDiscount,
                  }).Paging(itemSerach.PageIndex,itemSerach.PageSize);
        }
        public async Task<List<OrderItemDto>> GetOrderItems(int OrderID,int CompanyID)
        {
      return await _repoOrderItem.Get(w => w.OrderID == OrderID && w.Order.CompanyID == CompanyID)
                .Include(inc=>inc.Permission)
                .Include(inc=>inc.Promotion)
                .Select(s=>new OrderItemDto
                {
                    OrderID = OrderID,
                    APrice = s.APrice,
                    CreditAmount = s.CreditAmount,
                    Discount=s.Discount,
                    ID = s.ID,
                    Tax = s.Tax,
                    IDForType =  s.PermissionID.Value ,
                    Title =  s.Permission.Title ,
                }).ToListAsync();
        }
        public async Task<Order> GetOrder(int OrderID, int CompanyID)
        {
            return await _repoOrder.Get(w => w.ID == OrderID && w.CompanyID == CompanyID)
                .Include(inc=>inc.OrderItems)
                .FirstOrDefaultAsync();
        }
        public async Task<bool> UpdateOrder(Order order)
        {
            return await _repoOrder.UpdateAsync(order);
        }
        public async Task<Order> AddOrder(Order order)
        {
            try
            {
                return await _repoOrder.AddAsync(order);
 
            }
            catch (Exception ex)
            {
                return null;

            }
        }
        public async Task<bool> SubmitOrder(Order ordermodel,int CompanyID)
        {
            try
            {
                foreach (OrderItem order in ordermodel.OrderItems.ToList())
                {
                    var pp = await _repoPermissionPeriod.Get(w => w.PermissionID == order.PermissionID && w.CompanyID == CompanyID && w.CalculationTypeID == 1).FirstOrDefaultAsync();
                    if (pp != null)
                    {
                        pp.RemainingAmount += order.CreditAmount;
                        pp.TotalAmount += order.CreditAmount;
                        await _repoPermissionPeriod.UpdateAsync(pp);
                    }
                }
                ordermodel.Status = StatusOrder.Paid;
               return await _repoOrder.UpdateAsync(ordermodel);
            }
            catch (Exception)
            {
                return false;
                throw;
            }
           
           
        }
    }
}
