using System;
using System.Collections.Generic;
using System.Linq;
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.HumanAffairs;
using GxPress.Result.HumanAffairs;
using Microsoft.Extensions.Options;
using Datory;

namespace GxPress.Repository.Implement
{
    public class HumanAffairsRepository : IHumanAffairsRepository
    {
        private readonly Repository<HumanAffairs> _repository;

        public HumanAffairsRepository(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<HumanAffairs>(database);
        }

        public IDatabase Database => _repository.Database;
        public string TableName => _repository.TableName;
        public List<TableColumn> TableColumns => _repository.TableColumns;

        /// <summary>
        /// 添加人事数据
        /// </summary>
        /// <param name="humanAffairsList"></param>
        /// <returns></returns>
        public async Task<bool> InsertAsync(IEnumerable<HumanAffairs> humanAffairsList)
        {
            try
            {
                using (TransactionScope transactionScope = new TransactionScope())
                {
                    foreach (var humanAffairs in humanAffairsList)
                    {
                        await _repository.InsertAsync(humanAffairs);
                    }

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

            return true;
        }

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

        /// <summary>
        /// 获取人数图像数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<HumanAffairsResult> GetHumanAffairsChartAsync(HumanAffairsRequest request)
        {
            var humanAffairs = new List<int>();
            if (request.DataType == 1)
            {
                humanAffairs.Add(1);
                humanAffairs.Add(2);
            }
            else
                humanAffairs.Add(request.DataType - 1);
            var result = new HumanAffairsResult();
            //获取当前时间
            DateTime dt = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"));
            //当前星期几
            int weekNow = Convert.ToInt32(DateTime.Now.DayOfWeek);
            //集团
            result.HumanAffairsChartDataResult = new List<HumanAffairsChartData>();
            //总人数
            var humanAffairsTypeOne =
                await _repository.GetAllAsync();
            result.PersonCount = humanAffairsTypeOne.Sum(n => n.NumberPeople);
            //工资总额
            result.Salary = humanAffairsTypeOne.Sum(n => n.Salary);
            //上月人数
            var a = await _repository.GetAllAsync(Q.WhereIn(nameof(HumanAffairs.HumanAffairsType), humanAffairs)
                .WhereDate(nameof(HumanAffairs.EnteringDateTime), "<=", dt.AddDays(-dt.Day))
                .WhereDate(nameof(HumanAffairs.EnteringDateTime), ">=",
                    dt.AddDays(-dt.Day).AddMonths(1)));
            //本月人数
            var b = await _repository.GetAllAsync(Q.WhereIn(nameof(HumanAffairs.HumanAffairsType), humanAffairs)
                .WhereDate(nameof(HumanAffairs.EnteringDateTime), "<=", dt)
                .WhereDate(nameof(HumanAffairs.EnteringDateTime), ">=",
                    dt.AddDays(-dt.Day)));
            //同比上月增长多少钱
            result.ComparedMonthAmount = b.Sum(n => n.Salary) - a.Sum(n => n.Salary);
            //同比上月增长人数
            result.ComparedMonthCount = b.Sum(n => n.NumberPeople) - a.Sum(n => n.NumberPeople);

            //工资总额
            result.Salary = b.Sum(n => n.Salary);
            //
            if (request.DataType > 1)
            {
                //天
                if (request.DateType == 1)
                {
                    var humanAffairsDay = await _repository.GetAllAsync(Q.WhereIn(nameof(HumanAffairs.HumanAffairsType), humanAffairs)
                      .WhereDate(nameof(HumanAffairs.EnteringDateTime), "<=", DateTime.Now)
                      .WhereDate(nameof(HumanAffairs.EnteringDateTime), ">=", dt));
                    result.PersonCount = humanAffairsDay.Sum(n => n.NumberPeople);
                }
                //周
                else if (request.DateType == 2)
                {
                    var weekDt = dt;
                    //本周
                    if (dt.DayOfWeek.GetHashCode() == 0)
                        weekDt = dt.AddDays(-7);
                    else
                        weekDt = dt.AddDays(-dt.DayOfWeek.GetHashCode());
                    var humanAffairsDay = await _repository.GetAllAsync(Q.WhereIn(nameof(HumanAffairs.HumanAffairsType), humanAffairs)
                                         .WhereDate(nameof(HumanAffairs.EnteringDateTime), "<=", DateTime.Now)
                                         .WhereDate(nameof(HumanAffairs.EnteringDateTime), ">=", weekDt));
                    result.PersonCount = humanAffairsDay.Sum(n => n.NumberPeople);
                }
                //月
                else if (request.DateType == 3)
                {
                    var mouthDt = dt;
                    mouthDt = dt.AddDays(-dt.Day);
                    var humanAffairsDay = await _repository.GetAllAsync(Q.WhereIn(nameof(HumanAffairs.HumanAffairsType), humanAffairs)
                                         .WhereDate(nameof(HumanAffairs.EnteringDateTime), "<=", DateTime.Now)
                                         .WhereDate(nameof(HumanAffairs.EnteringDateTime), ">=", mouthDt));
                    result.PersonCount = humanAffairsDay.Sum(n => n.NumberPeople);
                }
                //年
                else if (request.DateType == 4)
                {
                    var yearDt = dt;
                    yearDt = dt.AddMonths(-dt.Month).AddDays(-dt.Day);
                    var humanAffairsDay = await _repository.GetAllAsync(Q.WhereIn(nameof(HumanAffairs.HumanAffairsType), humanAffairs)
                                         .WhereDate(nameof(HumanAffairs.EnteringDateTime), "<=", DateTime.Now)
                                         .WhereDate(nameof(HumanAffairs.EnteringDateTime), ">=", yearDt));
                    result.PersonCount = humanAffairsDay.Sum(n => n.NumberPeople);
                }
            }
            //计算周
            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.WhereIn(nameof(HumanAffairs.HumanAffairsType), humanAffairs)
                        .WhereDate(nameof(HumanAffairs.EnteringDateTime), "<=", beginDat)
                        .WhereDate(nameof(HumanAffairs.EnteringDateTime), ">=", endDay));
                    var humanAffairsChartData = new HumanAffairsChartData
                    {
                        NavigationNumber = i,
                        ResultParameter = humanAffairsWeekList.Sum(n => n.NumberPeople)
                    };
                    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.WhereIn(nameof(HumanAffairs.HumanAffairsType), humanAffairs)
                        .WhereDate(nameof(HumanAffairs.EnteringDateTime), "<=", beginDat)
                        .WhereDate(nameof(HumanAffairs.EnteringDateTime), ">=", endDay));
                    var humanAffairsChartData = new HumanAffairsChartData
                    {
                        NavigationNumber = i,
                        ResultParameter = humanAffairsDayList.Sum(n => n.NumberPeople)
                    };
                    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.WhereIn(nameof(HumanAffairs.HumanAffairsType), humanAffairs)
                        .WhereDate(nameof(HumanAffairs.EnteringDateTime), "<=", beginDat)
                        .WhereDate(nameof(HumanAffairs.EnteringDateTime), ">=", endDay));
                    var humanAffairsChartData = new HumanAffairsChartData
                    {
                        NavigationNumber = i,
                        ResultParameter = humanAffairsMonthList.Sum(n => n.NumberPeople)
                    };
                    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.WhereIn(nameof(HumanAffairs.HumanAffairsType), humanAffairs)
                        .WhereDate(nameof(HumanAffairs.EnteringDateTime), "<=", beginDat)
                        .WhereDate(nameof(HumanAffairs.EnteringDateTime), ">=", endDay));
                    var humanAffairsChartData = new HumanAffairsChartData
                    {
                        NavigationNumber = i,
                        ResultParameter = humanAffairsYearList.Sum(n => n.NumberPeople)
                    };
                    result.HumanAffairsChartDataResult.Add(humanAffairsChartData);
                    beginDat = endDay;
                }
            }
            return result;
        }
    }
}