using Edge.Core.Core.database;
using Edge.Core.Domain.FccNozzleInfo.Output;
using Edge.Core.Domain.FccTankInfo.Input;
using Edge.Core.Domain.FccTankInfo.Output;
using Microsoft.EntityFrameworkCore;

namespace FccLite.Web.Repositories.FccTankInfo
{
    public class TankReposity : ITankReposity
    {
        static NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();

        private readonly MysqlDbContext _dbContext;

        public TankReposity(MysqlDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        /// <summary>
        /// 增加油罐
        /// </summary>
        /// <param name="addTankInput">油罐信息</param>
        /// <returns></returns>
        public async Task<int> AddDetailsTankAsync(AddTankInput addTankInput)
        {
            _dbContext.TankInfos.Add(addTankInput.ToComponent());
            return await _dbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 通过油罐id删除油罐
        /// </summary>
        /// <param name="id">油罐id</param>
        /// <returns></returns>
        public async Task<int> DeleteTankById(long id)
        {
            Edge.Core.Domain.FccTankInfo.FccTankInfo? tankInfo = await _dbContext.TankInfos.FirstOrDefaultAsync(info => info.Id == id);
            if (tankInfo == null)
            {
                Logger.Info($"find tank info with id :{id} for delete,result is null");
                return 0;
            }
            //先批量删除所关联的油枪
            List<Edge.Core.Domain.FccNozzleInfo.FccNozzleInfo> fccNozzleInfos = await _dbContext.NozzleInfos.Where(info => info.TankId == tankInfo.Id).ToListAsync();
            _dbContext.NozzleInfos.RemoveRange(fccNozzleInfos);
            //再删除油罐
            _dbContext.TankInfos.Remove(tankInfo);
            return await _dbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 统计站点 id 获取油罐基本信息
        /// </summary>
        /// <param name="stationId">站点id</param>
        /// <returns></returns>
        public async Task<List<BaseTankInfoOutput>> GetBaseTankByStationIdAsync(long stationId)
        {
            var query = from tank in _dbContext.TankInfos
                        join nozzle in _dbContext.NozzleInfos
                        on tank.Id equals nozzle.TankId
                        into baseTankInfo
                        select new BaseTankInfoOutput()
                        {
                            Id = tank.Id,
                            Number = tank.Number,
                            OilId = tank.OilId,
                            OilName = tank.OilName,
                            AssociatedNozzles = baseTankInfo.Select(info => new BaseTankInfoOutput.AssociatedNozzle()
                            {
                                NozzleId = info.Id,
                                NozzleNum = info.ExternalNum
                            }).ToList()
                        };

            return await query.ToListAsync();
        }

        /// <summary>
        /// 通过油罐id获取油罐详情信息
        /// </summary>
        /// <param name="tankId">油罐id</param>
        /// <returns></returns>
        public async Task<Edge.Core.Domain.FccTankInfo.FccTankInfo?> GetDetailsTankByTankIdAsync(long tankId)
        {
            return await _dbContext.TankInfos.FirstOrDefaultAsync(info => info.Id == tankId);
        }

        /// <summary>
        /// 修改油罐
        /// </summary>
        /// <param name="updateTankInput">油罐信息</param>
        /// <returns></returns>
        public async Task<int> UpdateDetailsTankAsync(UpdateTankInput updateTankInput)
        {
            Edge.Core.Domain.FccTankInfo.FccTankInfo? fccTankInfo = await _dbContext.TankInfos.FirstOrDefaultAsync(info => info.Id == updateTankInput.Id);
            if (fccTankInfo == null)
            {
                Logger.Info($"find tank info with id : {updateTankInput.Id} for update,result is null");
                return 0;
            }

            fccTankInfo.Number = updateTankInput.Number;
            fccTankInfo.OilId = updateTankInput.OilId;
            fccTankInfo.OilName = updateTankInput.OilName;
            fccTankInfo.Capacity = updateTankInput.Capacity;

            return await _dbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 获取油罐id,油罐号
        /// </summary>
        /// <returns></returns>
        public async Task<List<DetailsNozzleInfoOutput.RelatableTank>> GetTankInfo()
        {
            return await _dbContext.TankInfos.Select(info => new DetailsNozzleInfoOutput.RelatableTank
            {
                TankId = info.Id,
                TankNum = info.Number
            }).ToListAsync();
        }

        public async Task<DetailTankInfoForCloud?> GetTankDetail(long id)
        {
            var query = from tank in _dbContext.TankInfos
                        join oil in _dbContext.OilInfos
                        on tank.OilId equals oil.Id
                        where tank.Id == id
                        select new DetailTankInfoForCloud()
                        {
                            TankNumber = tank.Number,
                            TankCapacity = tank.Capacity,
                            ProductName = oil.Name,
                            ProductCode = oil.Code,
                            ProductPrice = oil.Price
                        };

            return await query.FirstOrDefaultAsync();
        }
    }
}
