using System.Reflection;

namespace RobotNet.Script.Shares;

public static class ScriptExtensions
{
    private static readonly string PreCode;

    static ScriptExtensions()
    {
        var preCode = "";

        var glovalType = typeof(IRobotNetGlobals);

        var properties = glovalType.GetProperties();
        foreach (var property in properties)
        {
            preCode = string.Join(Environment.NewLine, preCode, ToDeclarationString(property));
        }


        var fields = glovalType.GetFields();
        foreach (var field in fields)
        {
            preCode = string.Join(Environment.NewLine, preCode, ToDeclarationString(field));
        }

        var methods = glovalType.GetMethods();
        foreach (var method in methods)
        {
            if (method.Name.StartsWith("get_") || method.Name.StartsWith("set_")) continue;

            preCode = string.Join(Environment.NewLine, preCode, ToMethodString(method));
        }

        PreCode = preCode;
    }

    private static string ToDeclarationString(PropertyInfo property)
    {
        if (property.CanRead)
        {
            return $"{property.PropertyType.FullName} {property.Name} {{ get; {(property.CanWrite ? "set; " : "")}}}";
        }
        else if (property.CanWrite)
        {
            return $"{property.PropertyType.FullName} {property.Name} {{ set => throw new System.NotImplementedException(); }}";
        }
        else
        {
            return "";
        }
    }

    private static string ToDeclarationString(FieldInfo field)
    {
        return $"{field.FieldType.FullName} {field.Name};";
    }

    private static string ToMethodString(MethodInfo method)
    {
        return $"{ToTypeString(method.ReturnType)} {method.Name}({string.Join(',', method.GetParameters().Select(ToParameterString))}) => throw new System.NotImplementedException();";
    }

    private static string ToParameterString(ParameterInfo parameter)
    {
        var defaultValue = "";
        if (parameter.HasDefaultValue)
        {
            if (parameter.DefaultValue != null)
            {
                if (parameter.ParameterType.IsEnum)
                {
                    defaultValue = $" = {parameter.ParameterType.FullName}.{parameter.DefaultValue}";
                }
                else
                {
                    defaultValue = $" = {parameter.DefaultValue}";
                }
            }
            else
            {
                defaultValue = " = null";
            }
        }
        return $"{parameter.ParameterType.FullName} {parameter.Name}{defaultValue}";
    }

    private static string ToTypeString(Type type)
    {
        return type == typeof(void) ? "void" : type.FullName ?? type.Name;
    }
}
