using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
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.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.Repository.Repositories.Interface;
using Siger.Middlelayer.Dapper.Data;
using Siger.ApiCommon.Utilities;
using Siger.Middlelayer.Common.AppSettings;
using System.IO;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;
using System.Text;
using System.Net.Http;
using Newtonsoft.Json;
using Siger.Middlelayer.Repository.Response;

namespace Siger.ApiTPM.Controllers
{
    public class OutsourcedMaintenanceController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IProjectOutsourcedMaintenanceRepository _outsourcedMaintenanceRepository;
        private readonly ISigerProjectEmailConfig _emailConfig;
        private readonly ISigerProjectUserRepository _userRepository;
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly ISigerProjectMachineRepository _machineRepository;

        public OutsourcedMaintenanceController(IUnitOfWork unitOfWork, IProjectOutsourcedMaintenanceRepository outsourcedMaintenanceRepository, ISigerProjectEmailConfig emailConfig
            ,ISigerProjectUserRepository userRepository,IHttpClientFactory httpClientFactory,ISigerProjectMachineRepository machineRepository)
        {
            _unitOfWork = unitOfWork;
            _outsourcedMaintenanceRepository = outsourcedMaintenanceRepository;
            _emailConfig = emailConfig;
            _userRepository = userRepository;
            _httpClientFactory = httpClientFactory;
            _machineRepository = machineRepository;
        }
        /// <summary>
        /// 添加/修改委外维修管理
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult SetOutsourcedMaintenance([FromBody] RequestAddProjectOutsourcedMaintenance request)
        {
            if (request.id != 0)
            {
                var model = _outsourcedMaintenanceRepository.Get(f => f.ProjectId == ProjectId && f.status != 0 && f.id == request.id);
                if (model == null)
                {
                    throw new BadRequestException(CommonEnum.NoData);
                }
                if (model.State != 3 && model.State != 0)
                {
                    throw new BadRequestException(CommonEnum.NoData);
                }
                model.Editor = UserId;
                model.EditTime = UnixTimeHelper.GetNow();
                model.RepairTime = request.RepairTime;
                model.MachineId = request.MachineId;
                model.Price = request.Price;
                model.ProcessId = request.ProcessId;
                model.State = 0;
                model.Supplier = request.Supplier;
            }
            else
            {
                _outsourcedMaintenanceRepository.Insert(new ProjectOutsourcedMaintenanceEntity
                {
                    ProjectId = ProjectId,
                    CreateTime = DateTime.Now,
                    Creator = UserId,
                    Editor = UserId,
                    EditTime = UnixTimeHelper.GetNow(),
                    RepairTime = request.RepairTime,
                    MachineId = request.MachineId,
                    OrderNo = IdHelper.Generate<string>(),
                    Price = request.Price,
                    ProcessId = request.ProcessId,
                    State = 0,
                    Supplier = request.Supplier
                });
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 查询委外维修管理
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType(typeof(ResponseProjectOutsourcedMaintenance))]
        [HttpPost]
        public IActionResult GetOutsourcedMaintenance([FromBody] RequestProjectOutsourcedMaintenance request)
        {
            request.projectId = ProjectId;
            var ret = _outsourcedMaintenanceRepository.GetPagedList(request);
            if (request.toExcel.ToInt() == 1)
            {
                return ExportOutsourcedMaintenance(ret.Data);
            }
            return new PagedObjectResult(ret.Data, ret.Total, request.Page, request.PageSize);
        }
        /// <summary>
        /// 委外维修审核查询
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType(typeof(ResponseProjectOutsourcedMaintenance))]
        [HttpPost]
        public IActionResult GetOutsourcedMaintenanceForSubmit([FromBody] RequestProjectOutsourcedMaintenance request)
        {
            request.projectId = ProjectId;
            request.toExcel = "1";
            //filtter mid
            var processData = GetProcessidsByMid(request.mid.ToInt());
            if (!string.IsNullOrEmpty(request.mid))
            {
                request.processId = string.Join(',', processData.Select(s => s.processid));
            }
            var data = _outsourcedMaintenanceRepository.GetPagedList(request);
            var ret = new List<ResponseProjectOutsourcedMaintenance>();
            foreach (var item in data.Data)
            {
                if (!processData.Any(f => f.processid == item.ProcessId && f.step == item.CurrentLevel))
                {
                    continue;
                }
                ret.Add(item);
            }
            return new ObjectResult(ret);
        }

        private IActionResult ExportOutsourcedMaintenance(IEnumerable<ResponseProjectOutsourcedMaintenance> data)
        {
            if (!data.Any())
            {
                throw new BadRequestException(CommonEnum.NoDataForExport);
            }
           
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            var temporaryFileName = $"OutsourcedMaintenance_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileName = Path.Combine(rootDir, temporaryFileName);

            var helper = new EpPlusExcelHelper<ImportOutsourcedMaintenance>();
            try
            {
                var models = new List<ImportOutsourcedMaintenance>();
                var no = 1;
                foreach (var item in data)
                {
                    var model = Mapper<ResponseProjectOutsourcedMaintenance, ImportOutsourcedMaintenance>.Map(item);
                    model.No = no++;
                    model.RepairTime = UnixTimeHelper.ConvertStringDateTime(item.RepairTime.ToStr()).ToString(UnixTimeHelper.DateFormat);
                    model.StateName = item.State == 0 ? "未审核" : item.State == 1 ? "审核中" : item.State == 2 ? "已审核" : item.State == 3 ? "审核不通过" : "";
                    models.Add(model);
                }
                helper.GenerateExcel(models, fileName);
                return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ExportOutsourcedMaintenance failed, error: " + e.Message);
                throw new BadRequestException(RequestEnum.ExportFailed);
            }
            finally
            {
                helper.Dispose();
            }
        }
        /// <summary>
        /// 审核/驳回 接口
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult SubmitOutsourcedMaintenance([FromBody] RequestSubmitProjectOutsourcedMaintenance request)
        {
            if (string.IsNullOrEmpty(request.ids))
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            var ids = request.ids.Split(',');
            var entities = _outsourcedMaintenanceRepository.GetList(f => f.ProjectId == ProjectId && f.status != 0 && ids.Contains(f.id.ToStr())).ToList();
            if (!entities.Any())
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            var state = request.state.ToInt();

            entities.ForEach(item =>
            {
                var sb = new StringBuilder();
                sb.Append("尊敬的XXX：");
                sb.Append($"     【{_machineRepository.GetMachineAndSectionName(item.MachineId,ProjectId)}】委外维修工单 已提交进入审核流程，请您尽快完成审批。\r\n");
                sb.Append($"     提交人：{_userRepository.Get(f => f.projectid == ProjectId && f.status != 0 && f.mid == item.Editor)?.name ?? ""} \r\n");
                sb.Append($"     提交时间：{UnixTimeHelper.ConvertStringDateTime(item.EditTime.ToStr()).ToString(UnixTimeHelper.DateTimeFormat)} \r\n");

                item.State = state;
                if (state == 3)//驳回
                {
                    item.CurrentLevel = 0;
                }
                else
                {
                    item.CurrentLevel += 1;
                    var mids = GetMidsByLevel(item.ProcessId, item.CurrentLevel);
                    if (mids.Any())
                    {
                        PushMsg(mids, sb.ToString());
                        item.State = 1;
                    }
                }
                _outsourcedMaintenanceRepository.Update(item);
                //TODO History
            });
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 删除委外维修管理
        /// </summary>
        /// <param name="ids">批量删除用，隔开</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult DelOutsourcedMaintenance(string ids)
        {
            if (string.IsNullOrEmpty(ids))
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            var idList = ids.Split(',');
            var entities = _outsourcedMaintenanceRepository.GetList(f => f.ProjectId == ProjectId && f.status != 0 && idList.Contains(f.id.ToStr())).ToList();
            if (!entities.Any())
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            //TODO 业务Check

            entities.ForEach(item => { item.status = 0; _outsourcedMaintenanceRepository.Update(item); });
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 获取当前层级推送的用户
        /// </summary>
        /// <param name="processId"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        private List<int> GetMidsByLevel(int processId,int level)
        {
            var client = _httpClientFactory.CreateClient("ApiGateway");
            var response = client.GetAsync($"/esop/EsopProcess/GetMidsByLevel?processId={processId}&level={level}");
            var strResult = response.Result.Content.ReadAsStringAsync().Result;
            var result = JsonConvert.DeserializeObject<ResultObject>(strResult);
            if (result.ret == 0)
            {
                return new List<int>();
            }
            else
            {
                return JsonConvert.DeserializeObject<List<int>>(result.data.ToString());
            }
        }
        /// <summary>
        /// 获取该用户所有推送流程Id
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        private List<ResultEsopObject> GetProcessidsByMid(int mid)
        {
            var client = _httpClientFactory.CreateClient("ApiGateway");
            var response = client.GetAsync($"/esop/EsopProcess/GetProcessidsByMid?mid={mid}");
            var strResult = response.Result.Content.ReadAsStringAsync().Result;
            var result = JsonConvert.DeserializeObject<ResultObject>(strResult);
            if (result.ret == 0)
            {
                return new List<ResultEsopObject>();
            }
            else
            {
                return JsonConvert.DeserializeObject<List<ResultEsopObject>>(result.data.ToString());
            }
        }
        /// <summary>
        /// 推送消息+发邮件 
        /// </summary>
        private void PushMsg(List<int> mids,string msg)
        {
            //mail
            var Cfg = _emailConfig.Get(f => f.project == ProjectId && f.status == (int)RowState.Valid);
            if (Cfg == null)
            {
                return;
            }
            foreach (var mid in mids)
            {
                var user = _userRepository.Get(f => f.mid==mid && f.status == (int)RowState.Valid);
                if (user == null || string.IsNullOrEmpty(user.work_email))
                {
                    continue;
                }
                msg = msg.Replace("XXX", user.name);
                //Logger.WriteLineInfo($"msg:{msg},work_email:{user.work_email}");
                MailHelper.SendMail(Cfg.server, true, Cfg.send, Cfg.code, "TPM",
                  Cfg.send, user.work_email, "委外维修工单通知", msg, new List<string>());
            }
        }
    }
}