using OpenCvSharp;
using System.ComponentModel;
using System.Drawing;
using static OpenCvSharp.AgastFeatureDetector;
using System.Text.RegularExpressions;
using System.Text;

namespace DH.Devices.Vision
{
    public enum MLModelType
    {
        [Description("图像分类")]
        ImageClassification = 1,
        [Description("目标检测")]
        ObjectDetection = 2,
        //[Description("图像分割")]
        //ImageSegmentation = 3
        [Description("语义分割")]
        SemanticSegmentation = 3,
        [Description("实例分割")]
        InstanceSegmentation = 4,
        [Description("目标检测GPU")]
        ObjectGPUDetection = 5
    }
    public class MLRequest
    {
        public int ImageChannels = 3;
        public Mat mImage;
        public int ResizeWidth;
        public int ResizeHeight;

        public float confThreshold;

        public float iouThreshold;

        //public int ImageResizeCount;
        public bool IsCLDetection;
        public int ProCount;
        public string in_node_name;

        public string out_node_name;

        public string in_lable_path;

        public int ResizeImageSize;
        public int segmentWidth;
        public int ImageWidth;

       // public List<labelStringBase> OkClassTxtList;


       // public List<ModelLabel> LabelNames;

        public float Score;

    }
    public enum ResultState
    {
       
        [Description("检测NG")]
        DetectNG = -3,

        //[Description("检测不足TBD")]
        // ShortageTBD = -2,
        [Description("检测结果TBD")]
        ResultTBD = -1,
        [Description("OK")]
        OK = 1,
        // [Description("NG")]
        // NG = 2,
        //统计结果
        [Description("A类NG")]
        A_NG = 25,
        [Description("B类NG")]
        B_NG = 26,
        [Description("C类NG")]
        C_NG = 27,
    }
    /// <summary>
    /// 深度学习 识别结果明细 面向业务:detect 面向深度学习:Recongnition、Inference
    /// </summary>
    public class DetectionResultDetail
    {
        public string LabelBGR { get; set; }//识别到对象的标签BGR


        public int LabelNo { get; set; }   // 识别到对象的标签索引

        public string LabelName { get; set; }//识别到对象的标签名称

        public double Score { get; set; }//识别目标结果的可能性、得分

        public string LabelDisplay { get; set; }//识别到对象的 显示信息

        public double Area { get; set; }//识别目标的区域面积

        public Rectangle Rect { get; set; }//识别目标的外接矩形

        public RotatedRect MinRect { get; set; }//识别目标的最小外接矩形(带角度)

        public ResultState InferenceResult { get; set; }//只是模型推理 label的结果

        public double DistanceToImageCenter { get; set; }  //计算矩形框到图像中心的距离



        public ResultState FinalResult { get; set; }//模型推理+其他视觉、逻辑判断后 label结果
    }
    public class MLResult
    {
        public bool IsSuccess = false;
        public string ResultMessage;
        public Bitmap ResultMap;
        public List<DetectionResultDetail> ResultDetails = new List<DetectionResultDetail>();
    }
    public class MLInit
    {
        public string ModelFile;
        public string InferenceDevice;


        public int InferenceWidth;
        public int InferenceHeight;

        public string InputNodeName;


        public int SizeModel;

        public bool bReverse;//尺寸测量正反面
                             //目标检测Gpu
        public bool IsGPU;
        public int GPUId;
        public float Score_thre;
        public MLInit(string modelFile, bool isGPU, int gpuId, float score_thre)
        {
            ModelFile = modelFile;
            IsGPU = isGPU;
            GPUId = gpuId;
            Score_thre = score_thre;
        }

        public MLInit(string modelFile, string inputNodeName, string inferenceDevice, int inferenceWidth, int inferenceHeight)
        {
            ModelFile = modelFile;
            InferenceDevice = inferenceDevice;

            InferenceWidth = inferenceWidth;
            InferenceHeight = inferenceHeight;
            InputNodeName = inputNodeName;


        }
    }
    public class DetectStationResult 
    {
        public string Pid { get; set; }

        public string TempPid { get; set; }

        /// <summary>
        /// 检测工位名称
        /// </summary>
        public string DetectName { get; set; }

     
        /// <summary>
        /// 深度学习 检测结果
        /// </summary>
        public List<DetectionResultDetail> DetectDetails = new List<DetectionResultDetail>();


        /// <summary>
        /// 工位检测结果
        /// </summary>
        public ResultState ResultState { get; set; } = ResultState.ResultTBD;


        public double FinalResultfScore { get; set; } = 0.0;


        public string ResultLabel { get; set; } = "";// 多个ng时,根据label优先级,设定当前检测项的label

        public string ResultLabelCategoryId { get; set; } = "";// 多个ng时,根据label优先级,设定当前检测项的label

        public int PreTreatState { get; set; }
        public bool IsPreTreatDone { get; set; } = true;

        public bool IsAfterTreatDone { get; set; } = true;

        public bool IsMLDetectDone { get; set; } = true;

        /// <summary>
        /// 预处理阶段已经NG
        /// </summary>
        public bool IsPreTreatNG { get; set; } = false;

        /// <summary>
        /// 目标检测NG
        /// </summary>
        public bool IsObjectDetectNG { get; set; } = false;

        public DateTime EndTime { get; set; }

        public int StationDetectElapsed { get; set; }
        public static string NormalizeAndClean(string input)
        {
            if (input == null) return null;

            // Step 1: 标准化字符编码为 Form C (规范组合)
            string normalizedString = input.Normalize(NormalizationForm.FormC);

            // Step 2: 移除所有空白字符,包括制表符和换行符
            string withoutWhitespace = Regex.Replace(normalizedString, @"\s+", "");

            // Step 3: 移除控制字符 (Unicode 控制字符,范围 \u0000 - \u001F 和 \u007F)
            string withoutControlChars = Regex.Replace(withoutWhitespace, @"[\u0000-\u001F\u007F]+", "");

            // Step 4: 移除特殊的不可见字符(如零宽度空格等)
            string cleanedString = Regex.Replace(withoutControlChars, @"[\u200B\u200C\u200D\uFEFF]+", "");

            return cleanedString;
        }
       
    }
    public class RelatedCamera 
    {

        [Category("关联相机")]
        [DisplayName("关联相机")]
        [Description("关联相机描述")]
       
        //[TypeConverter(typeof(CollectionCountConvert))]
        public string CameraSourceId { get; set; } = "";


        
    }
    public class VisionEngine
    {
        [ReadOnly(true)]
        public string Id { get; set; } = Guid.NewGuid().ToString();


        [Category("检测配置")]
        [DisplayName("检测配置名称")]
        [Description("检测配置名称")]
        public string Name { get; set; }

        [Category("关联相机")]
        [DisplayName("关联相机")]
        [Description("关联相机描述")]
       
       
        public string CameraSourceId { get; set; } = "";


        [Category("关联相机集合")]
        [DisplayName("关联相机集合")]
        [Description("关联相机描述")]
        //[TypeConverter(typeof(DeviceIdSelectorConverter<CameraBase>))]
       
        public List<RelatedCamera> CameraCollects { get; set; } = new List<RelatedCamera>();


        [Category("启用配置")]
        [DisplayName("是否启用GPU检测")]
        [Description("是否启用GPU检测")]
        public bool IsEnableGPU { get; set; } = false;

        [Category("2.中检测(深度学习)")]
        [DisplayName("中检测-模型类型")]
        [Description("模型类型:ImageClassification-图片分类;ObjectDetection:目标检测;Segmentation-图像分割")]
        //[TypeConverter(typeof(EnumDescriptionConverter<MLModelType>))]
        public MLModelType ModelType { get; set; } = MLModelType.ObjectDetection;

        //[Category("2.中检测(深度学习)")]
        //[DisplayName("中检测-GPU索引")]
        //[Description("GPU索引")]
        //public int GPUIndex { get; set; } = 0;

        [Category("2.中检测(深度学习)")]
        [DisplayName("中检测-模型文件路径")]
        [Description("中处理 深度学习模型文件路径,路径中不可含有中文字符,一般情况可以只配置中检测模型,当需要先用预检测过滤一次时,请先配置好与预检测相关配置")]
       
        public string ModelPath { get; set; }

        public VisionEngine(string name, MLModelType modelType, string modelPath, bool isEnableGPU,string sCameraSourceId)
        {
            ModelPath = modelPath ?? string.Empty;
            Name = name;
            ModelType = modelType;
            IsEnableGPU = isEnableGPU;
            Id = Guid.NewGuid().ToString();
            CameraSourceId = sCameraSourceId;

        }
    }
}