using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace CtrEditor.ObjetosSim.UserControls
{
    /// <summary>
    /// Interaction logic for CircularSegment.xaml
    /// </summary>
    public partial class CircularSegment : UserControl
    {
        public double Angle
        {
            get { return (double)GetValue(AngleProperty); }
            set { SetValue(AngleProperty, value); }
        }

        public static readonly DependencyProperty AngleProperty =
            DependencyProperty.Register("Angle", typeof(double), typeof(CircularSegment), new PropertyMetadata(0.0));

        public double OuterRadius
        {
            get { return (double)GetValue(OuterRadiusProperty); }
            set { SetValue(OuterRadiusProperty, value); }
        }

        public static readonly DependencyProperty OuterRadiusProperty =
            DependencyProperty.Register("OuterRadius", typeof(double), typeof(CircularSegment), new PropertyMetadata(100.0, OnPropertyChanged));

        public double InnerRadius
        {
            get { return (double)GetValue(InnerRadiusProperty); }
            set { SetValue(InnerRadiusProperty, value); }
        }

        public static readonly DependencyProperty InnerRadiusProperty =
            DependencyProperty.Register("InnerRadius", typeof(double), typeof(CircularSegment), new PropertyMetadata(80.0, OnPropertyChanged));

        public double StartAngle
        {
            get { return (double)GetValue(StartAngleProperty); }
            set { SetValue(StartAngleProperty, value); }
        }

        public static readonly DependencyProperty StartAngleProperty =
            DependencyProperty.Register("StartAngle", typeof(double), typeof(CircularSegment), new PropertyMetadata(0.0, OnPropertyChanged));

        public double EndAngle
        {
            get { return (double)GetValue(EndAngleProperty); }
            set { SetValue(EndAngleProperty, value); }
        }

        public static readonly DependencyProperty EndAngleProperty =
            DependencyProperty.Register("EndAngle", typeof(double), typeof(CircularSegment), new PropertyMetadata(90.0, OnPropertyChanged));

        // Nuevas propiedades para las guías
        public bool ShowGuides
        {
            get { return (bool)GetValue(ShowGuidesProperty); }
            set { SetValue(ShowGuidesProperty, value); }
        }

        public static readonly DependencyProperty ShowGuidesProperty =
            DependencyProperty.Register("ShowGuides", typeof(bool), typeof(CircularSegment), new PropertyMetadata(false, OnPropertyChanged));

        public double GuideDistance
        {
            get { return (double)GetValue(GuideDistanceProperty); }
            set { SetValue(GuideDistanceProperty, value); }
        }

        public static readonly DependencyProperty GuideDistanceProperty =
            DependencyProperty.Register("GuideDistance", typeof(double), typeof(CircularSegment), new PropertyMetadata(5.0, OnPropertyChanged));

        public double GuideThickness
        {
            get { return (double)GetValue(GuideThicknessProperty); }
            set { SetValue(GuideThicknessProperty, value); }
        }

        public static readonly DependencyProperty GuideThicknessProperty =
            DependencyProperty.Register("GuideThickness", typeof(double), typeof(CircularSegment), new PropertyMetadata(2.0, OnPropertyChanged));

        public static readonly DependencyProperty GuideStrokeProperty =
            DependencyProperty.Register("GuideStroke", typeof(Brush), typeof(CircularSegment), new PropertyMetadata(new SolidColorBrush(Colors.DarkBlue), OnGuidePropertyChanged));

        public Brush GuideStroke
        {
            get { return (Brush)GetValue(GuideStrokeProperty); }
            set { SetValue(GuideStrokeProperty, value); }
        }

        public CircularSegment()
        {
            InitializeComponent();
            this.Loaded += CircularSegment_Loaded;
        }

        private void CircularSegment_Loaded(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("CircularSegment_Loaded called");
            DrawSegment();
        }

        // Propiedad pública para acceder al Path desde código externo
        public System.Windows.Shapes.Path TransportePath => path;

        private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as CircularSegment)?.DrawSegment();
        }

        private static void OnGuidePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as CircularSegment)?.DrawSegment();
        }

        private void DrawSegment()
        {
            System.Diagnostics.Debug.WriteLine($"DrawSegment called - ShowGuides: {ShowGuides}");

            if (OuterRadius <= 0 || InnerRadius <= 0 || StartAngle == EndAngle)
                return;

            // Limpiar canvas existente - mantener solo el path principal
            for (int i = mainCanvas.Children.Count - 1; i >= 0; i--)
            {
                if (mainCanvas.Children[i] != path)
                {
                    mainCanvas.Children.RemoveAt(i);
                }
            }

            DrawMainSegment();

            if (ShowGuides)
            {
                System.Diagnostics.Debug.WriteLine("About to call DrawGuides()");
                DrawGuides();
            }
        }

        private void DrawMainSegment()
        {
            PathGeometry geometry = new PathGeometry();
            PathFigure figure = new PathFigure();

            // Calcula el centro del Canvas (suponemos que el Canvas es lo suficientemente grande)
            Point center = new Point(OuterRadius, OuterRadius);

            // Calcular los puntos de inicio y fin del arco externo
            Point startPoint = new Point(center.X + Math.Cos(StartAngle * Math.PI / 180) * OuterRadius,
                                         center.Y + Math.Sin(StartAngle * Math.PI / 180) * OuterRadius);
            Point endPoint = new Point(center.X + Math.Cos(EndAngle * Math.PI / 180) * OuterRadius,
                                       center.Y + Math.Sin(EndAngle * Math.PI / 180) * OuterRadius);

            // Crear arco externo
            bool largeArc = Math.Abs(EndAngle - StartAngle) > 180.0;
            figure.StartPoint = startPoint;
            figure.Segments.Add(new ArcSegment(endPoint, new Size(OuterRadius, OuterRadius), 0, largeArc, SweepDirection.Clockwise, true));

            // Crear línea hacia el arco interno
            figure.Segments.Add(new LineSegment(new Point(center.X + Math.Cos(EndAngle * Math.PI / 180) * InnerRadius,
                                                         center.Y + Math.Sin(EndAngle * Math.PI / 180) * InnerRadius), true));

            // Crear arco interno
            startPoint = new Point(center.X + Math.Cos(StartAngle * Math.PI / 180) * InnerRadius,
                                   center.Y + Math.Sin(StartAngle * Math.PI / 180) * InnerRadius);
            figure.Segments.Add(new ArcSegment(startPoint, new Size(InnerRadius, InnerRadius), 0, largeArc, SweepDirection.Counterclockwise, true));

            // Cerrar la figura
            figure.IsClosed = true;
            geometry.Figures.Add(figure);
            path.Data = geometry;
        }

        private void DrawGuides()
        {
            Point center = new Point(OuterRadius, OuterRadius);

            // Calcular radios de las guías
            double outerGuideRadius = OuterRadius + GuideDistance;
            double innerGuideRadius = InnerRadius - GuideDistance;

            System.Diagnostics.Debug.WriteLine($"DrawGuides - Creating guides with radii: Outer={outerGuideRadius}, Inner={innerGuideRadius}");

            // Asegurar que el radio interior no sea negativo
            if (innerGuideRadius < 1.0)
                innerGuideRadius = 1.0;

            // Crear guía exterior
            CreateGuideArc(center, outerGuideRadius, "OuterGuide");

            // Crear guía interior solo si el radio es válido
            if (innerGuideRadius > 1.0)
            {
                CreateGuideArc(center, innerGuideRadius, "InnerGuide");
            }
        }

        private void CreateGuideArc(Point center, double radius, string name)
        {
            var guidePath = new System.Windows.Shapes.Path
            {
                Name = name,
                Stroke = GuideStroke,
                StrokeThickness = GuideThickness,
                Fill = null
            };

            // Crear geometría del arco
            double radiansStart = StartAngle * Math.PI / 180.0;
            double radiansEnd = EndAngle * Math.PI / 180.0;

            Point startPoint = new Point(
                center.X + radius * Math.Cos(radiansStart),
                center.Y + radius * Math.Sin(radiansStart)
            );

            Point endPoint = new Point(
                center.X + radius * Math.Cos(radiansEnd),
                center.Y + radius * Math.Sin(radiansEnd)
            );

            // Crear el arco usando ArcSegment
            var pathGeometry = new PathGeometry();
            var pathFigure = new PathFigure
            {
                StartPoint = startPoint
            };

            var arcSegment = new ArcSegment
            {
                Point = endPoint,
                Size = new Size(radius, radius),
                SweepDirection = SweepDirection.Clockwise,
                IsLargeArc = Math.Abs(EndAngle - StartAngle) > 180
            };

            pathFigure.Segments.Add(arcSegment);
            pathGeometry.Figures.Add(pathFigure);
            guidePath.Data = pathGeometry;

            System.Diagnostics.Debug.WriteLine($"Adding guide {name} to canvas");
            mainCanvas.Children.Add(guidePath);
        }
    }
}
