using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiTPM.Utilities;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.TpmRepository.Entities;
using Siger.Middlelayer.TpmRepository.Repositories.Interface;
using Siger.Middlelayer.TpmRepository.Response;

namespace Siger.ApiTPM.Controllers
{
    public class AppIndexController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IRepairRepository _repairRepository;
        private readonly ISigerSystemConfigRepository _systemConfigRepository;
        private readonly IPlanRepository _planRepository;
        private readonly IPlanReportRepository _planReportRepository;
        private readonly IPlanItemRepository _planItemRepository;
        private readonly IWorkingRelationUserRepository _workingRelationUser;
        private readonly IWorkingRelationMachineRepository _workingRelationMachine;
        private readonly IWorkingCalendarRepository _calendarRepository;
        private readonly ISigerProjectUserRepository _projectUserRepository;
        private readonly ISigerAndonExpectionTypeRepository _andonExpectionTypeRepository;

        public AppIndexController(IUnitOfWork unitOfWork, IRepairRepository repairRepository, ISigerSystemConfigRepository systemConfigRepository
            , IPlanRepository planRepository, IPlanReportRepository planReportRepository, IPlanItemRepository planItemRepository, IWorkingRelationUserRepository workingRelationUser, IWorkingRelationMachineRepository workingRelationMachine,
            IWorkingCalendarRepository calendarRepository, ISigerProjectUserRepository projectUserRepository, ISigerAndonExpectionTypeRepository andonExpectionTypeRepository)
        {
            _unitOfWork = unitOfWork;
            _repairRepository = repairRepository;
            _systemConfigRepository = systemConfigRepository;
            _planRepository = planRepository;
            _planReportRepository = planReportRepository;
            _planItemRepository = planItemRepository;
            _workingRelationUser = workingRelationUser;
            _workingRelationMachine = workingRelationMachine;
            _calendarRepository = calendarRepository;
            _projectUserRepository = projectUserRepository;
            _andonExpectionTypeRepository = andonExpectionTypeRepository;
        }

        /// <summary>
        /// 获取APP首页数据
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetAppIndexItem()
        {
            var groupid = _projectUserRepository.Get(f => f.mid == UserId)?.usergroupid ?? "0";
            var abnormals = new List<ItemModel>();
            var todos = new List<ItemModel>();

            var userRelation = _workingRelationUser.Get(f => f.projectid == ProjectId && f.employ == UserId && f.status == (int)RowState.Valid);
            var machineIds = userRelation != null ? userRelation.machineSplit : new List<int>();

            //var machineIds = _calendarRepository.GetList(q =>
            //        q.user_mid == UserId && q.project_id == ProjectId && q.status == (int)RowState.Valid && q.date == DateTime.Now.Date).Select(q => q.machine_id)
            //    .Distinct().ToList();
            var repairReports = _repairRepository.GetRepairListByMachineArr(machineIds, 0, ProjectId, UserId)
                .OrderBy(t => t.machineid).ToList();
            var temp = repairReports.ToList();
            foreach (var item in temp)
            {
                if (item.expection == 0)
                {
                    continue;
                }
                var expectiondata = _andonExpectionTypeRepository.GetExpectionParent(item.expection, ProjectId).FirstOrDefault(f => f.level == 2);
                if (expectiondata == null)
                {
                    continue;
                }
                if (expectiondata.usergroup != groupid.ToInt() && expectiondata.second_usergroup != groupid.ToInt())
                {
                    repairReports.Remove(item);
                }
            }
            var locationHelper = new MachineLocationHelper(ProjectId, _planRepository);
            var levelSections = _repairRepository.GetAllSections(ProjectId).ToList();
            foreach (var repair in repairReports)
            {
                if (repair.report_level > 1)//工单维护
                {
                    var model = new ItemModel
                    {
                        Location = locationHelper.GetLocationsByMahcineIdForLoop(repair.machineid, levelSections),
                        itemid = repair.repairid,
                        type = (int)RepairOrPlanStatus.Repair,
                        content = "901100"
                    };
                    abnormals.Add(model);
                }
            }

            var planReports = GetPlanTimeOutsList(UnixTimeHelper.GetTodayUnix(), machineIds).OrderBy(t => t.machineid).ToList();
            foreach (var plan in planReports)
            {
                var model = new ItemModel
                {
                    Location = locationHelper.GetLocationsByMahcineIdForLoop(plan.machineid, levelSections),
                    itemid = plan.machineid,
                    type = (int)RepairOrPlanStatus.Plan,
                    content = "901101"
                };
                abnormals.Add(model);
            }

            var repairs = _repairRepository
                .GetList(t =>
                    t.status > 0 && t.status < (int)MachineRepairStatus.Completed && t.projectid == ProjectId && machineIds.Contains(t.machineid))
                .OrderBy(t => t.machineid).ToList();
            foreach (var repair in repairs)
            {
                var model = new ItemModel
                {
                    Location = locationHelper.GetLocationsByMahcineIdForLoop(repair.machineid, levelSections),
                    itemid = repair.id,
                    type = (int)RepairOrPlanStatus.Repair,
                    content = "901102"
                };
                todos.Add(model);
            }

            var plans = _planRepository
                .GetListAppIndexItem(machineIds, (int)PlanStatus.Normal, UnixTimeHelper.GetTodayUnix(), ProjectId)
                .GroupBy(t => t.machineid).Select(t => t.FirstOrDefault()).OrderBy(t => t.machineid).ToList();
            foreach (var plan in plans)
            {
                var model = new ItemModel
                {
                    Location = locationHelper.GetLocationsByMahcineIdForLoop(plan.machineid, levelSections),
                    itemid = plan.machineid,
                    type = (int)RepairOrPlanStatus.Plan,
                    content = "901103"
                };
                todos.Add(model);
            }

            var res = new ResponseAppIndexItem
            {
                abnormallist = abnormals,
                abnormalcount = abnormals.Count,
                todolist = todos,
                todocount = todos.Count
            };
            return new ObjectResult(res);
        }

        /// <summary>
        /// 获取异常上报的计划维护
        /// </summary>
        /// <returns></returns>
        private List<PlanByMachine> GetPlanTimeOutsList(int time, List<int> machineIds)
        {
            var res = new List<PlanTemp>();
            var planTimes =
                _planRepository.GetListAppIndexItem(machineIds, (int)PlanStatus.Normal, time, ProjectId);
            var config = _systemConfigRepository.Get(q =>
                q.key == SystemConfigKey.MessagePlanTime && q.status == (int)RowState.Valid);
            var repeatTime = (config != null ? config.value : "1").ToInt();
            var planReportLevelHelper =
                new PlanReportLevelHelper(ProjectId, _planReportRepository);
            var spaceTimeArr1 = _planReportRepository.GetList(t =>
                    t.projectid == ProjectId && t.status == (int)RowState.Valid && t.mode == 1)
                .ToList();
            var spaceTimeArr2 = _planReportRepository.GetList(t =>
                    t.projectid == ProjectId && t.status == (int)RowState.Valid && t.mode == 2)
                .ToList();
            foreach (var planTime in planTimes)
            {
                var tempArr = new PlanTemp
                {
                    planid = planTime.planid,
                    plantimeid = planTime.timeid,
                    machineid = planTime.machineid,
                    instruction_mid = planTime.instruction_mid,
                    instruction_time = planTime.instruction_time,
                    mode = planTime.mode,
                    type = ConvertTypeByInstructionCycle(planTime.instruction_cycle)
                };
                var spaceTimeArr = planTime.mode == 1 ? spaceTimeArr1 : spaceTimeArr2;
                var level = planReportLevelHelper.GetPlanReportTimeOut(planTime.mode, time, planTime.instruction_time,
                    planTime.instruction_cycle,
                    repeatTime, spaceTimeArr);
                if (level > 1)
                {
                    tempArr.level = level;
                    res.Add(tempArr);
                }
            }

            var result = new List<PlanByMachine>();
            var resGroup = res.GroupBy(t => t.machineid).ToList();
            foreach (var resPlan in resGroup)
            {
                var resList = resPlan.ToList();
                if (resList.Any())
                {
                    var model = new PlanByMachine
                    {
                        PlanTimeList = resList,
                        machineid = resList[0].machineid,
                        count = resList.Count,
                    };
                    result.Add(model);
                }
            }

            return result;
        }

        /// <summary>
        /// 获取当月 报修工单  维修工单 维修项目 的数量
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetMouthItemCount()
        {
            var res = new ResponseAppMouthItemCount();

            var machineIds = _calendarRepository.GetList(q =>
                    q.user_mid == UserId && q.project_id == ProjectId && q.status == (int)RowState.Valid && q.date == DateTime.Now.Date).Select(q => q.machine_id)
                .Distinct().ToList();

            var endTime = UnixTimeHelper.GetNow();
            var startTime =
                (int)UnixTimeHelper.ConvertDataTimeLong(DateTime.Now.ToString(ParameterConstant.YearMonthFormat)
                    .ToDateTime());

            res.submitrepairnum = _repairRepository
                .GetRepairListByMachineArr(machineIds, 0, ProjectId, UserId).Count(t =>
                    t.mid == UserId && t.createtime <= endTime && t.createtime >= startTime);

            var repairnum = 0;
            var repairs = _repairRepository.GetRepairListByMachineArr(machineIds, 0, ProjectId, UserId).Where(t =>
                t.mid != UserId && t.createtime <= endTime && t.createtime >= startTime);
            //工单是否与自己有关
            foreach (var repair in repairs)
            {
                var addUser = _repairRepository.GetAddUserListByRepairId(repair.repairid).ToList();
                var userList = addUser.Select(t => t.mid).ToList();
                if (!addUser.Any())
                {
                    var addrepairmid = repair.add_repairmid.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
                    foreach (var midstr in addrepairmid)
                    {
                        userList.Add(midstr.ToInt());
                    }
                }
                userList.Add(repair.mid);
                userList.Add(repair.takemid);
                userList.Add(repair.signmid);
                userList.Add(repair.checkmid);
                userList.Add(repair.completemid);
                userList.Add(repair.repairmid);

                if (userList.Contains(UserId) && repair.createtime <= endTime && repair.createtime >= startTime)
                {
                    repairnum++;
                }
            }
            res.repairnum = repairnum;

            res.plannum = GetMouthPlanCount(machineIds);
            res.Inventorynum = 0;
            return new ObjectResult(res);
        }

        private int GetMouthPlanCount(List<int> machineIds)
        {
            var startTime =
                (int)UnixTimeHelper.ConvertDataTimeLong(DateTime.Now.ToString(ParameterConstant.MouthFirstDay).ToDateTime());
            //计划维护历史（已完成）
            var res = _planItemRepository.GetPlanHistoryListByMid(startTime, machineIds, ProjectId, UserId).ToList();

            return res.Count(t => t.actual_mid == UserId || t.create_mid == UserId);
        }

        private int ConvertTypeByInstructionCycle(int instructionCycle)
        {
            int type;
            switch (instructionCycle)
            {
                case 1:
                    type = 1;
                    break;
                case 7:
                    type = 2;
                    break;
                case 15:
                    type = 3;
                    break;
                case 30:
                    type = 4;
                    break;
                case 60:
                    type = 5;
                    break;
                case 120:
                    type = 6;
                    break;
                case 180:
                    type = 7;
                    break;
                case 360:
                    type = 8;
                    break;
                default:
                    type = 0;
                    break;
            }

            return type;
        }
    }
}