using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using AutoMapper;
using GxPress.Common.AppOptions;
using GxPress.Common.Exceptions;
using GxPress.Common.Page;
using GxPress.Common.Tools;
using GxPress.Entity;
using GxPress.Repository.Interface;
using GxPress.Request.Sell;
using GxPress.Result.HumanAffairs;
using GxPress.Result.Print;
using GxPress.Result.sell;
using Microsoft.Extensions.Options;
using Datory;

namespace GxPress.Repository.Implement
{
    public class SellRepository : ISellRepository
    {
        private readonly Repository<Sell> _repository;
        public SellRepository(IOptionsMonitor<DatabaseOptions> dbOptionsAccessor, IMapper mapper)
        {
            var databaseType = StringUtils.ToEnum<DatabaseType>(dbOptionsAccessor.CurrentValue.DatabaseType, DatabaseType.MySql);
            var database = new Database(databaseType, dbOptionsAccessor.CurrentValue.ConnectionString);
            _repository = new Repository<Sell>(database);
        }

        public IDatabase Database => _repository.Database;
        public string TableName => _repository.TableName;
        public List<TableColumn> TableColumns => _repository.TableColumns;
        /// <summary>
        /// 添加发行数据
        /// </summary>
        /// <param name="sells"></param>
        /// <returns></returns>
        public async Task<bool> InsertAsync(IEnumerable<Sell> sells)
        {
            try
            {
                using (TransactionScope transactionScope = new TransactionScope())
                {
                    foreach (var sell in sells)
                    {
                        await _repository.InsertAsync(sell);
                    }

                    transactionScope.Complete();
                }
            }
            catch (Exception e)
            {
                throw new BusinessException(e.Message);
            }

            return true;
        }

        public async Task<PagedList<Sell>> GetPageListAsync(PageParameter request)
        {
            var result = new PagedList<Sell>
            {
                Items = await _repository.GetAllAsync(Q.ForPage(request.Page, request.PerPage)),
                Total = await _repository.CountAsync()
            };
            return result;
        }

        public async Task<SellResult> GetSellChartAsync(SellRequest request)
        {
            var result = new SellResult();
            //获取当前时间
            DateTime dt = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"));
            var nowDt = DateTime.Now;
            //当前星期几
            int weekNow = Convert.ToInt32(DateTime.Now.DayOfWeek);
            result.HumanAffairsChartDataResult = new List<HumanAffairsChartData>();
            //收入
            //上月
            var a = await _repository.GetAllAsync(Q
                .WhereDate(nameof(Print.EnteringDateTime), "<=", dt.AddDays(-dt.Day))
                .WhereDate(nameof(Print.EnteringDateTime), ">=",
                    dt.AddDays(-dt.Day).AddMonths(1)));
            //本月
            var b = await _repository.GetAllAsync(Q
                .WhereDate(nameof(Print.EnteringDateTime), "<=", dt)
                .WhereDate(nameof(Print.EnteringDateTime), ">=",
                    dt.AddDays(-dt.Day)));
            //本年
            var c = await _repository.GetAllAsync(Q
                .WhereDate(nameof(Print.EnteringDateTime), "<=", dt)
                .WhereDate(nameof(Print.EnteringDateTime), ">=",
                    dt.AddDays(-dt.DayOfYear)));
            //同比月增长多少册
            result.ComparedMonthCount = b.Sum(n => n.SellVolumeCount) - a.Sum(n => n.SellVolumeCount);
            //同比月增长多少金额
            result.ComparedMonthAmount = b.Sum(n => n.SellAmount) - a.Sum(n => n.SellAmount);
            if (request.DateType == 1)
            {
                b = await _repository.GetAllAsync(Q
                   .WhereDate(nameof(Print.EnteringDateTime), "<=", nowDt)
                   .WhereDate(nameof(Print.EnteringDateTime), ">=", dt));
                //同比月增长多少册
                result.ComparedMonthCount = b.Sum(n => n.SellVolumeCount);
                //同比月增长多少金额
                result.ComparedMonthAmount = b.Sum(n => n.SellAmount);
            }
            else if (request.DateType == 2)
            {
                var weekDt = dt;
                //本周
                if (dt.DayOfWeek.GetHashCode() == 0)
                    weekDt = dt.AddDays(-7);
                else
                    weekDt = dt.AddDays(-dt.DayOfWeek.GetHashCode());
                b = await _repository.GetAllAsync(Q
                 .WhereDate(nameof(Print.EnteringDateTime), "<=", nowDt)
                 .WhereDate(nameof(Print.EnteringDateTime), ">=", weekDt));
                //同比月增长多少册
                result.ComparedMonthCount = b.Sum(n => n.SellVolumeCount);
                //同比月增长多少金额
                result.ComparedMonthAmount = b.Sum(n => n.SellAmount);
            }
            else if (request.DateType == 3)
            {
                var mouthDt = dt;
                mouthDt = dt.AddDays(-dt.Day);
                b = await _repository.GetAllAsync(Q
                 .WhereDate(nameof(Print.EnteringDateTime), "<=", nowDt)
                 .WhereDate(nameof(Print.EnteringDateTime), ">=", mouthDt));
                //同比月增长多少册
                result.ComparedMonthCount = b.Sum(n => n.SellVolumeCount);
                //同比月增长多少金额
                result.ComparedMonthAmount = b.Sum(n => n.SellAmount);
            }
            else if (request.DateType == 4)
            {
                var yearDt = dt;
                yearDt = dt.AddMonths(-dt.Month).AddDays(-dt.Day);
                b = await _repository.GetAllAsync(Q
                 .WhereDate(nameof(Print.EnteringDateTime), "<=", nowDt)
                 .WhereDate(nameof(Print.EnteringDateTime), ">=", yearDt));
                //同比月增长多少册
                result.ComparedMonthCount = b.Sum(n => n.SellVolumeCount);
                //同比月增长多少金额
                result.ComparedMonthAmount = b.Sum(n => n.SellAmount);
            }
            //本月发行额
            result.MonthSellAmount = b.Sum(n => n.SellAmount);
            //本月发行数量
            result.MonthSellCount = b.Sum(n => n.SellVolumeCount);
            //计算周
            if (request.DateType == 2)
            {
                var beginDat = dt;
                for (int i = 1; i <= 7; i++)
                {
                    var week = (i - 1) * 7;
                    var endDay = beginDat.AddDays(-weekNow + week + 1);
                    var query = Q.NewQuery();
                    var humanAffairsWeekList = await _repository.GetAllAsync(query
                        .WhereDate(nameof(Print.EnteringDateTime), "<=", beginDat)
                        .WhereDate(nameof(Print.EnteringDateTime), ">=", endDay));
                    var humanAffairsChartData = new HumanAffairsChartData
                    {
                        NavigationNumber = i,
                        ResultParameter = humanAffairsWeekList.Sum(n => n.SellAmount)
                    };
                    result.HumanAffairsChartDataResult.Add(humanAffairsChartData);
                    beginDat = endDay;
                }
            }

            //天数
            if (request.DateType == 1)
            {
                var beginDat = dt;
                for (int i = 1; i <= 7; i++)
                {

                    var endDay = beginDat.AddDays(-1);
                    var query = Q.NewQuery();
                    var humanAffairsDayList = await _repository.GetAllAsync(query
                        .WhereDate(nameof(Print.EnteringDateTime), "<=", beginDat)
                        .WhereDate(nameof(Print.EnteringDateTime), ">=", endDay));
                    var humanAffairsChartData = new HumanAffairsChartData
                    {
                        NavigationNumber = i,
                        ResultParameter = humanAffairsDayList.Sum(n => n.SellAmount)
                    };
                    result.HumanAffairsChartDataResult.Add(humanAffairsChartData);
                    beginDat = endDay;
                }
            }
            //月
            if (request.DateType == 3)
            {
                var beginDat = dt;
                for (int i = 1; i <= 7; i++)
                {
                    var days = beginDat.Day;
                    var endDay = dt.AddDays(-days).AddMonths(-1);
                    var query = Q.NewQuery();
                    var humanAffairsMonthList = await _repository.GetAllAsync(query
                        .WhereDate(nameof(Print.EnteringDateTime), "<=", beginDat)
                        .WhereDate(nameof(Print.EnteringDateTime), ">=", endDay));
                    var humanAffairsChartData = new HumanAffairsChartData
                    {
                        NavigationNumber = i,
                        ResultParameter = humanAffairsMonthList.Sum(n => n.SellAmount)
                    };
                    result.HumanAffairsChartDataResult.Add(humanAffairsChartData);
                    beginDat = endDay;
                }
            }

            //年
            if (request.DateType == 4)
            {
                var beginDat = dt;
                for (int i = 1; i <= 7; i++)
                {
                    var days = beginDat.DayOfYear;
                    var endDay = dt.AddDays(-days).AddYears(-1);
                    var query = Q.NewQuery();
                    var humanAffairsYearList = await _repository.GetAllAsync(query
                        .WhereDate(nameof(Print.EnteringDateTime), "<=", beginDat)
                        .WhereDate(nameof(Print.EnteringDateTime), ">=", endDay));
                    var humanAffairsChartData = new HumanAffairsChartData
                    {
                        NavigationNumber = i,
                        ResultParameter = humanAffairsYearList.Sum(n => n.SellAmount)
                    };
                    result.HumanAffairsChartDataResult.Add(humanAffairsChartData);
                    beginDat = endDay;
                }
            }
            //支出
            return result;
        }
    }
}