using LiteDB;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using System.Windows;
using System.Windows.Media;

namespace Nodify.Calculator
{
    public enum ConnectorShape
    {
        Circle,
        Triangle,
        Square,
    }

    public class ConnectorViewModel : ObservableObject
    {
        private string? _title;
        public string? Title
        {
            get => _title;
            set => SetProperty(ref _title, value);
        }

        private double _value;
        public double Value
        {
            get => _value;
            set => SetProperty(ref _value, value)
                .Then(() => ValueObservers.ForEach(o => o.Value = value));
        }

        private ConnectorShape _shape;
        public ConnectorShape Shape
        {
            get => _shape;
            set => SetProperty(ref _shape, value);
        }

        private bool _isConnected;
        public bool IsConnected
        {
            get => _isConnected;
            set => SetProperty(ref _isConnected, value);
        }

        private bool _isInput;
        public bool IsInput
        {
            get => _isInput;
            set => SetProperty(ref _isInput, value);
        }

        private Point _anchor;
        public Point Anchor
        {
            get => _anchor;
            set => SetProperty(ref _anchor, value);
        }

        private System.Drawing.Color _color = System.Drawing.Color.DodgerBlue;
        public System.Drawing.Color ConnectorColor
        {
            set
            {
                _color = value;
            }
        }

        public System.Drawing.Color RawColor => _color;

        public Brush Color
        {
            get
            {
                var mediacolor = System.Windows.Media.Color.FromArgb
                    (
                        _color.A,
                        _color.R,
                        _color.G,
                        _color.B
                    );
                return ColorToSolidBrushConverter.Convert(mediacolor);
            }
        }

        [Newtonsoft.Json.JsonIgnore]
        [BsonIgnore]
        private OperationViewModel _operation = default!;
        [Newtonsoft.Json.JsonIgnore]
        [BsonIgnore]
        public OperationViewModel Operation
        {
            get => _operation;
            set => SetProperty(ref _operation, value);
        }

        [Newtonsoft.Json.JsonIgnore]
        [BsonIgnore]
        public List<ConnectorViewModel> ValueObservers { get; } = new List<ConnectorViewModel>();

        private string _dataType = string.Empty;
        /// <summary>
        /// The underlying C# type of this connector (e.g. "string", "int", "double").
        /// Used to enforce type-safe connections.
        /// </summary>
        public string DataType
        {
            get => _dataType;
            set => SetProperty(ref _dataType, value);
        }

        private bool _isCopyConnector;
        /// <summary>
        /// When true, this connector belongs to a COPY node and accepts any shape for connections.
        /// </summary>
        public bool IsCopyConnector
        {
            get => _isCopyConnector;
            set => SetProperty(ref _isCopyConnector, value);
        }

        private bool _isTakeListConnector;
        /// <summary>
        /// When true, this connector belongs to a TAKE node and only accepts list/array types.
        /// </summary>
        public bool IsTakeListConnector
        {
            get => _isTakeListConnector;
            set => SetProperty(ref _isTakeListConnector, value);
        }

        /// <summary>
        /// Returns a color based on the C# data type.
        /// </summary>
        public static System.Drawing.Color GetColorForType(string typeName)
        {
            return (typeName ?? "").ToLower() switch
            {
                "string" => System.Drawing.Color.CornflowerBlue,
                "int" => System.Drawing.Color.LightGreen,
                "double" => System.Drawing.Color.Orange,
                "float" => System.Drawing.Color.Gold,
                "bool" => System.Drawing.Color.Tomato,
                "decimal" => System.Drawing.Color.MediumOrchid,
                "long" => System.Drawing.Color.YellowGreen,
                "datetime" => System.Drawing.Color.DeepSkyBlue,
                "object" => System.Drawing.Color.Silver,
                "list<object>" => System.Drawing.Color.Plum,
                _ => System.Drawing.Color.LightGray,
            };
        }
    }
}
