using System.Text.Json;
using System.Text.Json.Serialization;
using Inspectron.Settings;
using LindtLeerformPlugin.Models;
using VisionBuilder.UI.Common;

namespace LindtLeerformPlugin;

public class LeerformSettings : ISettings
{
    public string CameraName { get; }

    public LeerformSettings(string cameraName)
    {
        CameraName = cameraName;
    }

    public CalibrationData? CalibrationData { get; set; }
    public int CheckerboardRows { get; set; } = 6;
    public int CheckerboardCols { get; set; } = 9;
    public string CalibrationImageDirectory { get; set; } = "CalibrationImages";

    public void RegisterSettings(InspectronSettings settings)
    {
        settings.RegisterSimple(this, () => CalibrationData!, $"{CameraName}/Leerform", nameof(CalibrationData));
        settings.RegisterSimple(this, () => CheckerboardRows, $"{CameraName}/Leerform", nameof(CheckerboardRows));
        settings.RegisterSimple(this, () => CheckerboardCols, $"{CameraName}/Leerform", nameof(CheckerboardCols));
        settings.RegisterSimple(this, () => CalibrationImageDirectory, $"{CameraName}/Leerform", nameof(CalibrationImageDirectory));
    }
}

public class CalibrationDataConverter : ITypeConverter
{
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNameCaseInsensitive = true,
        Converters = { new JsonStringEnumConverter() }
    };

    public object ConvertFrom(object value)
    {
        if (value is string json)
        {
            if (string.IsNullOrWhiteSpace(json) || json == "null")
                return null!;

            return JsonSerializer.Deserialize<CalibrationData>(json, JsonOptions)
                   ?? throw new InvalidOperationException("Failed to deserialize CalibrationData from JSON.");
        }
        throw new InvalidOperationException("Value must be a JSON string.");
    }

    public object ConvertTo(object value, Type destinationType)
    {
        if (value is CalibrationData data)
        {
            return JsonSerializer.Serialize(data, JsonOptions);
        }
        if (value == null)
        {
            return "null";
        }
        throw new InvalidOperationException("Value must be a CalibrationData.");
    }
}
