using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using MadRunFabric.Common;
using Microsoft.Extensions.Logging;
using EquipmentApi.IRepositories;
using EquipmentApi.Model.Input;
using MadRunFabric.Model.EquipmentApi.Model;
using System.Security.Claims;
using MadRunFabric.Model;
using MongoDB.Driver;
using Api.SignToken;
using MongoDB.Bson;
using Microsoft.AspNetCore.Authorization;
using MadRunFabric.Model.HangfireApi.Model;
using System.Net.Http;
using System.Threading;
using Microsoft.Extensions.Configuration;

namespace EquipmentApi.Controllers.workordermanage
{
    /// <summary>
    /// 设备运行工单计划
    /// </summary>
    [Authorize]
    [ApiVersion("6.0")]
    [Produces("application/json")]
    [Route("api/[controller]")]
    public class WoEquipmentRunningPlanController : BaseController
    {
        private readonly ILogger<WoEquipmentRunningPlanController> _logger;
        private readonly IConfiguration _configuration;
        private readonly ISys_User_AccountRepository _sys_user_accountRepository;
        private readonly IWo_EquipmentRunningRepository _wo_equipmentrunningrepository;
        private readonly IWo_EquipmentRunning_PlanRepository _wo_equipmentrunning_planrepository;
        private readonly IWo_EquipmentRunning_ItemsRepository _wo_equipmentrunning_itemsrepository;
        private readonly IEqp_Equipment_InfoRepository _eqp_equipment_infoRepository;
        private readonly IHangfireService _hangfireService;
        private readonly IPro_Project_InfoRepository _pro_project_infoRepository;
        private readonly IHangfire_PlanRepository _hangfire_planrepository;
        private readonly IWo_MattersRepository _wo_mattersRepository;
        private readonly ISignTokenService _signTokenService;
        public WoEquipmentRunningPlanController(
            ILogger<WoEquipmentRunningPlanController> logger,
            IConfiguration configuration,
            ISys_User_AccountRepository sys_user_accountRepository,
            IWo_EquipmentRunningRepository wo_equipmentrunningrepository,
            IWo_EquipmentRunning_PlanRepository wo_equipmentrunning_planrepository,
            IWo_EquipmentRunning_ItemsRepository wo_equipmentrunning_itemsrepository,
            IHangfireService hangfireService,
            IEqp_Equipment_InfoRepository eqp_equipment_infoRepository,
            IPro_Project_InfoRepository pro_project_infoRepository,
            IHangfire_PlanRepository hangfire_planrepository,
            ISignTokenService signTokenService,
            IWo_MattersRepository wo_mattersRepository
            )
        {
            _logger = logger;
            _configuration = configuration;
            _sys_user_accountRepository = sys_user_accountRepository;
            _wo_equipmentrunningrepository = wo_equipmentrunningrepository;
            _wo_equipmentrunning_planrepository = wo_equipmentrunning_planrepository;
            _wo_equipmentrunning_itemsrepository = wo_equipmentrunning_itemsrepository;
            _hangfireService = hangfireService;
            _eqp_equipment_infoRepository = eqp_equipment_infoRepository;
            _pro_project_infoRepository = pro_project_infoRepository;
            _hangfire_planrepository = hangfire_planrepository;
            _wo_mattersRepository = wo_mattersRepository;
            _signTokenService = signTokenService;
        }

        /// <summary>
        /// 获取设备运行工单计划列表 - 关联查询
        /// </summary>
        /// <returns></returns>
        [HttpGet("getlistsbypage")]
        public async Task<IActionResult> GetListsByPageAsync(string keyword, string projectid, string stime, string etime, int pageIndex = 1, int pageSize = 10)
        {
            string nowusercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            //var userstr = _signTokenService.GetUserInfoAsync(nowusercode).Result;
            //var userinfo = userstr.ToJObject()["data"].ToString().ToObject<UserInfoModel>();

            
            var userinfos = _sys_user_accountRepository.GetUserInfo(nowusercode);
            var userinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());
            int recordCount = 0;
            var result = _wo_equipmentrunning_planrepository.GetListsByPage(keyword, projectid, stime, etime, nowusercode, userinfo, pageIndex, pageSize, out recordCount);
            var list = result.ToList();
            foreach (var item in list)
            {
                if (!string.IsNullOrWhiteSpace(item.hangfireid))
                {
                    var hfmo = await _hangfire_planrepository.GetSingle(item.hangfireid);
                    if (hfmo != null)
                    {
                        item.plancycle = hfmo.plancycle;
                        item.planinterval = hfmo.planinterval;
                        item.plantimes = hfmo.plantimes;
                        item.extensiontime = hfmo.extensiontime;
                    }
                }
                #region 检查事项
                if (item.matterids != null)
                {
                    string[] mattername = new string[item.matterids.Length];
                    for (int i = 0; i < item.matterids.Length; i++)
                    {
                        var matter = await _wo_mattersRepository.GetSingle(item.matterids[i]);
                        if (matter != null)
                        {
                            mattername[i] = matter.matter;
                        }
                        else
                            mattername[i] = "";
                    }
                    item.matternames = mattername;
                }
                #endregion
                #region
                //if (item.equipmentid != null)
                //{
                //    string[] equname = new string[item.equipmentid.Length];
                //    for (int i = 0; i < item.equipmentid.Length; i++)
                //    {
                //        var eqpmo = await _eqp_equipment_infoRepository.GetSingle(item.equipmentid[i]);
                //        if (eqpmo != null)
                //        {
                //            equname[i] = eqpmo.equipment_name;
                //        }
                //        else
                //            equname[i] = "";
                //    }
                //    item.equipmentname = equname;
                //}
                #endregion
            }
            var obj = new
            {
                rows = list,
                total = recordCount,
            };
            return Success("获取成功", obj);
        }

        /// <summary>
        /// 获取洗涤工单列表计划 - 关联查询
        /// </summary>
        /// <returns></returns>
        [HttpGet("getapplists")]
        public IActionResult GetAppLists(string keyword, string projectid, string stime, string etime)
        {
            var result = _wo_equipmentrunning_planrepository.GetAppLists(keyword, projectid, stime, etime);
            return Success("获取成功", result);
        }

        /// <summary>
        /// 获取设备运行计划详情 by id - 关联查询
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("getdetails")]
        public async Task<IActionResult> GetDetailsAsync(string id)
        {
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = _wo_equipmentrunning_planrepository.GetDetails(id);
            if (model != null)
            {
                if (!string.IsNullOrWhiteSpace(model.hangfireid))
                {
                    var hfmo = await _hangfire_planrepository.GetSingle(model.hangfireid);
                    if (hfmo != null)
                    {
                        model.plancycle = hfmo.plancycle;
                        model.planinterval = hfmo.planinterval;
                        model.plantimes = hfmo.plantimes;
                        model.extensiontime = hfmo.extensiontime;
                    }
                }
                #region 检查事项
                if (model.matterids != null)
                {
                    string[] mattername = new string[model.matterids.Length];
                    for (int i = 0; i < model.matterids.Length; i++)
                    {
                        var matter = await _wo_mattersRepository.GetSingle(model.matterids[i]);
                        if (matter != null)
                            mattername[i] = matter.matter;
                        else
                            mattername[i] = "";
                    }
                    model.matternames = mattername;
                }
                #endregion
                #region
                //if (model.equipmentid != null)
                //{
                //    string[] equname = new string[model.equipmentid.Length];
                //    for (int i = 0; i < model.equipmentid.Length; i++)
                //    {
                //        var eqpmo = await _eqp_equipment_infoRepository.GetSingle(model.equipmentid[i]);
                //        if (eqpmo != null)
                //            equname[i] = eqpmo.equipment_name;
                //        else
                //            equname[i] = "";
                //    }
                //    model.equipmentname = equname;
                //}
                #endregion
                return Success("获取成功！", model);
            }
            return Error("获取失败");
        }

        /// <summary>
        /// 添加设备运行工单计划
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("add")]
        public async Task<IActionResult> AddAsync(WoEquipmentRunningPlanInput input)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;

            if (string.IsNullOrEmpty(input.projectid))
                return Error("项目名称不能为空");
            else
            {
                var pro = await _pro_project_infoRepository.GetSingle(input.projectid);
                if (pro != null)
                {
                    if (pro.isend == 1)
                    {
                        return Error("暂停巡检计划");
                    }
                }
            }
            var model = new Wo_EquipmentRunning_Plan();

            #region 添加计划任务
            model.id = ObjectId.GenerateNewId().ToString();
            model.projectid = input.projectid;
            model.matterids = input.matterids;
            //model.systemid = input.systemid;
            //model.equipmentid = input.equipmentid;
            model.planname = input.planname;
            model.plancontent = input.plancontent;
            model.planstate = input.planstate;
            model.startdate = input.startdate;
            model.enddate = input.enddate;
            if (input.files != null)
            {
                model.files = input.files;
            }
            else
            {
                model.files = new List<FileBaseModel>();
            }
            if (input.extensionlist != null)
            {
                model.extensionlist = input.extensionlist;
            }
            else
            {
                model.extensionlist = new List<ExtensionFileModel>();
            }
            model.createtime = DateTime.Now;
            model.createby = usercode;
            model.isreturnmsg = input.isreturnmsg;
            #endregion
            bool b = await _wo_equipmentrunning_planrepository.Add(model);
            if (b)
            {
                #region 添加设备运行工单
                var planid = await addplan(input, "");
                model.hangfireid = planid;
                await _wo_equipmentrunning_planrepository.UpdateOne(model);
                //_logger.LogError(null, "ceshi2:" + input.ToJson());
                //添加定时计划
                SetTaskAsync(model.id, input.plancycle, input.planinterval, input.plantimes);

                #endregion
                if (DateTime.Now.Date == input.startdate.Date)
                {
                    await addwoAsync(model);
                }
                return Success("添加成功");
            }
            return Error("添加失败");
        }

        /// <summary>
        /// 修改设备运行工单计划
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("update")]
        public async Task<IActionResult> UpdateAsync(WoEquipmentRunningPlanInput input)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            if (string.IsNullOrEmpty(input.projectid))
                return Error("项目名称不能为空");
            else
            {
                var pro = await _pro_project_infoRepository.GetSingle(input.projectid);
                if (pro != null)
                {
                    if (pro.isend == 1)
                    {
                        return Error("暂停巡检计划");
                    }
                }
            }
            var model = new Wo_EquipmentRunning_Plan();
            model = await _wo_equipmentrunning_planrepository.GetSingle(input.id);
            if (model == null)
                return Error("操作失败");
            #region 修改计划任务

            model.projectid = input.projectid;
            model.matterids = input.matterids;
            //model.systemid = input.systemid;
            //model.equipmentid = input.equipmentid;
            model.planname = input.planname;
            model.plancontent = input.plancontent;
            model.planstate = input.planstate;
            model.startdate = input.startdate;
            model.enddate = input.enddate;
            if (input.files != null)
            {
                model.files = input.files;
            }
            else
            {
                model.files = new List<FileBaseModel>();
            }
            if (input.extensionlist != null)
            {
                model.extensionlist = input.extensionlist;
            }
            else
            {
                model.extensionlist = new List<ExtensionFileModel>();
            }
            model.isreturnmsg = input.isreturnmsg;
            #endregion
            bool b = await _wo_equipmentrunning_planrepository.UpdateOne(model);
            if (b)
            {
                await addplan(input, model.hangfireid);
                SetTaskAsync(model.id, input.plancycle, input.planinterval, input.plantimes);
                return Success("修改成功");
            }
            return Error("修改失败");
        }

        /// <summary>
        /// 删除设备运行工单计划
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpPost("delete")]
        public async Task<IActionResult> RemoveAsync(string[] ids)
        {
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            //使用逻辑删除
            //物理删除的数据无法恢复
            var res = 0;
            if (ids != null && ids.Length > 0)
            {
                foreach (var item in ids)
                {
                    var ml = await _wo_equipmentrunning_planrepository.GetSingle(item);
                    ml.isdelete = -1;
                    ml.deleteby = usercode;
                    ml.deletetime = DateTime.Now;
                    if (await _wo_equipmentrunning_planrepository.UpdateOne(ml))
                    {
                        #region 查询此计划是否有未执行的工单，若有一并删除
                        var rl = await _wo_equipmentrunningrepository.Get(r => r.planid.Equals(item) && r.wostate == (int)EnumEquipmentRunningState.create);
                        if (rl.Count() > 0)
                        {
                            foreach (var itemrun in rl)
                            {
                                itemrun.isdelete = -1;
                                itemrun.dealby = usercode;
                                itemrun.dealtime = DateTime.Now;
                                await _wo_equipmentrunningrepository.UpdateOne(itemrun);
                            }
                        }
                        #endregion
                        removeTask(ml.id);
                        res += 1;
                    }
                }
                if (res == ids.Length)
                    return Success("删除成功");
                else if (res > 0 && res < ids.Length)
                    return Error("部分删除失败，请查看后重新操作");
                else
                    return Error("删除失败，请查看后重新操作");
            }
            else
                return Error("请选择要删除的记录");
        }

        /// <summary>
        /// 启动计划
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost("start")]
        public async Task<IActionResult> StartAsync(string[] ids)
        {
            var res = 0;
            if (ids != null && ids.Length > 0)
            {
                try
                {
                    foreach (var item in ids)
                    {
                        var ml = await _wo_equipmentrunning_planrepository.GetSingle(item);
                        ml.planstate = 0;
                        if (await _wo_equipmentrunning_planrepository.UpdateOne(ml))
                        {
                            var hl = await _hangfire_planrepository.GetSingle(ml.hangfireid);

                            SetTaskAsync(item, hl.plancycle, hl.planinterval, hl.plantimes);
                            res += 1;
                        }
                    }
                    if (res == ids.Length)
                        return Success("操作成功");
                    else if (res > 0 && res < ids.Length)
                        return Error("部分操作失败，请查看后重新操作");
                    else
                        return Error("操作失败，请查看后重新操作");
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "启动巡检计划异常");
                    return Error("启动巡检计划失败");
                }
            }
            else
                return Error("请选择要操作的记录");
        }

        /// <summary>
        /// 中止计划
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost("stop")]
        public async Task<IActionResult> StopAsync(string[] ids)
        {
            var res = 0;
            if (ids != null && ids.Length > 0)
            {
                try
                {
                    foreach (var item in ids)
                    {
                        var ml = await _wo_equipmentrunning_planrepository.GetSingle(item);
                        ml.planstate = 1;
                        if (await _wo_equipmentrunning_planrepository.UpdateOne(ml))
                        {
                            removeTask(ml.id);
                            res += 1;
                        }
                    }
                    if (res == ids.Length)
                        return Success("操作成功");
                    else if (res > 0 && res < ids.Length)
                        return Error("部分操作失败，请查看后重新操作");
                    else
                        return Error("操作失败，请查看后重新操作");
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "中止巡检计划异常");
                    return Error("中止巡检计划失败");
                }
            }
            else
                return Error("请选择要操作的记录");
        }

        #region 保存计划任务
        private async Task<string> addplan(WoEquipmentRunningPlanInput input, string planid)
        {
            var model = new HangfirePlan();
            if (!string.IsNullOrWhiteSpace(planid))
            {
                model = await _hangfire_planrepository.GetSingle(planid);
            }
            else
            {
                model.id = ObjectId.GenerateNewId().ToString();
                model.wotype = (int)EnumWoType.inspection;

                model.createby = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
                model.createtime = DateTime.Now;
                model.isdelete = 0;
                //bool b = await _hangfire_planrepository.Add(model);
            }
            model.plantype = (int)enummainplantype.timing;
            model.plancycle = input.plancycle;
            model.plantimes = input.plantimes;
            model.planinterval = input.planinterval;
            model.planstate = input.planstate;
            model.extensiontime = input.extensiontime;
            var b = false;
            if (string.IsNullOrWhiteSpace(planid))
                b = await _hangfire_planrepository.Add(model);
            else
                b = await _hangfire_planrepository.UpdateOne(model);

            if (b)
                return model.id;
            else
                return "";
        }
        #endregion
        #region 删除计划
        private void removeTask(string id)
        {
            _hangfireService.RemovePlan(id);
        }
        #endregion
        #region 设置定时任务
        private void SetTaskAsync(string planid, int plancycle, int planinterval, int plantimes)
        {
            _logger.LogError("WoEquipmentRunningPlanController/SetTask start");
            _hangfireService.AddWoEquipmentRunning(planid, plancycle, planinterval, plantimes);
        }
        #endregion
        #region 添加工单
        public async Task<bool> addwoAsync(Wo_EquipmentRunning_Plan planmodel)
        {
            int res = 0; int count = 0;
            var hangfiremodel = await _hangfire_planrepository.GetSingle(planmodel.hangfireid);
            var model = new Wo_EquipmentRunning();
            #region 基本信息
            model.woname = planmodel.planname;
            model.wocontent = planmodel.plancontent;
            model.projectid = planmodel.projectid;
            model.matterids = planmodel.matterids;
            //model.systemid = planmodel.systemid;
            //model.equipmentid = planmodel.equipmentid;
            model.planid = planmodel.id;    //巡检计划id
            model.extensionlist = planmodel.extensionlist;    //默认值[]

            model.isdelete = 0;
            model.checkpic = new List<FileBaseModel>();
            #endregion
            #region 获取上一次巡检信息
            var sort = Builders<Wo_EquipmentRunning>.Sort.Descending("createtime");
            var dModel = await _wo_equipmentrunningrepository.GetSingle(s => s.planid.Equals(planmodel.id) & s.isdelete == 0, sort);
            if (dModel != null)
            {
                model.lastchecktime = dModel.lastchecktime;
                model.lastcheckresultid = dModel.lastcheckresultid;
            }
            #endregion

            if (hangfiremodel != null)
            {
                foreach (var item in hangfiremodel.extensiontime)
                {
                    Thread.Sleep(500);
                    model.id = ObjectId.GenerateNewId().ToString();
                    //model.wocode = DateTime.Now.ToString("yyMMddHHmmssffffff");
                    model.wocode = UniqueData.Gener("", 2);
                    model.wodate = DateTime.Now.ToString("yyyy-MM-dd");
                    model.starttime = DateTime.Parse(DateTime.Now.AddDays(item.startdate - 1).ToString("yyyy-MM-dd") + " " + item.starttime.ToString("HH:mm"));
                    model.endtime = DateTime.Parse(DateTime.Now.AddDays(item.enddate - 1).ToString("yyyy-MM-dd") + " " + item.endtime.ToString("HH:mm"));
                    model.createtime = DateTime.Now;
                    //开始时间小于当前时间不创建工单
                    if (model.starttime < DateTime.Now)
                    { continue; }
                    if (await _wo_equipmentrunningrepository.Add(model))
                    {
                        AddItems(model.id, model.wocode, (int)EnumEquipmentRunningState.create, 0, 0, "", "", "创建工单", "");
                        res += 1;
                    }
                    count++;
                }
            }
            if (res == count && res > 0)
            {
                _logger.LogError("即时添加工单成功，工单名称：" + planmodel.planname + "，工单内容：" + planmodel.plancontent + ",添加了" + count + "条工单");
                return true;
            }
            else
            {
                _logger.LogError("即时添加工单失败，工单名称：" + planmodel.planname + "，工单内容：" + planmodel.plancontent + ",添加了" + count + "条工单");
                return false;
            }
        }
        /// <summary>
        /// 添加工单记录
        /// </summary>
        /// <param name="wocode">工单编号</param>
        /// <param name="wostate">工单状态</param>
        /// <param name="ishasten">是否催办（0不催办1催办）</param>
        /// <param name="islast">是否最后一步 0否 1是</param>
        /// <param name="touser">指派下一步人员</param>
        /// <param name="todept">指派下一步部门</param>
        /// <param name="detail">处理说明</param>
        /// <param name="usercode">当前操作人</param>
        private async void AddItems(string woid, string wocode, int wostate, int ishasten, int islast, string touser, string todept, string detail, string usercode)
        {
            try
            {
                #region 更新流程
                if (wostate > 0)
                {
                    var list = await _wo_equipmentrunning_itemsrepository.Get(Builders<Wo_EquipmentRunning_Items>.Filter.Eq("woid", woid), null, Builders<Wo_EquipmentRunning_Items>.Sort.Descending("createtime"));
                    if (list.Count() > 0)
                    {
                        var itemmodel = list.FirstOrDefault();
                        itemmodel.sureuser = usercode;
                        itemmodel.suretime = DateTime.Now;
                        itemmodel.itemstate = 1;
                        itemmodel.islast = islast;
                        await _wo_equipmentrunning_itemsrepository.UpdateOne(itemmodel);
                    }
                }
                #endregion
                #region 添加下一步明细
                var model = new Wo_EquipmentRunning_Items();
                model.woid = woid;
                model.wocode = wocode;
                model.wostate = wostate;
                model.itemstate = 0;
                model.isdelete = 0;
                model.createby = usercode;
                model.createtime = DateTime.Now;
                model.detail = detail;
                model.islast = islast;
                if (wostate < (int)EnumEquipmentRunningState.deal)
                {
                    model.ishasten = ishasten;
                    #region 创建、转派、抢单
                    model.touser = touser;
                    model.todept = todept;
                    #endregion
                }
                else if (wostate == (int)EnumEquipmentRunningState.deal)
                {
                    #region 结单
                    model.dealtime = DateTime.Now;
                    model.dealuser = usercode;
                    #endregion
                }
                await _wo_equipmentrunning_itemsrepository.Add(model);
                #endregion
            }
            catch (Exception ex)
            {
                _logger.LogDebug("工单日志记录异常", ex);
            }
        }
        #endregion
    }
}