using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using NPOI.SS.Formula.Functions;
using Siger.ApiCommon.Exceptions;
using Siger.ApiCommon.Result;
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.Log;
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.Request;
using Siger.Middlelayer.TpmRepository.Response;
using Siger.ApiCommon.Filters;
using Siger.Middlelayer.Utility.Helpers;

namespace Siger.ApiTPM.Controllers
{
    /// <summary>
    /// 安灯基础设置
    /// </summary>
    public class AndonBaseSettingController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerAndonProcessRepository _andonProcessRepository;
        private readonly IPlanReportRepository _planReportRepository;
        private readonly IPlanReportLevelRepository _planReportLevelRepository;
        private readonly ISigerAndonExpectionTypeRepository _andonExpectionType;
        private readonly ISigerAndonPlan _sigerAndonPlan;
        private readonly ISigerProjectUserRepository _projectUserRepository;
        private readonly ISigerProjectMachineRepository _projectMachineRepository;
        private readonly ISigerProjectLevelSectionRepository _projectLevelSectionRepository;
        private readonly ISigerAndonStationConfigRepository _andonStationConfigRepository;
        private readonly ISigerProjectMachineAttributionRepository _machineAttributionRepository;

        public AndonBaseSettingController(IUnitOfWork unitOfWork, ISigerAndonProcessRepository andonProcessRepository, IPlanReportRepository planReportRepository, IPlanReportLevelRepository planReportLevelRepository
            , ISigerAndonExpectionTypeRepository andonExpectionType, ISigerAndonPlan sigerAndonPlan, ISigerProjectUserRepository projectUserRepository, ISigerProjectMachineRepository projectMachineRepository
            , ISigerProjectLevelSectionRepository projectLevelSectionRepository, ISigerAndonStationConfigRepository andonStationConfigRepository, ISigerProjectMachineAttributionRepository machineAttributionRepository)
        {
            _unitOfWork = unitOfWork;
            _andonProcessRepository = andonProcessRepository;
            _planReportRepository = planReportRepository;
            _planReportLevelRepository = planReportLevelRepository;
            _andonExpectionType = andonExpectionType;
            _sigerAndonPlan = sigerAndonPlan;
            _projectUserRepository = projectUserRepository;
            _projectMachineRepository = projectMachineRepository;
            _projectLevelSectionRepository = projectLevelSectionRepository;
            _andonStationConfigRepository = andonStationConfigRepository;
            _machineAttributionRepository = machineAttributionRepository;
        }
        /// <summary>
        /// 信息推送流程查询
        /// </summary>
        /// <param name="name"></param>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet]
        [ProducesDefaultResponseType(typeof(ResponseAndonProcess))]
        public IActionResult GetInfoProcessData(string name, int page, int pagesize)
        {
            var ret = _andonProcessRepository.GetAndonProcessData(name, ProjectId, page, pagesize);
            return new PagedObjectResult(ret.Data, ret.Total);
        }
        /// <summary>
        /// 新增消息通知流程
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AddProcessData([FromBody]RequestAndonProcess req)
        {
            //异常拦截
            if (req.ProcessLevel == null || !req.ProcessLevel.Any())
            {
                throw new BadRequestException(TpmEnum.ProcessLevelNull);
            }
            if (req.ProcessTime == null || !req.ProcessTime.Any())
            {
                throw new BadRequestException(TpmEnum.ProcessTimeNull);
            }
            var check = _andonProcessRepository.Get(f => f.name.Equals(req.name) && f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid);
            if (check != null)
            {
                throw new BadRequestException(CommonEnum.RecordExits);
            }
            //实体填写
            var code = IdHelper.Generate<string>();
            var model = Mapper<RequestAndonProcess, siger_andon_process>.Map(req);
            model.projectid = ProjectId;
            model.code = code;
            model.creator = UserId;
            _andonProcessRepository.Insert(model);
            //上报时间
            foreach (var item in req.ProcessTime)
            {
                _planReportRepository.Insert(new siger_project_plan_report
                {
                    space_time = item.space_time,
                    create_mid = UserId,
                    create_time = UnixTimeHelper.GetNow(),
                    start_level = item.start_level,
                    end_level = item.end_level,
                    mode = 0,
                    type = item.type,
                    projectid = ProjectId,
                    process_code = code
                });
            }
            //上报岗位
            foreach (var item in req.ProcessLevel)
            {
                if (item.usergroup != null && item.usergroup.Any())
                {
                    foreach (var user in item.usergroup)
                    {
                        _planReportLevelRepository.Insert(new siger_project_plan_report_level
                        {
                            level = item.level,
                            mode = 0,
                            project_id = ProjectId,
                            usergroup_id = user,
                            process_code = code
                        });
                    }
                }
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 修改消息通知流程
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ModifyProcessData([FromBody]RequestAndonProcess req)
        {
            //异常拦截
            if (req.ProcessLevel == null || !req.ProcessLevel.Any())
            {
                throw new BadRequestException(TpmEnum.ProcessLevelNull);
            }
            if (req.ProcessTime == null || !req.ProcessTime.Any())
            {
                throw new BadRequestException(TpmEnum.ProcessTimeNull);
            }
            var model = _andonProcessRepository.Get(f => f.code.Equals(req.code) && f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid);
            if (model == null)
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            //实体填写
            var code = model.code;
            model.name = req.name;
            model.repeattime = req.repeattime;
            model.remark = req.remark;
            _andonProcessRepository.Update(model);
            //上报时间
            var reportData = _planReportRepository.GetList(f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid && f.process_code.Equals(code));
            if (reportData != null && reportData.Any())
            {
                foreach (var item in reportData)
                {
                    item.status = (int)RowState.Invalid;
                    _planReportRepository.Update(item);
                }
            }
            foreach (var item in req.ProcessTime)
            {
                _planReportRepository.Insert(new siger_project_plan_report
                {
                    space_time = item.space_time,
                    create_mid = UserId,
                    create_time = UnixTimeHelper.GetNow(),
                    start_level = item.start_level,
                    end_level = item.end_level,
                    mode = 0,
                    type = item.type,
                    projectid = ProjectId,
                    process_code = code
                });
            }
            //上报岗位
            var levelData = _planReportLevelRepository.GetList(f => f.project_id.Equals(ProjectId) && f.status == (int)RowState.Valid && f.process_code.Equals(code));
            if (levelData != null && levelData.Any())
            {
                foreach (var item in levelData)
                {
                    item.status = (int)RowState.Invalid;
                    _planReportLevelRepository.Update(item);
                }
            }
            foreach (var item in req.ProcessLevel)
            {
                if (item.usergroup != null && item.usergroup.Any())
                {
                    foreach (var user in item.usergroup)
                    {
                        _planReportLevelRepository.Insert(new siger_project_plan_report_level
                        {
                            level = item.level,
                            mode = 0,
                            project_id = ProjectId,
                            usergroup_id = user,
                            process_code = code
                        });
                    }
                }
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 删除消息通知流程
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult DeleteProcessData(string code)
        {
            //TODO增加逻辑（限制无法删除的流程）
            if (string.IsNullOrEmpty(code))
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            var expectiontype = _andonExpectionType.Get(f => f.process_code.Equals(code));
            if (expectiontype != null)
            {
                Logger.WriteLineInfo("推送流程已被异常类型绑定,无法删除！");
                throw new BadRequestException(CommonEnum.Fail);
            }
            var model = _andonProcessRepository.Get(f => f.code.Equals(code) && f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid);
            if (model == null)
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            //删除流程
            model.status = (int)RowState.Invalid;
            _andonProcessRepository.Update(model);
            //删除上报岗位
            var levelData = _planReportLevelRepository.GetList(f => f.project_id.Equals(ProjectId) && f.status == (int)RowState.Valid && f.process_code.Equals(code));
            if (levelData != null && levelData.Any())
            {
                foreach (var item in levelData)
                {
                    item.status = (int)RowState.Invalid;
                    _planReportLevelRepository.Update(item);
                }
            }
            //删除上报时间
            var reportData = _planReportRepository.GetList(f => f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid && f.process_code.Equals(code));
            if (reportData != null && reportData.Any())
            {
                foreach (var item in reportData)
                {
                    item.status = (int)RowState.Invalid;
                    _planReportRepository.Update(item);
                }
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 获取异常类型信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetExpectionTypeData([FromBody]RequestExpectionTypeData request)
        {
            var data = _andonExpectionType.GetData(request.name, ProjectId, request.page, request.pagesize);
            var ret = data.Data.ToList();
            foreach (var item in ret)
            {
                #region//找到上级类型
                var names = _andonExpectionType.GetExpectionParent(item.parent, ProjectId).Select(s => s.name).ToList();
                switch (names.Count)
                {
                    case 1:
                        item.first = names[0];
                        item.second = item.title;
                        break;
                    case 2:
                        item.first = names[1];
                        item.second = names[0];
                        item.third = item.title;
                        break;
                    default:
                        item.first = item.title;
                        break;
                }
                #endregion
            }
            return new PagedObjectResult(ret, data.Total);
        }
        /// <summary>
        /// 获取异常类型信息
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetExpectionTypeTree(string name)
        {
            var ret = _andonExpectionType.GetTreeData(name, ProjectId);
            return new ObjectResult(ret);
        }
        /// <summary>
        /// 添加异常类型信息
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AddExpectionTypeData([FromBody]RequestAndonExpection req)
        {
            //异常拦截
            if (string.IsNullOrEmpty(req.name))
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            if (req.level == 1)
            {
                req.parent = 0;
            }
            var data = _andonExpectionType.Get(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId) && f.name.Equals(req.name));
            if (data != null)
            {
                throw new BadRequestException(CommonEnum.RecordExits);
            }
            //实体填写
            var model = Mapper<RequestAndonExpection, siger_andon_expection_type>.Map(req);
            model.projectid = ProjectId;
            _andonExpectionType.Insert(model);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 修改异常类型信息
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ModifyExpectionTypeData([FromBody]RequestAndonExpection req)
        {
            //异常拦截
            if (string.IsNullOrEmpty(req.name))
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            if (req.level == 1)
            {
                req.parent = 0;
            }
            var model = _andonExpectionType.Get(f => f.id.Equals(req.id) && f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid);
            if (req.level != 1)
            {
                var parentmodel = _andonExpectionType.Get(f => f.id.Equals(req.parent) && f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid);
                if (parentmodel==null)
                {
                    throw new BadRequestException(CommonEnum.NoData);
                }
                if (model.level != parentmodel.level + 1)
                {
                    throw new BadRequestException(TpmEnum.ExpectionParentError);
                }
            }
            if (model == null)
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            if (model.id == req.parent )//parentid不能与id相同 并且是父子级关系
            {
                throw new BadRequestException(TpmEnum.ExpectionParentError);
            }
            //实体填写
            model.name = req.name;
            //model.level = req.level;//禁止修改级别
            model.parent = req.parent;
            model.process_code = req.process_code;
            model.usergroup = req.usergroup;
            model.second_usergroup = req.second_usergroup;
            model.errorlevel = req.errorlevel;
            _andonExpectionType.Update(model);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 删除异常类型信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult DeleteExpectionTypeData(int id)
        {
            //TODO增加逻辑（限制无法删除的流程）
            if (id == 0)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var model = _andonExpectionType.Get(f => f.id.Equals(id) && f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid);
            if (model == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            //if (model.level == 1)
            //{
            //    throw new BadRequestException(RequestEnum.AndonExceptionCannotDelete);
            //}
            //检查是否拥有子集
            var son = _andonExpectionType.Get(f => f.parent.Equals(id) && f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid);
            if (son != null)
            {
                throw new BadRequestException(RequestEnum.AndonExceptionCannotDelete);
            }

            //删除流程
            model.status = (int)RowState.Invalid;
            _andonExpectionType.Update(model);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 获取上级类别
        /// </summary>
        /// <param name="parent"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetExpectionTypeByParent(int parent)
        {
            var model = _andonExpectionType.GetList(f => f.level.Equals(parent) && f.projectid.Equals(ProjectId) && f.status == (int)RowState.Valid);
            return new ObjectResult(model);
        }

        /// <summary>
        /// 获取上级类别
        /// </summary>
        /// <param name="parentId"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetExpectionTypeByParentId(int parentId)
        {
            var model = _andonExpectionType.GetList(f => f.parent == parentId && f.projectid == ProjectId && f.status == (int)RowState.Valid);
            return new ObjectResult(model);
        }

        /// <summary>
        /// 获取异常信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetExpectionInfoByid(int id)
        {
            var data = _andonExpectionType.Get(f => f.projectid == ProjectId && f.status != 0 && f.id == id);
            return new ObjectResult(data);
        }
        /// <summary>
        /// 获取安灯自动触发列表设置
        /// </summary>
        /// <param name="page"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(List<ResponseAndonPlan>), 200)]
        public IActionResult GetAndonPlan(int page, int pagesize)
        {
            var now = DateTimeHelper.GetTodayStartTime();
            var ret = new List<ResponseAndonPlan>();
            var entities = _sigerAndonPlan.GetPagedList(page, pagesize, f => f.projectid == ProjectId && f.status != 0);
            foreach (var item in entities.Data)
            {
                var model = Mapper<siger_andon_plan, ResponseAndonPlan>.Map(item);
                model.resttime = Math.Round((double)(model.end - model.start) / 60, 1);//休息时间
                model.creator_name = _projectUserRepository.Get(f => f.mid == model.creator)?.name ?? "";//创建人
                model.machine_name = _projectMachineRepository.Get(f => f.id == model.machine)?.title ?? "";//设备名称
                model.line_name = _projectLevelSectionRepository.Get(f => f.id == model.line && f.projectid == ProjectId && f.status != 0)?.title ?? "";//产线名称
                model.dtstart = now.AddSeconds((double)model.start).ToString(ParameterConstant.TimeFormat);
                model.dtend = now.AddSeconds((double)model.end).ToString(ParameterConstant.TimeFormat);
                ret.Add(model);
            }
            return new PagedObjectResult(ret, entities.Total, page, pagesize);
        }

        /// <summary>
        /// 获取瓶颈工位产线位置
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(List<ResponseLineForAndonPlan>), 200)]
        public IActionResult GetLineForAndonPlan()
        {
            var ret = new List<ResponseLineForAndonPlan>();
            //瓶颈工位
            var mids = _andonStationConfigRepository.GetList(f => f.project_id == ProjectId && f.status != 0 && f.station_type == 1).Select(s => s.machine_id).Distinct().ToList();
            if (!mids.Any())
            {
                return new ObjectResult(ret);
            }
            var machines = _machineAttributionRepository.GetList(f => f.projectid == ProjectId && f.status != 0 && mids.Contains(f.machine)).ToList();
            foreach (var machine in machines)
            {
                var sections = _projectLevelSectionRepository.GetParentLevelSections(machine.station, ProjectId).OrderByDescending(o => o.id);
                if (sections.Count() < 2)
                {
                    continue;
                }
                var temp = sections.ToList();
                ret.Add(new ResponseLineForAndonPlan
                {
                    lineid = temp[1].id,
                    stationid = temp[0].id,
                    machineid = machine.machine,
                    title = temp[1].title + temp[0].title + _projectMachineRepository.Get(f => f.id == machine.machine && f.projectid == ProjectId)?.title ?? ""
                });
            }
            return new ObjectResult(ret);
        }

        /// <summary>
        /// 安灯自动触发列表设置(产线位置不允许修改)
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult SetAndonPlan([FromBody]RequestAndonPlan request)
        {
            var now = DateTimeHelper.GetTodayStartTime();
            request.start = (int)request.dtstart.Subtract(now).TotalSeconds;
            request.end = (int)request.dtend.Subtract(now).TotalSeconds;
            var expectionid = _andonExpectionType.Get(f => f.projectid == ProjectId && f.status != 0 && f.is_passprocess == 1 && f.is_caloee == 0)?.id ?? 0;//计划停机
            if (request.id == 0)
            {
                //重复添加卡控
                //var plandata = _sigerAndonPlan.Get(f => f.machine == request.machine && f.expectionid == expectionid && f.status != 0);
                //if (plandata != null)
                //{
                //    throw new BadRequestException(CommonEnum.RecordExits);
                //}
                var model = Mapper<RequestAndonPlan, siger_andon_plan>.Map(request);
                model.createtime = UnixTimeHelper.GetNow();
                model.projectid = ProjectId;
                model.creator = UserId;
                model.expectionid = expectionid;
                _sigerAndonPlan.Insert(model);
            }
            else
            {
                var model = _sigerAndonPlan.Get(f => f.id == request.id);
                if (model == null)
                {
                    throw new BadRequestException(CommonEnum.RecordNotFound);
                }
                model.createtime = UnixTimeHelper.GetNow();
                model.projectid = ProjectId;
                model.expectionid = expectionid;
                model.content = request.content;
                model.end = request.end;
                model.start = request.start;
                _sigerAndonPlan.Update(model);
                //machine line禁止修改
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 安灯自动触发列表删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult DeleteAndonPlan(int id)
        {
            var model = _sigerAndonPlan.Get(f => f.id == id && f.status != 0);
            if (model == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            model.status = (int)RowState.Invalid;
            _sigerAndonPlan.Update(model);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
    }
}