using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Result;
using Siger.ApiCommon.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.Redis.Repositories;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Dapper;
using Siger.Middlelayer.Redis.Model;
using Siger.Middlelayer.ToolRepository.Entities;
using Siger.Middlelayer.ToolRepository.Repositories.Interface;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.ToolRepository.Request;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.ApiTools.Controllers
{
    public class ToolChangeController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerToolChangeRecordRepository _sigerToolChangeRecord;
        private readonly ISigerProjectToolChangeExtendRepository _sigerProjectToolChangeExtend;
        private readonly ISigerProjectMachineRepository _sigerProjectMachine;
        public ToolChangeController(IUnitOfWork unitOfWork, ISigerToolChangeRecordRepository sigerToolChange, ISigerProjectToolChangeExtendRepository sigerProjectToolChangeExtend,
            ISigerProjectMachineRepository sigerProjectMachine)
        {
            _unitOfWork = unitOfWork;
            _sigerToolChangeRecord = sigerToolChange;
            _sigerProjectToolChangeExtend = sigerProjectToolChangeExtend;
            _sigerProjectMachine = sigerProjectMachine;
        }

        [HttpGet]
        public IActionResult GetChangeRecordList(int sectionId, string toolId, string drawingCode,
            string change_reason, string change_user, int page=1, int pageSize=10)
        {
            var data = _sigerToolChangeRecord.GetToolChangeRecord(sectionId, ProjectId, toolId, drawingCode, change_reason, change_user,page,pageSize);

            foreach (var d in data.Data)
            {
                d.section_dsc = _sigerProjectMachine.GetLineLevelTitlebByMachine(d.machineId, ProjectId);
            }
            return new PagedObjectResult(data.Data,data.Total,page,pageSize);
        }

        [HttpGet]
        public IActionResult GetChangeUserNameList()
        {
            var data = _sigerToolChangeRecord.GetChangeToolUser(ProjectId);
            return new ObjectResult(data);
        }

        [HttpPost]
        public ActionResult Add([FromBody]RequestToolChangeRecord changeRecord)
        {
            var entity = new siger_tool_change_record
            {
                equip_code = changeRecord.machine_code,
                equip_name = changeRecord.machine_name,
                machine_id = changeRecord.machine_id,
                mainaxis = changeRecord.spindle_name,
                tool_no = changeRecord.cutter_location_name,
                tool_name = changeRecord.tool_name,
                tool_drawno = changeRecord.drawingcode,
                supplier = changeRecord.supplier,
                rating_life = changeRecord.ratedlife,
                residual_life = changeRecord.residual_life,
                true_residual_life = changeRecord.surplus_life,
                programno = changeRecord.programno,
                change_time = UnixTimeHelper.GetUnixByShortDate(changeRecord.change_time),
                comment = changeRecord.comment,
                change_reason = changeRecord.change_reason,
                url_path = changeRecord.cover,
                status = (int)RowState.Valid,
                projectid = ProjectId,
                change_user = UserId.ToString()
            };

            _sigerToolChangeRecord.Insert(entity);
            //GrayImage info
            _sigerProjectToolChangeExtend.Insert(new SigerProjectToolChangeExtend {
                 MachineID= changeRecord.machine_id,
                 Spindle= int.Parse(changeRecord.spindle_name),
                 Tool= int.Parse(changeRecord.cutter_location_name),
                 Program= changeRecord.programno,
                 ChangeTime= UnixTimeHelper.GetUnixByShortDate(changeRecord.change_time),
                 Project=ProjectId,
                 Date = DateTime.Parse(DateTime.Now.ToShortDateString())

            });
            if (_unitOfWork.Commit() > 0)
            {
                try
                {
                    var redis = new ChangeToolRepository(CompanyId, ProjectId);
                    //1.5.2
                    var dapper = new ToolAlarmRepository(CompanyId, ProjectId);
                  
                    var actime = DateTime.Now;
                    var spTime = dapper.GetSlicePeriod(changeRecord.programno, changeRecord.machine_id);
                    if (spTime != null)
                    {
                        var spTimeS = UnixTimeHelper.GetUnixByShortDate(spTime.starttime.ToStr());
                        var spTimeE = UnixTimeHelper.GetUnixByShortDate(spTime.endtime.ToStr());
                        var ChangeTime = UnixTimeHelper.GetUnixByShortDate(changeRecord.change_time);

                        if (ChangeTime >= spTimeS && ChangeTime <= spTimeE)
                            actime = UnixTimeHelper.ConvertStringDateTime(ChangeTime.ToStr());
                        else
                            actime = UnixTimeHelper.ConvertStringDateTime(spTimeE.ToStr());
                    }
                    var model = Mapper<siger_tool_change_record, RedisChangeRecordModel>.Map(entity);
                    redis.AddChangeToolsRecord(model, actime);
                }
                catch(Exception exception)
                {
                    Logger.WriteLineError("Sync add ToolChangeRecord failed :error:" + exception.Message);
                }
                return new ObjectResult(CommonEnum.Succefull);
            }

            throw new BadRequestException(CommonEnum.Fail);
        }
        
        [HttpPost]
        public IActionResult Delete([FromBody]RequestToolChangeDelete req)
        {
            var record = _sigerToolChangeRecord.Get(req.id);
            if (record == null || record.status !=(int)RowState.Valid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            _sigerToolChangeRecord.Delete(record);
            if (_unitOfWork.Commit() > 0)
            {
                try
                {
                    var redis = new ChangeToolRepository(CompanyId, ProjectId);

                    var model = Mapper<siger_tool_change_record, RedisChangeRecordModel>.Map(record);
                    redis.DeleteChangeToolsRecord(model);
                }
                catch (Exception exception)
                {
                    Logger.WriteLineError("Sync delete ToolChangeRecord failed :error:" + exception.Message);
                }
                return new ObjectResult(CommonEnum.Succefull);
            }

            throw new BadRequestException(CommonEnum.Fail);
        }


        [HttpGet]
        public IActionResult ExportRecords(int sectionId, string toolId, string drawingCode,
            string change_reason, string change_user)
        {
            var data = _sigerToolChangeRecord.ExportToolChangeRecords(sectionId, ProjectId, toolId, drawingCode, change_reason, change_user).ToList();
            if (!data.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
           
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            var exportData = new List<ToolChangeList>();
            var index = 1;
            foreach (var item in data)
            {
                var toolItem = new ToolChangeList
                {
                    No = index,
                    Code = item.equip_code,
                    Name = item.equip_name,
                    ChangeReason = ChangeToolReasonConverter.ChangeReasons[item.change_reason],
                    ChangeTime = UnixTimeHelper.ConvertStringDateTime(item.change_time),
                    ChangeUser = item.change_user,
                    RateLife = item.rating_life,
                    RemainderLife = item.true_residual_life.ToInt(),
                    Remark = item.comment,
                    SpindleNo = item.mainaxis,
                    ToolName = item.tool_name,
                    ToolDrawingCode = item.tool_drawno,
                    ToolProcesPn=item.programno,
                    ToolNo = item.tool_no,
                };
                index++;
                exportData.Add(toolItem);
            }

            EpPlusExcelHelper<ToolChangeList> helper = null;
            try
            {
                helper = new EpPlusExcelHelper<ToolChangeList>();
                var temporaryFileName = $"toolchange_{DateTime.Now:yyyyMMddHHmmss}换刀记录.xlsx";
                helper.GenerateExcel(exportData, Path.Combine(rootDir, temporaryFileName),true);
                return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
            }
            catch (Exception e)
            {
                Logger.WriteLineError("Export tool change record failed, error:" + e);
                throw new BadRequestException(CommonEnum.SystemExcetion);
            }
            finally
            {
                helper?.Dispose();
            }
        }
    }
}