using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Result;
using Siger.ApiCommon.Utilities;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.AppSettings;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.Log;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Request;
using Siger.Middlelayer.Repository.Response;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.ApiConfig.Controller
{
    public class WorkingCalendarController : BaseController
    {
        private readonly IWorkingGroupRepository _groupRepository;
        //private readonly IWorkingMachineSetRepository _machineSetRepository;
        private readonly ISigerProjectUserRepository _projectUserRepository;
        private readonly ISigerProjectMachineAttributionRepository _attributionRepository;
        private readonly IWorkingRelationMachineRepository _workingRelationMachine;
        private readonly IWorkingRelationUserRepository _workingRelationUser;
        private readonly IWorkingCalendarRepository _calendarRepository;
        private readonly ISigerProjectShiftRepository _projectShiftRepository;
        private readonly IUnitOfWork _unitOfWork;

        public WorkingCalendarController(IWorkingGroupRepository groupRepository,
             ISigerProjectUserRepository projectUserRepository,
            ISigerProjectMachineAttributionRepository attributionRepository,IWorkingRelationMachineRepository workingRelationMachine,IWorkingRelationUserRepository workingRelationUser,
            IWorkingCalendarRepository calendarRepository, ISigerProjectShiftRepository projectShiftRepository, IUnitOfWork unitOfWork)
        {
            _groupRepository = groupRepository;
            //_machineSetRepository = machineSetRepository;
            _projectUserRepository = projectUserRepository;
            _attributionRepository = attributionRepository;
            _workingRelationMachine = workingRelationMachine;
            _workingRelationUser = workingRelationUser;
            _calendarRepository = calendarRepository;
            _projectShiftRepository = projectShiftRepository;
            _unitOfWork = unitOfWork;
        }

        [HttpGet]
        public IActionResult GetWorkingMachine(int sectionId, int workinggroupId)
        {
            //var list = _machineSetRepository.GetList(q =>
            //    q.section_id == sectionId && q.workinggroup_id == workinggroupId && q.project_id == ProjectId);
          

            //var userIds = new List<int>();
            //var machineIds = new List<int>();

            //var hasMachineIds = list.Select(q => q.machine_id).ToList();
            //var attrs = _attributionRepository.GetList(q =>
            //    hasMachineIds.Contains(q.machine) && q.status == (int) RowState.Valid && q.projectid == ProjectId).ToList();

            //foreach (var set in list.ToList())
            //{
            //    if (!userIds.Contains(set.user_mid))
            //    {
            //        userIds.Add(set.user_mid);
            //    }

            //    var attr = attrs.FirstOrDefault(q => q.machine == set.machine_id);
            //    if (attr != null)
            //    {
            //        if (!machineIds.Contains(attr.station))
            //        {
            //            machineIds.Add(attr.station);
            //        }
            //    }
            //}


            var response = new ResponseGetWorkingMachine
            {
                section_id = sectionId,
                workgroup_id = workinggroupId
            };
            var machineSet = _workingRelationUser.Get(f => f.projectid == ProjectId && f.section == sectionId && f.workgroup_id == workinggroupId && f.status == (int)RowState.Valid);
            response.machine_ids = machineSet != null ? string.Join(',', machineSet.stations) : "";
            var userSet = _workingRelationMachine.Get(f => f.projectid == ProjectId && f.section == sectionId && f.workgroup_id == workinggroupId && f.status == (int)RowState.Valid);
            response.user_mids = userSet != null ? string.Join(',', userSet.employs) : "";
            return new ObjectResult(response);

        }

        [HttpPost]
        public IActionResult UpdateUserWokingGroup([FromBody]RequestUpdateUserWokingGroup request)
        {
            var dt = request.date.ToDateTime();
            var cals = _calendarRepository.GetList(q =>
                    q.user_mid == request.usermid && q.date.Date == dt.Date
                                                  && q.project_id == ProjectId && q.status == (int)RowState.Valid).ToList();
            if (!cals.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            if(dt.Date<DateTime.Now.Date)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            foreach (var cal in cals)
            {
                cal.shift_id = request.shiftid;
                _calendarRepository.Update(cal);
            }

            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult GetSectionWokingGroup(int sectionId, string date, int page = PageIndex, int pagesize = PageSize, int toexcel = 0)
        {
            if (sectionId == 0)
            {
                throw new BadRequestException(RequestEnum.SectionIsEmpty);
            }
            var dt = date.ToDateTime() == DateTime.MinValue ? DateTime.Now : date.ToDateTime();
            var dtstart = dt.ToString(ParameterConstant.MouthFirstDay).ToDateTime();
            var dtend = DateTime.Parse(dt.ToString(ParameterConstant.MouthFirstDay)).AddMonths(1).AddDays(-1);

            var responses = new List<ResponseGetSectionWokingGroup>();
            var allusers = _projectUserRepository.GetUsersBySectionid(sectionId, ProjectId);
            var users = allusers.Skip((page - 1) * pagesize).Take(pagesize);
            var userids = users.Select(m => m.id);
            var cals = _calendarRepository.GetList(q =>
                userids.Contains(q.user_mid) && q.date >= dtstart && q.date <= dtend
                && q.project_id == ProjectId && q.status == (int)RowState.Valid);
            var allshifts = _projectShiftRepository.GetList(q => q.projectid == ProjectId && q.status == (int)RowState.Valid);

            foreach (var projectUser in users)
            {
                var response = new ResponseGetSectionWokingGroup
                {
                    usermid = projectUser.id,
                    usergroupname = projectUser.usergrouptitle,
                    username = projectUser.name
                };

                var shifts = cals.Where(q => q.user_mid == projectUser.id);
                if (shifts.Any())
                {
                    for (var day = dtstart; day <= dtend; day = day.AddDays(1))
                    {
                        var shift = shifts.FirstOrDefault(q => q.date == day.Date);
                        if (shift != null)
                        {
                            var shiftname = allshifts.FirstOrDefault(q => q.id == shift.shift_id);
                            response.shifts.Add(new ResponseShiftinfo
                            {
                                shiftid = shift.shift_id,
                                shiftname = shiftname == null ? "" : shiftname.title,
                            });
                        }
                        else
                        {
                            response.shifts.Add(new ResponseShiftinfo
                            {
                                shiftid = 0,
                                shiftname = "",
                            });
                        }
                    }
                }
                responses.Add(response);
            }

            if (toexcel == 0)
            {
                return new PagedObjectResult(responses, allusers.Count(), page, pagesize);
            }

            return ExportWorkGroup(responses, dt);
        }

        private IActionResult ExportWorkGroup(List<ResponseGetSectionWokingGroup> responses, DateTime dt)
        {
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);

            var temporaryFileName = $"schedule_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileName = Path.Combine(rootDir, temporaryFileName);

            var helper = new EpPlusForWorkGroupHelper();
            try
            {
                var userList = new List<SectionWokingGroupList>();
                var index = 1;
                foreach (var projectUser in responses)
                {
                    var user = new SectionWokingGroupList
                    {
                        UserName = projectUser.username,
                        GroupName = projectUser.usergroupname,
                        Dates = projectUser.shifts.Select(m => m.shiftname).ToList()
                    };
                    userList.Add(user);
                    index++;
                }

                var columns = new List<string>
                {
                    "岗位",
                    "姓名"
                };
                var days = DateTime.DaysInMonth(dt.Year, dt.Month);
                for (var i = 1; i <= days; i++)
                {
                    var date = dt.Year + "-" + dt.Month + "-" + i;
                    var weekname = DateTimeHelper.GetWeekName((int)DateTime.Parse(date).DayOfWeek);
                    columns.Add(date + "(" + weekname + ")");
                }
                helper.GenerateExcel(userList, columns, fileName);
                return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ExportWorkGroup failed, error: " + e.Message);
                throw new BadRequestException(RequestEnum.ExportFailed);
            }
            finally
            {
                helper.Dispose();
            }
        }

        [HttpPost]
        public IActionResult UpdateWorkingGroup([FromBody]RequestUpdateWorkingGroup request)
        {
            var group = _groupRepository.Get(q => q.id == request.id && q.status == (int)RowState.Valid && q.project_id == ProjectId);
            if (group == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            //不同部门下班组不能重名
            var isExist = _groupRepository.Get(q =>
                q.section_id == request.sectionid && q.project_id == ProjectId && q.name == request.name &&
                q.status == (int)RowState.Valid && q.id != request.id);
            if (isExist != null)
            {
                throw new BadRequestException(RequestEnum.NameHasExist);
            }

            var oldids = group.user_mids.TrimEnd(',').Split(',').Select(x => x.ToInt()).ToList();
            var newids = request.user_mids.TrimEnd(',').Split(',').Select(x => x.ToInt()).ToList();
            var excepuserids = oldids.Except(newids);
            if (excepuserids.Any())
            {
                //删除设置
                //var list = _machineSetRepository.GetList(q => excepuserids.Contains(q.user_mid) && q.project_id == ProjectId && q.status == (int)RowState.Valid);
                //foreach (var set in list.ToList())
                //{
                //    _machineSetRepository.Delete(set);
                //}
                var userRelation = _workingRelationUser.GetList(f => f.projectid == ProjectId && f.workgroup_id==group.id && excepuserids.Contains(f.employ));
                foreach(var userSet in userRelation)
                {
                    _workingRelationUser.Delete(userSet);
                }

                //删除全部的排班
                var clas = _calendarRepository.GetList(q => excepuserids.Contains(q.user_mid) && q.project_id == ProjectId && q.working_group==group.id);
                if (clas.Any())
                {
                    foreach (var calendar in clas)
                    {
                        _calendarRepository.Delete(calendar);
                    }
                }
            }

            group.name = request.name;
            group.user_mids = request.user_mids.TrimEnd(',');
            group.start_date = request.start_date.ToDateTime();

            _groupRepository.Update(group);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
    }
}