using System;
using System.Collections.Generic;
using System.Linq;
using AI.Common;
using AI.DiagSystem;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WingInterfaceLibrary.Enum;

namespace WingAIDiagnosisService.Manage
{
    public class AIDiagnosisPerImageModel
    {
        public AIDiagnosisPerImageModel() { }

        public AIDiagnosisPerImageModel(int index, AIDiagResultPerImg diagResult, int contourInterval)
        {
            Index = index;
            PriorityScore = diagResult.PriorityScore;
            DiagResultsForEachOrgan = diagResult?.DiagResultsForEachOrgan.Select(o => new AIDiagnosisResultPerOrgan(o, contourInterval))?.ToList() ?? new List<AIDiagnosisResultPerOrgan>();
        }

        public int Index { get; set; }
        public float PriorityScore { get; set; }
        public List<AIDiagnosisResultPerOrgan> DiagResultsForEachOrgan { get; set; } = new List<AIDiagnosisResultPerOrgan>();
    }

    public class AIDiagnosisResultPerOrgan
    {
        public AIDiagnosisResultPerOrgan() { }
        public AIDiagnosisResultPerOrgan(AIDiagResultPerOrgan perOrgan, int contourInterval)
        {
            var organ = DiagnosisOrganEnum.Null;
            var organName = Enum.GetName(typeof(DiagnosisOrganEnum), (int)perOrgan.Organ);
            if (!string.IsNullOrWhiteSpace(organName))
            {
                organ = (DiagnosisOrganEnum)perOrgan.Organ;
            }
            Organ = organ;
            OrganBoundBox = new AIDiagnosisRect(perOrgan.OrganBoundBox);

            var organContours = new List<AIDiagnosisPoint2D>();
            if (perOrgan.OrganContours != null && perOrgan.OrganContours.Length > 0)
            {
                var coutours = perOrgan.OrganContours[0];
                if (coutours != null && coutours.Length > 0)
                {
                    for (var i = 0; i < coutours.Length; i++)
                    {
                        if (i % contourInterval == 0)
                        {
                            organContours.Add(new AIDiagnosisPoint2D(coutours[i]));
                        }
                    }
                }
            }
            OrganContours = organContours;
            OrganDescriptions = perOrgan.OrganDescriptions.Select(d => new AIDiagnosisDescription(d))?.ToList() ?? new List<AIDiagnosisDescription>();
            DetectedObjects = perOrgan.DetectedObjects?.Select(d => new AIDetectedObject(d, contourInterval))?.ToList() ?? new List<AIDetectedObject>();
        }

        public DiagnosisOrganEnum Organ { get; set; }
        public AIDiagnosisRect OrganBoundBox { get; set; }
        public List<AIDiagnosisPoint2D> OrganContours { get; set; }
        public List<AIDiagnosisPoint2D> OrganContour { get; set; }
        public List<AIDiagnosisDescription> OrganDescriptions { get; set; }
        public List<AIDetectedObject> DetectedObjects { get; set; }
    }

    public class AIDiagnosisRect
    {
        public AIDiagnosisRect() { }
        public AIDiagnosisRect(Rect rect)
        {
            Right = rect.Right;
            Bottom = rect.Bottom;
            Left = rect.Left;
            Top = rect.Top;
            Width = rect.Width;
            Height = rect.Height;
        }
        public int Right { get; set; }
        public int Bottom { get; set; }
        public int Left { get; set; }
        public int Top { get; set; }
        public int Width { get; set; }
        public int Height { get; set; }
    }

    public class AIDiagnosisPoint2D
    {
        public AIDiagnosisPoint2D() { }
        public AIDiagnosisPoint2D(Point2D point)
        {
            X = point.X;
            Y = point.Y;
        }
        public int X { get; set; }
        public int Y { get; set; }
    }

    public class AIDetectedObject
    {
        public AIDetectedObject() { }
        public AIDetectedObject(DetectedObject detectedObject, int contourInterval)
        {
            Label = detectedObject.Label;
            Confidence = detectedObject.Confidence;
            if (!detectedObject.BoundingBox.IsEmpty())
            {
                BoundingBox = new AIDiagnosisRect(detectedObject.BoundingBox);
            }

            var contours = new List<AIDiagnosisPoint2D>();
            if (detectedObject.Contours != null && detectedObject.Contours.Length > 0)
            {
                var coutours = detectedObject.Contours[0];
                if (coutours != null && coutours.Length > 0)
                {
                    for (var i = 0; i < coutours.Length; i++)
                    {
                        if (i % contourInterval == 0)
                        {
                            contours.Add(new AIDiagnosisPoint2D(coutours[i]));
                        }
                    }
                }
            }
            Contours = contours;
            var descriptionList = new List<AIDiagnosisDescription>();
            if (detectedObject.Descriptions != null && detectedObject.Descriptions.Any())
            {
                foreach (var des in detectedObject.Descriptions)
                {
                    var desType = Enum.GetName(typeof(DiagnosisDescription), (int)des.Type);
                    if (!string.IsNullOrWhiteSpace(desType))
                    {
                        descriptionList.Add(new AIDiagnosisDescription(des));
                    }
                }
            }
            Descriptions = descriptionList;
            //Descriptions = detectedObject.Descriptions?.Select(d => new AIDiagnosisDescription(d))?.ToList() ?? new List<AIDiagnosisDescription>();
        }

        public int Label { get; set; }
        public float Confidence { get; set; }
        public AIDiagnosisRect BoundingBox { get; set; }
        public List<AIDiagnosisPoint2D> Contours { get; set; }
        public List<AIDiagnosisPoint2D> Contour { get; set; }
        public List<AIDiagnosisDescription> Descriptions { get; set; }
    }

    public class AIDiagnosisDescription
    {
        public AIDiagnosisDescription() { }

        public AIDiagnosisDescription(IDescription description)
        {
            Type = (DiagnosisDescription)description.Type;
            if (description is DescriptionLesionSize lesionSize)
            {
                var lesionSizeInfo = lesionSize.Value;
                if (lesionSizeInfo != null)
                {
                    var lz = new AIDiagnosisLesionSize
                    {
                        HorizontalLengthInPixel = lesionSizeInfo.HorizontalLengthInPixel,
                        VerticalLengthInPixel = lesionSizeInfo.VerticalLengthInPixel,
                    };
                    if (lesionSizeInfo.HorizontalPoint1 != null)
                    {
                        lz.HorizontalPoint1 = new AIDiagnosisPoint2D { X = lesionSizeInfo.HorizontalPoint1.X, Y = lesionSizeInfo.HorizontalPoint1.Y };
                    }
                    if (lesionSizeInfo.HorizontalPoint2 != null)
                    {
                        lz.HorizontalPoint2 = new AIDiagnosisPoint2D { X = lesionSizeInfo.HorizontalPoint2.X, Y = lesionSizeInfo.HorizontalPoint2.Y };
                    }
                    if (lesionSizeInfo.VerticalPoint1 != null)
                    {
                        lz.VerticalPoint1 = new AIDiagnosisPoint2D { X = lesionSizeInfo.VerticalPoint1.X, Y = lesionSizeInfo.VerticalPoint1.Y };
                    }
                    if (lesionSizeInfo.VerticalPoint2 != null)
                    {
                        lz.VerticalPoint2 = new AIDiagnosisPoint2D { X = lesionSizeInfo.VerticalPoint2.X, Y = lesionSizeInfo.VerticalPoint2.Y };
                    }
                    Value = JsonConvert.SerializeObject(lz);
                }
            }
            else if (description is DescriptionShape shape)
            {
                Value = shape.Value.ToString();
            }
            else if (description is DescriptionOrientation orientation)
            {
                Value = orientation.Value.ToString();
            }
            else if (description is DescriptionEchoPattern echoPattern)
            {
                Value = echoPattern.Value.ToString();
            }
            else if (description is DescriptionLesionBoundary lesionBoundary)
            {
                Value = lesionBoundary.Value.ToString();
            }
            else if (description is DescriptionMargin margin)
            {
                Value = margin.Value.ToString();
            }
            else if (description is DescriptionCalcifications calcifications)
            {
                Value = calcifications.Value.ToString();
            }
            else if (description is DescriptionLiverShape liverShape)
            {
                Value = liverShape.Value.ToString();
            }
            else if (description is DescriptionLiverBoundary liverBoundary)
            {
                Value = liverBoundary.Value.ToString();
            }
            else if (description is DescriptionLiverEchoTexture liverEcho)
            {
                Value = liverEcho.Value.ToString();
            }

            else if (description is DescriptionThyroidEchoPattern thyroidEcho)
            {
                Value = thyroidEcho.Value.ToString();
            }
            else if (description is DescriptionThyroidShape thyroidShape)
            {
                Value = thyroidShape.Value.ToString();
            }
            else if (description is DescriptionThyroidMargin thyroidMargin)
            {
                Value = thyroidMargin.Value.ToString();
            }
            else if (description is DescriptionThyroidEchogenicFoci thyroidFoci)
            {
                Value = thyroidFoci.Value.ToString();
            }
            else if (description is DescriptionQlaqueEchoPattern qlaqueEchoPattern)
            {
                Value = qlaqueEchoPattern.Value.ToString();
            }
            else if (description is DescriptionQlaqueLocation qlaqueLocation)
            {
                Value = qlaqueLocation.Value.ToString();
            }
            else if (description is DescriptionCarotidRateOfStenosis carotidRateOfStenosis)
            {
                Value = carotidRateOfStenosis.Value.ToString();
            }
            else if (description is DescriptionCarotidInnerDiameter carotidInnerDiameter)
            {
                var carotidInnerDiameterValue = carotidInnerDiameter.Value;
                if (carotidInnerDiameterValue != null)
                {
                    var value = new AIDiagnosisMeasuringLine
                    {
                        MeasuringLineLengthInPixel = carotidInnerDiameterValue.MeasuringLineLengthInPixel,
                    };
                    if (carotidInnerDiameterValue.StartPoint != null)
                    {
                        value.StartPoint = new AIDiagnosisPoint2D { X = carotidInnerDiameterValue.StartPoint.X, Y = carotidInnerDiameterValue.StartPoint.Y };
                    }
                    if (carotidInnerDiameterValue.EndPoint != null)
                    {
                        value.EndPoint = new AIDiagnosisPoint2D { X = carotidInnerDiameterValue.EndPoint.X, Y = carotidInnerDiameterValue.EndPoint.Y };
                    }
                    Value = JsonConvert.SerializeObject(value);
                }
            }
            else if (description is DescriptionCarotidIntimaMediaThickness carotidIntimaMediaThickness)
            {
                var carotidIntimaMediaThicknessValue = carotidIntimaMediaThickness.Value;
                if (carotidIntimaMediaThicknessValue != null)
                {
                    var value = new AIDiagnosisMeasuringLine
                    {
                        MeasuringLineLengthInPixel = carotidIntimaMediaThicknessValue.MeasuringLineLengthInPixel,
                    };
                    if (carotidIntimaMediaThicknessValue.StartPoint != null)
                    {
                        value.StartPoint = new AIDiagnosisPoint2D { X = carotidIntimaMediaThicknessValue.StartPoint.X, Y = carotidIntimaMediaThicknessValue.StartPoint.Y };
                    }
                    if (carotidIntimaMediaThicknessValue.EndPoint != null)
                    {
                        value.EndPoint = new AIDiagnosisPoint2D { X = carotidIntimaMediaThicknessValue.EndPoint.X, Y = carotidIntimaMediaThicknessValue.EndPoint.Y };
                    }
                    Value = JsonConvert.SerializeObject(value);
                }
            }
        }

        public DiagnosisDescription Type { get; set; }

        public string Value { get; set; }

        public DiagnosisDescription DescriptionType { get; set; }

        public string DescriptionValue { get; set; }
    }

    public class AIDiagnosisLesionSize
    {
        public AIDiagnosisLesionSize() { }
        public AIDiagnosisPoint2D HorizontalPoint1 { get; set; }
        public AIDiagnosisPoint2D HorizontalPoint2 { get; set; }
        public int HorizontalLengthInPixel { get; set; }
        public AIDiagnosisPoint2D VerticalPoint1 { get; set; }
        public AIDiagnosisPoint2D VerticalPoint2 { get; set; }
        public int VerticalLengthInPixel { get; set; }
    }

    public class AIDiagnosisMeasuringLine
    {
        public AIDiagnosisPoint2D StartPoint { get; set; }
        public AIDiagnosisPoint2D EndPoint { get; set; }
        public int MeasuringLineLengthInPixel { get; set; }
    }


}