using Microsoft.Extensions.Logging;
using SlnMesnac.Business.@base;
using SlnMesnac.Common;
using SlnMesnac.Config;
using SlnMesnac.Model.domain;
using SlnMesnac.Model.dto;
using SlnMesnac.Plc;
using SlnMesnac.Repository.service;
using SlnMesnac.Rfid;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* 版权所有 (c) 2024 WenJY 保留所有权利。
* CLR版本：4.0.30319.42000
* 机器名称：LAPTOP-E0N2L34V
* 命名空间：SlnMesnac.Business
* 唯一标识：f79d6d97-d9b0-4b0b-a442-e6bb1c1c79e6
*
* 创建者：WenJY
* 电子邮箱：wenjy@mesnac.com
* 创建时间：2024-04-10 16:36:01
* 版本：V1.0.0
* 描述：
*
*--------------------------------------------------------------------
* 修改人：
* 时间：
* 修改说明：
*
* 版本：V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.Business
{
    /// <summary>
    /// 设备产出业务逻辑
    /// </summary>
    public class ProdCompletionBusiness : BaseBusiness
    {

        private readonly IMesProductPlanService _mesProductPlanService;
        private readonly IRealBarCodeTaskService _barCodeTaskService;
        
        private List<RealBarCodeTask> _barCodeTasks;

        public ProdCompletionBusiness(ILogger<BaseBusiness> logger, AppConfig appConfig, List<PlcAbsractFactory> plcFactories, List<RfidAbsractFactory> rfidFactories, IMesProductPlanService mesProductPlanService, IRealBarCodeTaskService barCodeTaskService, List<RealBarCodeTask> barCodeTasks,IServiceProvider serviceProvider) : base(logger, appConfig, plcFactories, rfidFactories, serviceProvider)
        {
            _mesProductPlanService = mesProductPlanService;
            _barCodeTaskService = barCodeTaskService;
            _barCodeTasks = barCodeTasks;
            
        }

        /// <summary>
        /// 刷新条码队列
        /// </summary>
        public delegate void RefreshBarCodeTaskList(List<RealBarCodeTask> list);
        public event RefreshBarCodeTaskList? RefreshBarCodeTaskListEvent;

        public void Init()
        {
            DeviceOutPutHandle();
        }

        /// <summary>
        /// 设备产出逻辑处理
        /// </summary>
        private void DeviceOutPutHandle()
        {
            while(true)
            {
                try
                {

                    var plc = base.GetPlcByKey("plc");

                    if (plc == null)
                    {
                        _logger.LogInformation("读取设备产出信号,PLC连接信息为空......");
                        Thread.Sleep(3000);
                        continue;
                    }

                    if (plc.readInt16ByAddress(GetPlcAddressByConfigKey("设备产出")) != 1)
                    {
                        _logger.LogInformation("等待设备产出信号触发......");
                        Thread.Sleep(5000);
                        continue;
                    }

                    _mesProductPlanService.GetStartedProdPlan(out MesProductPlanDto productPlanDto);

                    if (productPlanDto == null)
                    {
                        throw new ArgumentException($"未获取到正在执行的生产计划");
                    }
                    plc.writeInt16ByAddress(GetPlcAddressByConfigKey("设备产出"), 0);
                    //生成小包条码
                    string barCode = $"JYHB{(string.IsNullOrEmpty(productPlanDto.MaterialCode) ? "000000000" : productPlanDto.MaterialCode)}-000001";
                    if (_barCodeTasks.Count > 0)
                    {
                        var info = _barCodeTasks.OrderByDescending(x => x.RecordTime).Where(x=>x.MaterialCode == productPlanDto.MaterialCode);
                        if(info.Count() > 0)
                        {
                            var task = info.FirstOrDefault();

                            ExtractNumber(task.BarCode, out int orFlag);

                            barCode = $"JYHB{(string.IsNullOrEmpty(productPlanDto.MaterialCode) ? "000000000" : productPlanDto.MaterialCode)}-{orFlag.ToString().PadLeft(6,'0')}";
                        }
                    }

                    
                    
                    RealBarCodeTask barCodeTask = new RealBarCodeTask()
                    {
                        BarCode = barCode,
                        PlanCode = productPlanDto.PlanCode,
                        MaterialCode = productPlanDto.MaterialCode,
                        RecordTime = DateTime.Now
                    };
                    _barCodeTaskService.InsertBarCodeTask(barCodeTask);

                    RefreshBarCodeTaskListEvent?.Invoke(_barCodeTasks);
                }
                catch (Exception ex)
                {

                }
            }
        }

        /// <summary>
        /// 根据条码提取序列
        /// </summary>
        /// <param name="barCode"></param>
        /// <param name="result"></param>
        /// <exception cref="InvalidOperationException"></exception>
        private void ExtractNumber(string barCode,out int result)
        {
            string pattern = @"\b0*(\d{1,6})\b$";

            Match match = Regex.Match(barCode, pattern);
            if (match.Success)
            {
                result = Convert.ToInt32(match.Groups[1].Value)+1;
            }
            else
            {
                throw new InvalidOperationException($"通过条码:{barCode}提取当前序列异常:未找到匹配的数字");
            }
        }

        public void RemoveBarCode(string barCode)
        {
            _barCodeTaskService.RemoveBarCodeTask(barCode);
            RefreshBarCodeTaskListEvent?.Invoke(_barCodeTasks );
        }


        //public void testPenCode()
        //{

        //    //生成小包条码
        //    string materialCode = "000000000";
        //    string barCode = $"JYHB{(string.IsNullOrEmpty(materialCode) ? "000000000" : materialCode)}-000001";
        //    ExtractNumber(task.BarCode, out int orFlag);
        //    barCode = $"JYHB{(string.IsNullOrEmpty(productPlanDto.MaterialCode) ? "000000000" : productPlanDto.MaterialCode)}-{orFlag.ToString().PadLeft(6, '0')}";

        //}
    }
}
