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.Print;
using GxPress.Result.HumanAffairs;
using GxPress.Result.Print;
using Microsoft.Extensions.Options;
using Datory;

namespace GxPress.Repository.Implement
{
    public class PrintRepository : IPrintRepository
    {
        private readonly Repository<Print> _repository;
        public PrintRepository(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<Print>(database);
        }

        public IDatabase Database => _repository.Database;
        public string TableName => _repository.TableName;
        public List<TableColumn> TableColumns => _repository.TableColumns;
        /// <summary>
        /// 出版数据
        /// </summary>
        /// <param name="prints"></param>
        /// <returns></returns>
        public async Task<bool> InsertAsync(IEnumerable<Print> prints)
        {
            try
            {
                using (TransactionScope transactionScope = new TransactionScope())
                {
                    foreach (var print in prints)
                    {
                        await _repository.InsertAsync(print);
                    }

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

            return true;
        }
        /// <summary>
        /// 分页显示
        /// </summary>
        /// <returns></returns>
        public async Task<PagedList<Print>> GetPageListAsync(PageParameter request)
        {
            var result = new PagedList<Print>
            {
                Items = await _repository.GetAllAsync(Q.ForPage(request.Page, request.PerPage)),
                Total = await _repository.CountAsync()
            };
            return result;
        }

        public async Task<PrintResult> GetPrintChartAsync(PrintRequest request)
        {
            var result = new PrintResult();
            //获取当前时间
            DateTime dt = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"));
            //当前星期几
            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.VolumeCount) - a.Sum(n => n.VolumeCount);
            //同比月增长多少金额
            result.ComparedMonthAmount = b.Sum(n => n.PublishAmount) - a.Sum(n => n.PublishAmount);
            //本年累计出版册数
            result.YearPrintCount = c.Sum(n => n.VolumeCount);
            //本年累计出版金额
            result.YearPrintAmount = c.Sum(n => n.PublishAmount);
            //本年累计的印刷费用
            result.YearPressAmount = c.Sum(n => n.PrintAmount);
            //
            //本月累计出版册数
            result.MonthPrintCount = b.Sum(n => n.VolumeCount);
            //本月累计出版金额
            result.MonthPrintAmount = b.Sum(n => n.PublishAmount);
            //本月累计的印刷费用
            result.MonthPressAmount = b.Sum(n => n.PrintAmount);

            //计算周
            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.PublishAmount)
                    };
                    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.PublishAmount)
                    };
                    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.PublishAmount)
                    };
                    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.PublishAmount)
                    };
                    result.HumanAffairsChartDataResult.Add(humanAffairsChartData);
                    beginDat = endDay;
                }
            }

            //支出

            return result;
        }
    }
}
