using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.FieldEnum;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.IMSRepository.Entities;
using Siger.Middlelayer.IMSRepository.Repositories.Interface;
using Siger.Middlelayer.IMSRepository.Request;
using Siger.Middlelayer.IMSRepository.Response;
using Siger.Middlelayer.Dapper;
using Siger.Middlelayer.WmsRepository.Repositories.Interface;
using Siger.Middlelayer.Redis.Repositories;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Common.ModuleEnum;

namespace Siger.ApiIMS.Controllers
{
    public class PackageController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IToolLifeToolPackageRepository _packageRepository;
        private readonly IToolLifeToolInstallRepository _installRepository;
        private readonly IToolLifeReplaceReturnRepository _replaceReturnRepository;
        private readonly Isiger_wms_stockRepository _stockRepository;
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly IToolLifeToolRepository _toolLifeToolRepository;
        private readonly Isiger_wms_stock_detailRepository _stockDetailRepository;

        public PackageController(IUnitOfWork unitOfWork, IToolLifeToolPackageRepository packageRepository,
            IToolLifeToolInstallRepository installRepository, IToolLifeReplaceReturnRepository replaceReturnRepository
            , Isiger_wms_stockRepository stockRepository, ISigerProjectMachineRepository machineRepository, IToolLifeToolRepository toolLifeToolRepository
            , Isiger_wms_stock_detailRepository stockDetailRepository)
        {
            _unitOfWork = unitOfWork;
            _packageRepository = packageRepository;
            _installRepository = installRepository;
            _replaceReturnRepository = replaceReturnRepository;
            _stockRepository = stockRepository;
            _machineRepository = machineRepository;
            _toolLifeToolRepository = toolLifeToolRepository;
            _stockDetailRepository = stockDetailRepository;
        }

        /// <summary>
        /// 刀具组装卸载，扫描物料二维码
        /// </summary>
        /// <param name="mattercode"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetMatterInfo(string mattercode)
        {
            var response = _packageRepository.GetMatterInfo(mattercode, ProjectId);
            if (response == null)
            {
                throw new BadRequestException(ImsEnum.ToolNotFound);
            }
            return new ObjectResult(response);
        }

        /// <summary>
        /// 移除刀具的组装
        /// </summary>
        /// <param name="mattercode"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult RemoveAssemble(string mattercode)
        {
            var package = _packageRepository.Get(q =>
                q.code == mattercode && q.status == (int)RowState.Valid && q.project_id == ProjectId);
            if (package == null)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }

            if (package.code == package.assemble_code)
            {
                var packages = _packageRepository.GetList(q => q.assemble_code == mattercode && q.status == (int)RowState.Valid && q.project_id == ProjectId);
                foreach (var ProjectIMSPackage in packages.ToList())
                {
                    _packageRepository.Delete(ProjectIMSPackage);
                }
            }
            else
            {
                _packageRepository.Delete(package);
            }

            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 刀具组装卸载，提交组装
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult SetAssembleInfo([FromBody]RequestSetAssembleInfo request)
        {
            //清除所有已组装的
            if (request.assembles == null || !request.assembles.Any())
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            //移除刀柄的组装
            var handler = request.assembles.FirstOrDefault(q => q.matterType == "1");
            if (handler == null)
            {
                throw new BadRequestException(RequestEnum.ToolHandlerInValid);
            }

            var toolHandler = _packageRepository.GetMatterInfoByCode(handler.matterCode, ProjectId);
            if (toolHandler == null)
            {
                throw new BadRequestException(RequestEnum.ToolNotFound);
            }

            //移除不在请求中的刀柄组合
            var packages = _packageRepository.GetList(q =>
                q.assemble_code == handler.matterCode && q.project_id == ProjectId && q.status == (int)RowState.Valid);
            if (packages.Any())
            {
                foreach (var assemble in packages)
                {
                    _packageRepository.Delete(assemble);
                }
            }

            //移除刀具的组装
            foreach (var assemble in request.assembles)
            {
                var hasPackage = _packageRepository.Get(q => q.code == assemble.matterCode && q.project_id == ProjectId && q.status == (int)RowState.Valid);
                if (hasPackage != null)
                {
                    //如果是批次号，则不删除
                    var info = _packageRepository.GetMatterInfoByCode(hasPackage.code, ProjectId);
                    if (info.isBatchNumber == 0)
                    {
                        _packageRepository.Delete(hasPackage);
                    }
                }
            }

            if (_unitOfWork.Commit() < 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }

            //添加组装
            foreach (var info in request.assembles)
            {
                var entity = new siger_project_ims_package
                {
                    assemble_code = handler.matterCode,
                    code = info.matterCode,
                    location = info.location,
                    project_id = ProjectId,
                    confirm_status = ChoiceStatus.HasApply,
                    create_id = UserId,
                    create_time = DateTime.Now,
                    boom_code = request.boomCode ?? ""
                };

                _packageRepository.Insert(entity);
            }

            if (_unitOfWork.Commit() < 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }

            return new ObjectResult(CommonEnum.Succefull);
        }

        /// <summary>
        /// 刀具安装
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult SetInstallInfo([FromBody]RequestSetInstallInfo request)
        {
            if (string.IsNullOrWhiteSpace(request.matterCode))
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            if (string.IsNullOrWhiteSpace(request.knifePosition))
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            var handler = _packageRepository.GetMatterInfoByCode(request.matterCode, ProjectId);
            if (handler == null)
            {
                throw new BadRequestException(RequestEnum.ToolNotFound);
            }

            var installs = _installRepository.GetList(q =>
                q.machine_code == request.machineCode
                && q.cutter_number == request.knifePosition
                && q.install_category == InstallCategory.Install && q.project_id == ProjectId
                && q.status == (int)RowState.Valid);
            if (installs.Any())
            {
                throw new BadRequestException(ImsEnum.MachineCutterHasInstallTool);
            }

            //验证是否已安装，只验证序号
            var hasInstall = _packageRepository.HasInstall(request.matterCode, ProjectId);
            if (hasInstall)
            {
                throw new BadRequestException(ImsEnum.ToolCannotInstallAgain);
            }

            var entities = new List<siger_project_ims_tool_install>();
            var packageTool = _packageRepository.Get(q => q.code == request.matterCode && q.status == (int)RowState.Valid
                                                            && q.confirm_status == ChoiceStatus.HasApply);
            if (packageTool != null)
            {
                var packages = _packageRepository.GetList(q => q.assemble_code == packageTool.assemble_code && q.status == (int)RowState.Valid).ToList();
                if (packages.Any())
                {
                    foreach (var package in packages)
                    {
                        var detail = _stockDetailRepository.Get(f => f.projectid == ProjectId && (f.no == package.code || f.batch == package.code));
                        var material_id = detail?.inventory ?? 0;
                        var tool = _toolLifeToolRepository.Get(f => f.material_id == material_id && f.project_id == ProjectId && f.status != 0);
                        var entity = new siger_project_ims_tool_install
                        {
                            project_id = ProjectId,
                            create_time = DateTime.Now,
                            install_userid = UserId,
                            install_category = InstallCategory.Install,
                            machine_code = request.machineCode,
                            cutter_number = request.knifePosition ?? "",
                            tool_code = package.code,
                            package_id = package.id,
                            tool_category = tool?.category_id ?? 0,
                            boom_code = package.boom_code ?? "",
                            material_id = material_id
                        };
                        entities.Add(entity);
                    }
                }
            }
            else
            {
                //自动安刀？？
                var detail = _stockDetailRepository.Get(f => f.projectid == ProjectId && (f.no == request.matterCode || f.batch == request.matterCode));
                var material_id = detail?.inventory ?? 0;
                var tool = _toolLifeToolRepository.Get(f => f.material_id == material_id && f.project_id == ProjectId && f.status != 0);

                var entity = new siger_project_ims_tool_install
                {
                    project_id = ProjectId,
                    create_time = DateTime.Now,
                    install_userid = UserId,
                    install_category = InstallCategory.Install,
                    machine_code = request.machineCode,
                    cutter_number = request.knifePosition ?? "",
                    tool_code = request.matterCode,
                    tool_category = tool?.category_id ?? 2,
                };
                entities.Add(entity);
                //throw new BadRequestException(RequestEnum.NoPackageTools);
            }

            _installRepository.Insert(entities);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 获取安装信息，卸载时用
        /// </summary>
        /// <param name="matterCode"></param>
        /// <param name="machineCode"></param>
        /// <param name="knifePosz"></param>
        /// <param name="codeType"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetInstalledInfo(string matterCode, string machineCode, string knifePosz, string codeType)
        {
            var response = new ResponseGetInstllInfo();
            //var labelRep = new LabelCounterRepository(CompanyId, ProjectId);
            var list = new List<InstllInfo>();
            if (codeType == "1") // 刀具
            {
                var install = _installRepository.Get(q => q.tool_code == matterCode && q.project_id == ProjectId && q.install_category == InstallCategory.Install);
                if (install == null)
                {
                    //throw new BadRequestException(RequestEnum.ToolNotInstall);
                    throw new BadRequestException(ImsEnum.ToolNotInstall);
                }
                response.knifePoszDisp = install.cutter_number;
                response.machineCode = install.machine_code;

                var toolPackage = _packageRepository.Get(q => q.code == matterCode && q.project_id == ProjectId && q.status == (int)RowState.Valid
                                                            && q.confirm_status == ChoiceStatus.HasApply);
                if (toolPackage != null)
                {
                    var packages = _packageRepository.GetList(q => q.assemble_code == toolPackage.assemble_code).ToList();
                    if (packages.Any())
                    {
                        var installs = _installRepository.GetList(q => packages.Select(m => m.id).Contains(q.package_id) && q.project_id == ProjectId
                                                                                                                          && q.status == (int)RowState.Valid
                                                                                                                          && q.install_category == InstallCategory.Install);
                        foreach (var entityInstall in installs.ToList())
                        {
                            var package = packages.FirstOrDefault(q => q.id == entityInstall.package_id);
                            var info = _packageRepository.GetMatterInfoByCode(entityInstall.tool_code, ProjectId);
                            if (info != null)
                            {
                                list.Add(new InstllInfo
                                {
                                    ProcessCount = 0,//labelRep.GetProcessCount(entityInstall.create_time.ToStr(), entityInstall.machine_code.ToInt(), entityInstall.cutter_number.ToInt()),
                                    matterCode = info.matterCode,
                                    matterName = info.matterName,
                                    matterType = info.matterType,
                                    location = package != null ? package.location : "",
                                    toolcode=info.toolcode,
                                    lastLife = info.matterType == "2" ? GetToolLife(ProjectId, CompanyId, response.machineCode, "1", info.toolcode) : ""
                                });
                            }
                        }
                    }
                }
            }
            else if (codeType == "2") // 刀位号
            {
                var installs = _installRepository.GetList(q => q.machine_code == machineCode && q.cutter_number == knifePosz && q.project_id == ProjectId &&
                    q.install_category == InstallCategory.Install);
                if (!installs.Any())
                {
                    throw new BadRequestException(ImsEnum.CutterNumberNotInstall);
                }
                response.knifePoszDisp = knifePosz;
                response.machineCode = machineCode;
                response.Life = "0";//TODO对接寿命

                foreach (var install in installs.ToList())
                {
                    var package = _packageRepository.Get(q => q.id == install.package_id && q.project_id == ProjectId && q.status == (int)RowState.Valid);
                    var info = _packageRepository.GetMatterInfoByCode(install.tool_code, ProjectId);
                    if (info != null)
                    {
                        list.Add(new InstllInfo
                        {
                            ProcessCount = 0,//labelRep.GetProcessCount(install.create_time.ToStr(), install.machine_code.ToInt(), install.cutter_number.ToInt()),
                            matterCode = info.matterCode,
                            matterName = info.matterName,
                            matterType = info.matterType,
                            location = package != null ? package.location : "",
                            toolcode = info.toolcode,
                            lastLife= info.matterType=="2"? GetToolLife(ProjectId, CompanyId, response.machineCode, "1", info.toolcode) : ""
                        });
                    }
                }
            }
            response.detailInfo = list.OrderBy(m => m.location).ToList();
            response.Life = GetToolLife(ProjectId, CompanyId, response.machineCode, "1", response.detailInfo.FirstOrDefault(f => f.matterType == "1")?.toolcode ?? "");
            return new ObjectResult(response);
        }
        /// <summary>
        /// 获取刀具寿命 
        /// TODO还需优化
        /// </summary>
        /// <param name="pid"></param>
        /// <param name="cid"></param>
        /// <param name="machineCode"></param>
        /// <param name="spindleName"></param>
        /// <param name="toolName"></param>
        /// <returns></returns>
        private string GetToolLife(int pid,int cid, string machineCode, string spindleName, string toolName)
        {
            var helper = new ToolMachineCycleUsageRepository(cid, pid);
            var machineId = _machineRepository.Get(f => f.code == machineCode && f.projectid == pid && f.status != 0)?.id ?? 0;
            var data = helper.GetToolUsage(machineId, spindleName, toolName);
            if (data == null)
            {
                return "";
            }
            return data.tc.ToString();
        }
        /// <summary>
        /// 刀具卸载
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult UninstallKnife([FromBody]RequestUninstallKnife request)
        {
            var guid = IdHelper.Generate<string>();
            if (request.detailinfo == null || !request.detailinfo.Any())
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            var labelRep = new LabelCounterRepository(CompanyId, ProjectId);
            foreach (var knife in request.detailinfo)
            {
                var install = _installRepository.Get(q =>
                    q.tool_code == knife.matterCode && q.project_id == ProjectId &&
                    q.install_category == InstallCategory.Install);

                if (install != null)
                {
                    install.install_category = InstallCategory.UnInstall;
                    install.uninstall_reason = knife.uninstall_reason;
                    install.lastLife = knife.lastLife.ToStr();
                    install.uninstall_time = DateTime.Now;
                    install.process_count = 0;
                    install.install_code = guid;
                    //labelRep.GetProcessCount(install.create_time.ToStr(), install.machine_code.ToInt(), install.cutter_number.ToInt());
                    _installRepository.Update(install);
                    var stockData= _stockRepository.Get(f => f.serial_number == install.tool_code || f.batch_number == install.tool_code);
                    var entity = new siger_project_ims_tool_replace_return
                    {
                        workorder_id = 0,
                        workorder_code = string.Empty,
                        material_id = stockData?.material_id ?? 0,
                        part_no = stockData?.material_pn ?? "",
                        operate_time = UnixTimeHelper.GetNow(),
                        operate_mid = UserId,
                        operate_type = (int)ReplaceReturnTypeStatus.SendBack,
                        project_id = ProjectId,
                        status = 1,
                        quantity = 1,
                        stock_number = install.tool_code,
                        supplier_id = stockData?.businessid ?? 0,
                        create_mid = UserId,
                        create_time = UnixTimeHelper.GetNow(),
                        install_code = guid
                    };
                    _replaceReturnRepository.Insert(entity);
                }
            }

            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 安装查询
        /// </summary>
        /// <param name="machineCode"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetAllInstalledInfo(string machineCode)
        {
            if (string.IsNullOrWhiteSpace(machineCode))
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            var installs = _installRepository.GetList(q => q.machine_code == machineCode && q.project_id == ProjectId &&
                q.install_category == InstallCategory.Install).ToList();
            if (!installs.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var response = new ResponseGetAllInstalledInfo
            {
                machineCode = machineCode
            };

            var list = new List<AllInstalledInfo>();

            var cutternumbers = installs.Select(m => m.cutter_number).OrderBy(m => m).Distinct().ToList();
            foreach (var cutternumber in cutternumbers)
            {
                var cutterInstalls = installs.Where(q => q.cutter_number == cutternumber).OrderBy(m => m.tool_category);
                var handlerName = string.Empty;
                foreach (var install in cutterInstalls)
                {
                    var assTool = _packageRepository.GetMatterInfoByCode(install.tool_code, ProjectId);
                    if (assTool == null || assTool.matterType == "3")
                    {
                        continue;
                    }
                    var package = _packageRepository.Get(q => q.id == install.package_id && q.project_id == ProjectId && q.status == (int)RowState.Valid);
                    if (package != null)
                    {
                        if (package.code == package.assemble_code) //刀柄
                        {
                            handlerName = assTool.matterName;
                            continue;
                        }
                        list.Add(new AllInstalledInfo
                        {
                            handleName = handlerName,
                            knifePoszDisp = install.cutter_number,
                            knifeName = assTool.matterName,
                            installDate = install.create_time.ToString(ParameterConstant.DateFormat),
                            installTime = install.create_time.ToString(ParameterConstant.TimeFormat)
                        });
                    }
                    else
                    {
                        list.Add(new AllInstalledInfo
                        {
                            handleName = string.Empty,
                            knifePoszDisp = install.cutter_number,
                            knifeName = assTool.matterName,
                            installDate = install.create_time.ToString(ParameterConstant.DateFormat),
                            installTime = install.create_time.ToString(ParameterConstant.TimeFormat)
                        });
                    }
                }
            }

            //去重
            if (list.Any())
            {
                foreach (var info in list)
                {
                    var exist = response.data.FirstOrDefault(q => q.knifePoszDisp == info.knifePoszDisp && q.knifeName == info.knifeName);
                    if (exist == null)
                    {
                        response.data.Add(info);
                    }
                }
            }

            return new ObjectResult(response);
        }
    }
}