using PlcUiControl;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.IO;
using System.Linq;
using System.Windows.Forms;

[TypeConverter(typeof(NodeConverter))]
[Serializable]
public class Node
{
    private string _value;
    public static readonly string NodeFilePath = @"D:\XmlParser\ReadNodes.txt";
    public static List<string> AllNodes=new List<string>();
    public static bool EnableDesignTimeValidation { get; set; } = true; // 默认开启，提醒开发者
    public string Value
    {
        get => _value;
        set
        {
            value=value.Trim();
            if (string.IsNullOrWhiteSpace(value))
            {
                throw new ArgumentException("地址不能为空");
            }
            if (EnableDesignTimeValidation && !IsValidNode(value))
            {
                throw new ArgumentException($"地址\"{value}\"无效,请输入正确的地址，或导入XML后选择对应的地址。");
                //var dr = MessageBox.Show($"地址\"{value}\"无效，是否坚持绑定此地址？", "询问", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
                //if (dr == DialogResult.No)
                //{
                //    return;
                //}
            }
            _value = value;
        }
    }
    public string Name { get; set; }
    public NodeType Type {  get; set; }
    public string Comment { get; set; }

    public Node()
    {

    }
    public Node(string value)
    {
        _value = value;
        Name = null;
        Type =  NodeType.Unspecified;
        Comment = null;
    }
    public Node(string value, NodeType nodeType)
    {
        _value = value;
        //Name = StringExtensions.AfterLast(value, '.');
        Type = nodeType;
        Comment = null;
    }
    public Node(string value,NodeType nodeType,string comment)
    {
        _value = value;
        Name = StringExtensions.AfterLast(value, '.');
        Type = nodeType;
        Comment = comment;
    }

    public override string ToString()
    {
        return _value;
    }

    private bool IsValidNode(string input)
    {
        try
        {
            if (AllNodes.Contains(input))//先在内存中查找
            {
                return true;
            }
            if (!File.Exists(NodeFilePath))
            {
                throw new FileNotFoundException("ReadNodes.txt 文件未找到", NodeFilePath);
            }

            // 读取文件所有行并比较（忽略前后空格）
            return File.ReadLines(NodeFilePath)
                       .Any(line => line.Trim() == input.Trim());
        }
        catch (Exception ex)
        {
            // 可以记录日志或抛出异常
            Console.WriteLine("验证地址时出错：" + ex.Message);
            return false;
        }
    }
}

public class NodeConverter : TypeConverter
{ 
    // 1. 允许展开属性
    public override bool GetPropertiesSupported(ITypeDescriptorContext context)
    {
        return true; // 关键：返回 true 才能展开
    }
    // 2. 返回子属性集合
    public override PropertyDescriptorCollection GetProperties(
        ITypeDescriptorContext context,
        object value,
        Attribute[] attributes)
    {
        // 获取 Node 类的所有公共属性
        return TypeDescriptor.GetProperties(value, attributes)
            .Sort(new string[] { "Name", "Type", "Comment", "Value" }); // 可选排序
    }
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        // 支持从字符串转换
        if (sourceType == typeof(string))
        {
            return true;
        }
        return base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        // 当用户输入字符串时，尝试构造 ReadNode 对象
        if (value is string str)
        {
            str= str.Trim();
            if (!string.IsNullOrEmpty(str))
                return new Node { Value = str };
            else
                return null;
        }
        return base.ConvertFrom(context, culture, value);
    }

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(InstanceDescriptor) && value is Node n)
        {
            var ctor1 = typeof(Node).GetConstructor(new[] { typeof(string), typeof(NodeType), typeof(string) });
            if (ctor1 != null)
            {
                return new InstanceDescriptor(ctor1, new object[] { n.Value, n.Type, n.Comment });
            }
            else
            {
                MessageBox.Show("ConvertTo ctor1 Failed");
            }
            // 回退到单参数构造函数（更安全）
            var ctor2 = typeof(Node).GetConstructor(new[] { typeof(string), typeof(NodeType) });
            if (ctor2 != null)
            {
                return new InstanceDescriptor(ctor2, new object[] { n.Value, n.Type });
            }
            else
            {
                MessageBox.Show("ConvertTo ctor2 Failed");
            }
            
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        // 明确告诉设计器：可以生产new Node(...) 代码
        if (destinationType == typeof(InstanceDescriptor))
        {
            return true; // ✅ 关键！允许代码生成
        }
        if (destinationType == typeof(string))//如果返回True，那么设计器会调用ConvertTo 进行字符串格式化。
        {
            return false; // ✅ 关键！ 
        }
        return base.CanConvertTo(context, destinationType);
    }
}
public enum NodeType
{
   
    BOOL=0,
    BYTE,
    WORD,
    DWORD,
    LWORD,
    SINT,
    USINT,
    INT,
    UINT,
    DINT,
    UDINT,
    LINT,
    ULINT,

    REAL,
    LREAL,

    TIME,//UINT32
    STRING,

    Unspecified = -1,
}