using Google.Protobuf.WellKnownTypes;
using LinqToDB;
using log4net;
using MasaBlazorApp3.DataAccess.Dao;
using MasaBlazorApp3.Pojo;
using MasaBlazorApp3.Pojo.Config;
using MasaBlazorApp3.Util;
using Microsoft.Extensions.Options;
using System.Data;
using System.Xml.Linq;

namespace MasaBlazorApp3.DataAccess.Impl
{
    public class UserDao : IUserDao
    {

        //private MyContext Context;

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

        //public UserDao(MyContext context)
        //{
        //    Context = context;
        //}
        public UserDao(AppDataConnection connection, IOptions<SettingConfig> setting)
        {
            _connection = connection;
            _setting = setting.Value;
        }

        public async Task<PageData<User>> GetAllByNickname(string nickname, int? take, int? skip)
        {
            var query = _connection.User.AsQueryable();

            if (!String.IsNullOrEmpty(nickname))
            {
                query = query.Where(r => r.NickName.IndexOf(nickname) > -1);
            }
            query = query.Where(u => u.MachineId == _setting.machineId);

            List<User> list = await query
                .LoadWith(u => u.role)
                .OrderBy(u => u.Id)
                .Skip((int)skip)
                .Take((int)take)
                .ToListAsync();
            int pagedData = await query.CountAsync();
            return new PageData<User>()
            {

                TotalDesserts = pagedData,
                Desserts = list
            };
        }

        public User GetById(int id)
        {
            return _connection.User.LoadWith(u => u.role).FirstOrDefault(u => u.Id == id);
        }

        public User GetByUsername(string username)
        {

            return _connection.User.LoadWith(u => (u.role)).FirstOrDefault(u => u.Username == username && u.MachineId == _setting.machineId);
        }

        public int InsertUser(User user)
        {
            user.MachineId = _setting.machineId;
            user.Password = MD5.GetMD5Hash("123456").ToLower();
            return _connection.InsertWithInt32Identity(user);
        }

        public bool UpdateUser(User user)
        {
            var statement = _connection.User
                .Where(u => u.Id == user.Id)
                .Set(u => u.NickName, user.NickName)
                .Set(u => u.Username, user.Username)
                .Set(u => u.RoleId, user.RoleId);
            //if(!String.IsNullOrEmpty(user.Password))
            //{
            //    statement.Set(u => user.Password, MD5.GetMD5Hash(user.Password).ToLower());
            //}
            return statement.Update() > 0;
        }

        public bool DeleteeUser(int id)
        {
            return _connection.User.Where(u => u.Id == id).Delete() > 0;
        }
        //重置用户密码
        public bool ResetPassword(int id)
        {
            var statement = _connection.User.Where(u => u.Id == id).Set(u => u.Password, MD5.GetMD5Hash("123456").ToLower());
            return statement.Update() > 0;
        }

        public async Task<bool> UpdateSign(int id, string sign)
        {
            var statement = _connection.User
                .Where(u => u.Id == id)
                .Set(u => u.Sign, Convert.FromBase64String(sign));
            //if(!String.IsNullOrEmpty(user.Password))
            //{
            //    statement.Set(u => user.Password, MD5.GetMD5Hash(user.Password).ToLower());
            //}
            return (await statement.UpdateAsync()) > 0;
        }
        //修改密码
        public bool UpdateUserPassword(User user)
        {
            var statement = _connection.User
                .Where(u => u.Id == user.Id)
                .Set(u => u.Password, MD5.GetMD5Hash(user.Password).ToLower());
            return statement.Update() > 0;
        }

        //查询当前值班信息
        public HkcChangeShifts GetOnDuty()
        {
            try
            {
                return _connection.HkcChangeShifts.Where(cs => cs.MachineId == _setting.machineId && cs.State == "0").FirstOrDefault();

            }
            catch (Exception ex)
            {
                logger.Info($"查询当前值班信息异常{ex.Message}");
                return null;
            }
        }
        //保存交接班信息
        public async Task<bool> UpdateChangeShift(HkcChangeShifts changeShift, HkcChangeShifts changeShiftNew)
        {
            try
            {
                _connection.BeginTransaction();
                var insertResult = _connection.InsertWithInt32Identity(changeShiftNew);

                int updateResult = _connection.HkcChangeShifts
                     .Where(cs => cs.Id == changeShift.Id)
                     .Set(cs => cs.State, "1")
                     .Set(cs => cs.ToDate, DateTime.Now)
                     .Set(cs => cs.ToOperator, changeShift.ToOperator).Update();

                //插入交接班时药品数据信息
                var channelStockList = _connection.ChannelStock
                     .Where(cs => (cs.MachineId == _setting.machineId || cs.MachineId == _setting.boxMachineId) && cs.DrawerType == 1)
                     .GroupBy(cs => cs.DrugId)
                     .Select(g => new
                     {
                         drugId = g.Key,
                         sumQuantity = g.Sum(cs => cs.Quantity)
                     }).ToList();

                if (channelStockList != null && channelStockList.Count > 0)
                {
                    //将药品库存信息写入交接明细表
                    for (int i = 0; i < channelStockList.Count; i++)
                    {
                        //查询药品上次交接的明细，用于记录处方数
                        HkcChangeShiftsDetail? historyList = _connection.HkcChangeShiftsDetail
                            .Where(d => d.DrugId == channelStockList[i].drugId && d.ChangeshiftsId == changeShift.Id).FirstOrDefault();

                        HkcChangeShiftsDetail detail = new HkcChangeShiftsDetail()
                        {
                            ChangeshiftsId = insertResult,
                            DrugId = channelStockList[i].drugId,
                            RealNumber = channelStockList[i].sumQuantity,
                            OrderNumber = historyList != null ? historyList.OrderNumber + historyList.RealNumber - channelStockList[i].sumQuantity : 0
                        };
                        var insertDetailResult = _connection.InsertWithInt32Identity(detail);
                    }
                }


                if (insertResult <= 0 || updateResult <= 0)
                {
                    _connection.RollbackTransaction();
                    return false;
                }
                else
                {
                    _connection.CommitTransaction();
                    return true;
                }
            }
            catch (Exception ex)
            {
                logger.Error($"更新交接班信息异常: {ex.Message}");
                return false;
            }
        }
    }
}
