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

namespace EquipmentApi.Controllers.workordermanage
{
    /// <summary>
    /// 超时工单控制器
    /// </summary>
    [Authorize]
    [ApiVersion("6.0")]
    [Produces("application/json")]
    [Route("api/[controller]")]
    public class WoTimeOutController : BaseController
    {
        private readonly ILogger<WoTimeOutController> _logger;
        private readonly IConfiguration _configuration;
        private readonly ISys_User_AccountRepository _sys_user_accountRepository;
        private readonly IWo_TimeOutRepository _wo_timeoutrepository;
        private readonly IWo_TimeOut_ItemsRepository _wo_timeout_itemsrepository;
        private readonly IWo_EquipmentRunningRepository _wo_equipmentrunningrepository;
        private readonly IWo_Maintain_BaseRepository _wo_maintain_baseRepository;
        private readonly ISys_DictionaryValueRepository _sys_dictonaryvalueRepository;
        private readonly IWo_Order_User_MapRepository _wo_order_user_maprepository;
        private readonly ISignTokenService _signTokenService;
        public WoTimeOutController(
            ILogger<WoTimeOutController> logger,
            IConfiguration configuration,
            ISys_User_AccountRepository sys_user_accountRepository,
            IWo_TimeOut_ItemsRepository wo_timeout_itemsrepository, IWo_TimeOutRepository wo_timeoutrepository,
            IWo_EquipmentRunningRepository wo_equipmentrunningrepository, IWo_Maintain_BaseRepository wo_maintain_baseRepository,
            ISys_DictionaryValueRepository sys_dictonaryvalueRepository,
            IWo_Order_User_MapRepository wo_order_user_maprepository, ISignTokenService signTokenService)
        {
            _logger = logger;
            _configuration = configuration;
            _sys_user_accountRepository = sys_user_accountRepository;
            _wo_timeoutrepository = wo_timeoutrepository;
            _wo_timeout_itemsrepository = wo_timeout_itemsrepository;
            _wo_equipmentrunningrepository = wo_equipmentrunningrepository;
            _wo_maintain_baseRepository = wo_maintain_baseRepository;
            _sys_dictonaryvalueRepository = sys_dictonaryvalueRepository;
            _wo_order_user_maprepository = wo_order_user_maprepository;
            _signTokenService = signTokenService;
        }

        [HttpGet("getlistsbypage")]
        public IActionResult GetListsByPage(string stime, string etime, int wotype = -1, int pageIndex = 1, int pageSize = 10)
        {
            string rolecode = User.Claims.FirstOrDefault(c => c.Type == "RoleCode").Value;
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            int recordCount = 0;
            var result = _wo_timeoutrepository.GetListsByPage(wotype, stime, etime, rolecode, usercode, pageIndex, pageSize, out recordCount);

            var obj = new
            {
                rows = result,
                total = recordCount,
            };
            return Success("获取成功", obj);
        }
        [HttpGet("getdetailes")]
        public async Task<IActionResult> GetDetailsAsync(string id, int channelcode = 0)
        {
            //操作人
            string usercode = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            if (string.IsNullOrEmpty(id))
                return Error("参数错误");
            var model = await _wo_timeoutrepository.GetSingle(id);
            if (model != null)
            {
                #region 标记消息提醒工单（消息提醒，App推送）
                if (channelcode > 0)
                {
                    //维修工单号
                    var listmap = await _wo_order_user_maprepository.Get(x => x.woid == model.id && x.wocode == model.wocode && x.channelcode == channelcode && x.readby == usercode);
                    var modelmap = listmap.FirstOrDefault();
                    if (modelmap == null)
                    {
                        //添加是否已读关系表
                        modelmap = new Wo_Order_User_Map();
                        modelmap.wocode = model.wocode;
                        modelmap.woid = model.id;
                        modelmap.readby = usercode;
                        modelmap.channelcode = channelcode;   //工单类型（枚举EnumOrderState） 维修工单 = 1, 保养工单 = 2, 运行工单 = 3, 超时工单 = 4
                        modelmap.isread = 1;
                        modelmap.isnotice = 1;
                        modelmap.readtime = DateTime.Now.ToLocalTime();
                        modelmap.note = model.timeoutreason;
                        bool b = await _wo_order_user_maprepository.Add(modelmap);
                    }
                    else
                    {
                        modelmap.isread = 1;
                        modelmap.isnotice = 1;
                        modelmap.note = model.timeoutreason;
                        bool b = await _wo_order_user_maprepository.UpdateOne(modelmap);
                    }
                }
                #endregion
            }
            return Success("获取成功！", model);
        }
        /// <summary>
        /// 添加超时工单
        /// </summary>
        [AllowAnonymous]
        [HttpPost("save")]
        public async Task<IActionResult> AddAsync(int wotype)
        {
            var res = true;
            //根据类型检索超时工单，任何进行添加超时工单
            #region
            if (wotype == (int)EnumWoType.inspection)
            {
                #region 巡检工单
                var result = _wo_equipmentrunningrepository.GetLists();
                #region 遍历计算是否超时
                foreach (var item in result)
                {
                    var newModel = new WoTimeOutInput();
                    newModel.woid = item.id;
                    newModel.wotype = wotype;
                    newModel.wocode = item.wocode;
                    //newModel.touser = item.checkby;
                    newModel.touser = new List<string> { item.checkby };
                    #region 判断是否维修工
                    //var touserstr = _signTokenService.GetUserInfoAsync(item.checkby).Result;
                    //var toresult = touserstr.ToJObject();
                    //if (toresult["state"].ToString() == "success")
                    //{
                    //    var touserinfo = toresult["data"].ToString().ToObject<UserInfoModel>();
                    //    if (touserinfo.level == 1)
                    //    {
                    //        newModel.tousername = new List<string> { touserinfo.username };
                    //    }
                    //}

                    
                    var userinfos = _sys_user_accountRepository.GetUserInfo(item.checkby);
                    var touserinfo = JsonHelper.JsonToEntity<UserAccountInfoModel>(userinfos.ToJson());
                    if (touserinfo != null)
                    {
                        if (touserinfo.level == 1)
                        {
                            newModel.tousername = new List<string> { touserinfo.username };
                        }
                    }
                    #endregion
                    
                    #region 超时时长
                    if (item.wostate == (int)EnumEquipmentRunningState.deal || item.wostate == (int)EnumEquipmentRunningState.hangup)
                    {
                        if (item.dealtime > item.endtime)
                            newModel.times = (int)(item.dealtime - item.endtime).TotalSeconds;
                        else
                            continue;
                        newModel.isover = true;
                    }
                    else
                    {
                        if (DateTime.Now > item.endtime)
                            newModel.times = (int)(DateTime.Now - item.endtime).TotalSeconds;
                        else
                            continue;
                    }
                    #endregion
                    #region 根据工单Id 查询是否存在超时工单
                    var model = await _wo_timeoutrepository.GetSingle(t => t.woid == item.id);
                    if (model != null)
                        newModel.id = model.id;
                    #endregion
                    res &= await addtimeoutAsync(newModel, 0);
                }
                #endregion
                #endregion
            }
            if (wotype == (int)EnumWoType.maintain)
            {
                #region 保养工单
                var result = _wo_maintain_baseRepository.GetLists();
                #region 遍历计算是否超时
                foreach (var item in result)
                {
                    var newModel = new WoTimeOutInput();
                    newModel.woid = item.id;
                    newModel.wotype = wotype;
                    newModel.wocode = item.wocode;
                    //newModel.touser = item.maintainman;
                    newModel.touser = item.maintainuser;
                    newModel.tousername = item.maintainusername;
                    #region 超时时长
                    if (item.wostate == (int)EnumEquipmentRunningState.deal || item.wostate == (int)EnumEquipmentRunningState.hangup)
                    {
                        if (item.dealtime > item.endtime)
                            newModel.times = (int)(item.dealtime - item.endtime).TotalSeconds;
                        else
                            continue;
                        newModel.isover = true;
                    }
                    else
                    {
                        if (DateTime.Now > item.endtime)
                            newModel.times = (int)(DateTime.Now - item.endtime).TotalSeconds;
                        else
                            continue;
                    }
                    #endregion
                    #region 根据工单Id 查询是否存在超时工单
                    var model = await _wo_timeoutrepository.GetSingle(t => t.woid == item.id);
                    if (model != null)
                        newModel.id = model.id;
                    #endregion
                    res &= await addtimeoutAsync(newModel, 0);
                }
                #endregion
                #endregion
                
            }
            #endregion
            if (res)
                return Success("超时工单保存成功");
            else
                return Error("超时工单保存失败");
        }
        /// <summary>
        /// 提交超时原因
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("upreason")]
        public async Task<IActionResult> UpdateReasonAsync(WoTimeOutInput input)
        {
            var res = false;
            input.manager = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value;
            res = await addtimeoutAsync(input, 1);
            if (res)
                return Success("超时原因保存成功");
            else
            {
                return Error("超时原因保存失败");
            }
        }

        #region 保存超时工单
        private async Task<bool> addtimeoutAsync(WoTimeOutInput input,int type)
        {
            var clmodel = new Wo_TimeOut();
            int opttype = (int)EnumWoOptType.auto;
            int grade = (int)EnumWoGrade.auto;//自动识别
            
            #region 识别等级
            var dicmodel = await _sys_dictonaryvalueRepository.GetSingle(s => s.dictionarycode.Equals("GDCSSC"));
            var cssc = dicmodel.name.Split('|');
            if (cssc.Length > 0 & cssc.Length == 3)
            {
                if (input.times >= int.Parse(cssc[0]) * 60 & input.times < int.Parse(cssc[1]))
                    grade = (int)EnumWoGrade.manager;//上报主管
                else if(input.times >= int.Parse(cssc[1]) * 60 & input.times < int.Parse(cssc[2]))
                    grade = (int)EnumWoGrade.director;//上报经理
                else if(input.times >= int.Parse(cssc[2]))
                    grade = (int)EnumWoGrade.party;//上报甲方
            }
            #endregion
            var res = false;
            string remark = "超时等级：" + input.grade;
            #region 保存超时工单
            if (!string.IsNullOrWhiteSpace(input.id))
            {
                #region 已存在超时工单，修改
                clmodel = await _wo_timeoutrepository.GetSingle(input.id);
                if (clmodel != null)
                {
                    clmodel.touser = input.touser;
                    clmodel.times = input.times;
                    clmodel.isover = input.isover;
                    clmodel.grade = grade;
                    if (type == 1)
                    {
                        #region 提交超时原因
                        opttype = (int)EnumWoOptType.person;
                        clmodel.manager = input.manager;
                        clmodel.timeoutreason = input.timeoutreason;
                        clmodel.istimeout = input.istimeout;
                        remark = "超时等级：" + clmodel.grade + ",确认是否超时：" + (input.istimeout==2 ? "否": "是") + ",超时原因：" + input.timeoutreason;
                        #endregion
                    }
                    res = await _wo_timeoutrepository.UpdateOne(clmodel);
                }
                #endregion
            }
            else
            {
                #region 不存在超时工单，添加
                clmodel.id = ObjectId.GenerateNewId().ToString();
                clmodel.woid = input.woid;
                clmodel.wocode = input.wocode;
                clmodel.touser = input.touser;
                clmodel.wotype = input.wotype;
                clmodel.isover = input.isover;
                clmodel.times = input.times;
                clmodel.grade = grade;
                clmodel.createtime = DateTime.Now;
                clmodel.isdelete = false;
                res = await _wo_timeoutrepository.Add(clmodel);
                remark = "超时工单添加记录," + remark;
                #endregion
            }
            #endregion
            if (res)
            {
                additems(clmodel.id, opttype, remark, input.manager, clmodel.times);
            }
            return res;
        }
        #endregion
        #region 增加超时记录
        /// <summary>
        /// 增加超时记录
        /// </summary>
        /// <param name="toid"></param>
        /// <param name="opttype"></param>
        /// <param name="remark"></param>
        /// <param name="usercode"></param>
        private void additems(string toid,int opttype,string remark,string usercode,int times=0)
        {
            var itemmodel = new Wo_TimeOut_Items();
            itemmodel.wotoid = toid;
            itemmodel.opttype = opttype;
            itemmodel.optremark = remark;
            itemmodel.createby = usercode;
            itemmodel.times = times;
            itemmodel.createtime = DateTime.Now;
            _wo_timeout_itemsrepository.Add(itemmodel);
        }
        #endregion
    }
}