using LinqToDB;
using log4net;
using MasaBlazorApp3.DataAccess.Dao;
using MasaBlazorApp3.Pojo;
using MasaBlazorApp3.Pojo.Config;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MasaBlazorApp3.DataAccess.Impl
{
    public class DrugInfoDao : IDrugInfoDao
    {

        private AppDataConnection _connection;
        private readonly SettingConfig _setting;
        private readonly ILog logger = LogManager.GetLogger(typeof(DrugInfoDao));

        public DrugInfoDao(AppDataConnection connection, IOptions<SettingConfig> setting)
        {
            _connection = connection;
            _setting = setting.Value;
        }
        public async Task<List<DrugInfo>> GetAllDrugAndStock()
        {
            var query = _connection.DrugInfo.AsQueryable();

            List<DrugInfo> drugList = await query
                .LoadWith(di => di.Stocks.Where(cs => cs.Quantity > 0 && (cs.MachineId == _setting.machineId)))
                .InnerJoin(
                    _connection.ChannelStock.Where(cl => cl.MachineId == _setting.machineId && cl.DrawerType == 1).GroupBy(cl => cl.DrugId),
                    (di, cl) => di.DrugId == cl.Key,
                    (di, cl) => di
                )
                //.Where(cs => cs.Quantity > 0)
                .OrderBy((di) => di.DrugId)
                .ToListAsync();
            if(drugList!=null&&drugList.Count>0)
            {
                for (int i = 0; i < drugList.Count; i++)
                {
                    List<ChannelStock> channelStocks = _connection.ChannelStock.Where(cs => cs.MachineId.Equals(_setting.boxMachineId) && cs.DrugId == drugList[i].DrugId).OrderBy(cs=> new{ cs.DrawerNo, cs.ColNo}).ToList();
                    var  nomalBoxStockList= channelStocks.Where(cs => cs.DrawerNo <= 30).GroupBy(cs =>new { cs.ManuNo, cs.EffDate }).Select(g => new { manuNo=g.Key.ManuNo,effdate=g.Key.EffDate,Quantity=g.Sum(k=>k.Quantity)}).ToList();
                    foreach (var item in nomalBoxStockList)
                    {
                        ChannelStock nomalBox = new ChannelStock() { DrugId = drugList[i].DrugId,ManuNo=item.manuNo,Quantity=item.Quantity,EffDate=item.effdate,MachineId= "DM5" };
                        drugList[i].Stocks.Add(nomalBox);
                    }
                    drugList[i].Stocks.AddRange(channelStocks.Where(cs=>cs.DrawerNo>30));
                }
            }
            return drugList;
            //return await query
            //    .LoadWith(di => di.Stocks.Where(cs => cs.Quantity > 0 && (cs.MachineId == _setting.machineId)))
            //    .InnerJoin(
            //        _connection.ChannelStock.Where(cl => cl.MachineId == _setting.machineId && cl.DrawerType == 1).GroupBy(cl => cl.DrugId),
            //        (di, cl) => di.DrugId == cl.Key,
            //        (di, cl) => di
            //    )
            //    //.Where(cs => cs.Quantity > 0)
            //    .OrderBy((di) => di.DrugId)
            //    .ToListAsync();
        }

        public async Task<List<DrugInfo>> GetAllDrugAndStockByBox(BoxModel boxModel)
        {
            var query = _connection.DrugInfo.AsQueryable();


            return await query
                .LoadWith(di => di.Stocks.Where(cs => cs.Quantity > 0 && cs.MachineId == _setting.boxMachineId&&cs.DrawerNo==boxModel.BoxName&&cs.ColNo==boxModel.BoxNo))
                .InnerJoin(
                    _connection.ChannelStock.Where(cl => cl.MachineId == _setting.boxMachineId && cl.DrawerNo==boxModel.BoxName&&cl.ColNo==boxModel.BoxNo).GroupBy(cl => cl.DrugId),
                    (di, cl) => di.DrugId == cl.Key,
                    (di, cl) => di
                )
                //.Where(cs => cs.Quantity > 0)
                .OrderBy((di) => di.DrugId)
                .ToListAsync();
        }

        public async Task<PageData<DrugInfo>> GetAllDrug(string drugId, string drugName, int? take, int? skip)
        {
            var query = _connection.DrugInfo.AsQueryable();

            if (!String.IsNullOrEmpty(drugId))
            {
                query = query.Where(di => di.DrugId.Contains(drugId));
            }
            if (!String.IsNullOrEmpty(drugName))
            {
                query = query.Where(di => di.DrugName.Contains(drugName));
            }



            int pagedData = await query.CountAsync();
            query = query
                .LoadWith(di => di.Manus)
                .OrderBy((di) => di.DrugId)
                .Skip((int)skip)
                .Take((int)take);

            List<DrugInfo> list = await query
                .ToListAsync();

            return new PageData<DrugInfo>()
            {
                TotalDesserts = pagedData,
                Desserts = list
            };
        }

        public async Task<List<DrugInfo>> GetAllDrug()
        {
            var query = _connection.DrugInfo.AsQueryable();

            return await query
                .LoadWith(di => di.Manus)
                .OrderBy((di) => di.DrugId)
                .ToListAsync();
        }

        public async Task<DrugManuNo> GetDrugManuNo(string drugId, string manuNo)
        {
            var query = _connection.DrugManuNo.AsQueryable();

            return await query.Where(m => m.DrugId.Equals(drugId))
                .Where(m => m.ManuNo.Equals(manuNo))
                .FirstAsync();
        }

        public int AddDrugInfo(DrugInfo drugInfo)
        {
            return _connection.InsertWithInt32Identity(drugInfo);
        }

        public async Task<bool> DeleteDrugInfo(string drugId)
        {
            try
            {
                logger.Error($"删除药品{drugId}");
                return _connection.DrugInfo.Where(di => di.DrugId == drugId).Delete() > 0;
            }
            catch (Exception ex)
            {
                logger.Error("删除药品失败，错误：" + ex.Message);
                return false;
            }
        }

        public async Task<bool> UpdateDrugInfo(DrugInfo drugInfo)
        {
            try
            {
                var statement = _connection.DrugInfo
                    .Where(di => di.DrugId == drugInfo.DrugId)
                    .Set(di => di.DrugName, drugInfo.DrugName)
                    .Set(di => di.DrugSpec, drugInfo.DrugSpec)
                    .Set(di=>di.PackH,drugInfo.PackH)
                    .Set(di => di.Manufactory, drugInfo.Manufactory);
                return statement.Update() > 0;
            }
            catch (Exception ex)
            {
                logger.Error($"修改药品{drugInfo.DrugId}失败，错误：" + ex.Message);
                return false;
            }
        }
    }
}
