using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Exceptions;
using Siger.ApiCommon.Result;
using Siger.ApiCommon.Utilities;
using Siger.ApiTPM.Result;
using Siger.ApiTPM.Utilities;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.AppSettings;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Data.Tpm;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Response;
using Siger.Middlelayer.TpmRepository.Repositories.Interface;
using Siger.Middlelayer.TpmRepository.Request;
using Siger.Middlelayer.TpmRepository.Response;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.ApiTPM.Controllers
{
    public class PlanResultController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IPlanRepository _plan;
        private readonly ISparepartRecordRepository _sparepartRecord;
        private readonly ISparepartRepository _sparepart;
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly ISigerProjectUserRepository _userRepository;
        private readonly IPlanTimeRepository _planTimeRepository;
        private readonly IPlanRecordRepository _recordRepository;

        public PlanResultController(IUnitOfWork unitOfWork, IPlanRepository plan, ISparepartRecordRepository sparepartRecord,
            ISparepartRepository sparepart, ISigerProjectMachineRepository machineRepository,
            ISigerProjectUserRepository userRepository, IPlanTimeRepository planTimeRepository,
            IPlanRecordRepository recordRepository)
        {
            _unitOfWork = unitOfWork;
            _plan = plan;
            _sparepartRecord = sparepartRecord;
            _sparepart = sparepart;
            _machineRepository = machineRepository;
            _userRepository = userRepository;
            _planTimeRepository = planTimeRepository;
            _recordRepository = recordRepository;
        }

        [HttpPost]
        public IActionResult GetlistPlanResultItem([FromBody]RequestPlanResult res)
        {
            long stime = 0;
            long etime = 0;
            if (!string.IsNullOrWhiteSpace(res.start_time))
            {
                var success = DateTime.TryParse(res.start_time, out var dtStart);
                if (!success)
                {
                    throw new ServerException(500146);
                }
                stime = UnixTimeHelper.ConvertDataTimeLong(dtStart);
            }

            if (!string.IsNullOrWhiteSpace(res.end_time))
            {
                var success = DateTime.TryParse(res.end_time, out var dtEnd);
                if (!success)
                {
                    throw new ServerException(500146);
                }
                etime = UnixTimeHelper.ConvertDataTimeLong(dtEnd);
            }

            //获取设备ids
            var machineIds = _machineRepository.GetAttributionMachineIds(res.sectionid, ProjectId);
            if (!machineIds.Any())
            {
                if (res.toexcel == 0)
                {
                    return new PagedObjectResult(new List<GetListSearchPlan>(), 0, res.page, res.pagesize);
                }
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var req = _plan.GetlistPlanResultItem(machineIds, res.mode, (int)stime, (int)etime, res.severity_level.ToInt(), ProjectId, res.page, res.pagesize, res.toexcel);

            foreach (var plan in req.Data)
            {
                plan.machinetitle = _plan.GetMachineParentName(plan.machineid, ProjectId);
            }
            if (res.toexcel == 0)
            {
                return new PagedObjectResult(req.Data, req.Total, res.page, res.pagesize);
            }

            return ExportData(req.Data);
        }

        private IActionResult ExportData(IEnumerable<GetListSearchPlan> list)
        {
            var now = UnixTimeHelper.GetNow();
            
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);

            var temporaryFileName = $"MaintenanceResult_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileName = Path.Combine(rootDir, temporaryFileName);

            var helper = new EpPlusExcelHelper<PlanResultList>();
            try
            {
                var responses = new List<PlanResultList>();
                foreach (var record in list)
                {
                    var corepair = "";
                    var actualtime = 0;
                    var itemdata = _plan.GetlistPlanOneResultItem(record.id, 0, 0, ProjectId).ToList();
                    if (itemdata.Any())
                    {
                        actualtime = itemdata.Sum(s => s.standard_time);
                        var mids = new List<string>();
                        var midsList = itemdata.Where(f => f.mids.Any()).Select(s => s.mids).ToList();
                        foreach (var i in midsList)
                        {
                            mids.AddRange(i);
                        }
                        mids = mids.Distinct().ToList();
                        var names = _userRepository.GetList(f => mids.Contains(f.mid.ToStr())).Select(s => s.name).Distinct().ToList();
                        if (names.Any())
                        {
                            corepair = string.Join(',', names);
                        }
                    }
                    //record.id
                    var planTimeData = _planTimeRepository.GetList(f => f.status != 0 && f.projectid == ProjectId && f.planid == record.id && (f.instruction_time <= now || f.information == 1), "id").ToList();
                    foreach (var item in planTimeData)
                    {
                        var recordData = _recordRepository.Get(f => f.status != 0 && f.projectid == ProjectId && f.planid == record.id && f.plan_time_id == item.id);
                        var response = new PlanResultList
                        {
                            Up = record.up_limit,
                            Down = record.lower_limit,
                            Content = record.content,
                            Unit = record.unit,
                            Location = record.machinetitle,
                            MaintainType = record.mode == 1 ? "AM" : (record.mode == 2 ? "PM" : "CMP"),
                            Category = GetCategory(record.severity_level),
                            Time = record.standard_time.ToStr(),
                            IsCheck = record.value_type == 1 ? "勾选确定型" : "数值记录型",
                            Name = recordData == null ? "" : _userRepository.Get(f => f.projectid == ProjectId && f.mid == recordData.actual_mid)?.name ?? "",
                            corepair = corepair,
                            Actualtime = actualtime,
                            workorder = "P" + record.id.ToStr(),
                            time = recordData == null ? "" : UnixTimeHelper.ConvertIntDate(recordData.create_time)
                        };
                        responses.Add(response);
                    }
                }

                helper.GenerateExcel(responses, fileName);
                return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
            }
            catch (Exception e)
            {
                Logger.WriteLineError("Export result failed, error: " + e.Message);
                throw new BadRequestException(RequestEnum.ExportFailed);
            }
            finally
            {
                helper.Dispose();
            }
        }

        [HttpPost]
        public IActionResult GetlistPlanOneResultItem([FromBody]RequestGetlistPlanOneResultItem req)
        {
            var ret = new List<GetPlanResult>();
            var now = UnixTimeHelper.GetNow();
            var pid = ProjectId;
            var sparepartHelper = new SparepartHelper(ProjectId, UserId, _sparepartRecord, _sparepart);
            var planData = _plan.Get(f => f.status != 0 && f.projectid == pid && f.id == req.id);
            if (planData == null)
            {
                return new ObjectResult(ret);
            }
            var planTimeData = _planTimeRepository.GetList(f => f.status != 0 && f.projectid == pid && f.planid == req.id && (f.instruction_time <= now || f.information == 1), "id").ToList();
            foreach (var plan in planTimeData)
            {
                var model = new GetPlanResult();
                var start = plan.instruction_time;
                var end = plan.instruction_time + planData.instruction_cycle * 86400;
                model.keep_remark = plan.keep_remark.ToStr();
                model.work_order = $"P{planData.id}";
                model.actualtime = UnixTimeHelper.ConvertIntDate(plan.instruction_time);//原计划
                model.record_code = string.Empty;
                model.corepair = string.Empty;
                model.value = string.Empty;
                var recordData = _recordRepository.Get(f => f.status != 0 && f.projectid == pid && f.planid == req.id && f.plan_time_id == plan.id
                //&& f.create_time >= start && f.create_time < end
                );
                if (recordData != null)
                {
                    //执行人
                    model.name = _userRepository.Get(f => f.projectid == pid && f.mid == recordData.actual_mid)?.name ?? "";
                    model.time = UnixTimeHelper.ConvertIntDate(recordData.create_time);
                    model.value = recordData.value.ToLower() == "true" ? "通过" : "不通过";
                    model.state_name = "已执行";
                    if (string.IsNullOrEmpty(recordData.sparepartout))
                    {
                        model.record_code = string.Join(',', sparepartHelper.GetSparepartNameNum(recordData.sparepartout));
                    }
                    //合作维修人
                    if (!string.IsNullOrEmpty(recordData.corepairer))
                    {
                        var userIds = recordData.corepairer.Split(',').ToList();
                        var users = _userRepository.GetList(q =>
                            userIds.Contains(q.mid.ToString()) && q.status == (int)RowState.Valid
                                                               && q.projectid == ProjectId).ToList();
                        model.corepair = string.Join(',', users.Select(m => m.name).ToList());
                    }
                    model.act_standard_time = recordData.actual_standard_time;
                    model.imgurl = recordData.imgurl;
                }
                else
                {
                    model.state_name = "未执行";
                    if (plan.instruction_time < now)
                    {
                        model.state_name = "逾期";
                    }
                    if (end < now)
                    {
                        model.value = "不通过";
                    }
                }

                ret.Add(model);
            }
            return new ObjectResult(ret);
        }
    }
}