using System.Globalization;
using System.Windows;
using ConeCalorimeter.Services;

namespace ConeCalorimeter.Views;

public partial class HeatFluxCoefficientWindow : Window
{
    private const ushort HeatFluxCoefficientRegister = 474;
    private const ModbusFloatByteOrder HeatFluxCoefficientByteOrder = ModbusFloatByteOrder.Dcba;
    private const string CoefficientFormat = "0.0000";

    private readonly ITcpDeviceConnectionService _tcpDeviceConnectionService;

    public HeatFluxCoefficientWindow(ITcpDeviceConnectionService tcpDeviceConnectionService)
    {
        _tcpDeviceConnectionService = tcpDeviceConnectionService;
        InitializeComponent();

        Loaded += (_, _) => ReadCoefficient();
    }

    private void ReadButton_Click(object sender, RoutedEventArgs e)
    {
        ReadCoefficient();
    }

    private void WriteButton_Click(object sender, RoutedEventArgs e)
    {
        if (!TryParseCoefficient(out var value))
        {
            StatusTextBlock.Text = "请输入有效的热流计系数。";
            CoefficientTextBox.Focus();
            CoefficientTextBox.SelectAll();
            return;
        }

        if (!_tcpDeviceConnectionService.TryWriteFloat(
                HeatFluxCoefficientRegister,
                value,
                HeatFluxCoefficientByteOrder))
        {
            StatusTextBlock.Text = "写入失败：PLC未连接或通讯异常。";
            return;
        }

        if (!TryReadCoefficient(out var readbackValue))
        {
            StatusTextBlock.Text = "写入已发送，但读回确认失败。";
            return;
        }

        CoefficientTextBox.Text = FormatCoefficient(readbackValue);
        StatusTextBlock.Text = BitConverter.SingleToInt32Bits(value) == BitConverter.SingleToInt32Bits(readbackValue)
            ? "写入成功，已读回确认。"
            : $"写入完成，读回值为 {FormatCoefficient(readbackValue)}。";
    }

    private void CloseButton_Click(object sender, RoutedEventArgs e)
    {
        Close();
    }

    private void ReadCoefficient()
    {
        if (TryReadCoefficient(out var value))
        {
            CoefficientTextBox.Text = FormatCoefficient(value);
            StatusTextBlock.Text = "已读取当前热流计系数。";
        }
        else
        {
            StatusTextBlock.Text = "读取失败：PLC未连接、通讯异常或D474数据无效。";
        }
    }

    private bool TryReadCoefficient(out float value)
    {
        value = 0;

        if (!_tcpDeviceConnectionService.TryReadFloatValues(HeatFluxCoefficientRegister, out var result))
        {
            return false;
        }

        var decodedValue = result.GetValue(HeatFluxCoefficientByteOrder);
        if (!double.IsFinite(decodedValue)
            || decodedValue < -float.MaxValue
            || decodedValue > float.MaxValue)
        {
            return false;
        }

        value = (float)decodedValue;
        return float.IsFinite(value);
    }

    private bool TryParseCoefficient(out float value)
    {
        var text = CoefficientTextBox.Text.Trim();
        return (float.TryParse(text, NumberStyles.Float, CultureInfo.CurrentCulture, out value)
                || float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out value))
            && float.IsFinite(value);
    }

    private static string FormatCoefficient(float value)
    {
        return value.ToString(CoefficientFormat, CultureInfo.InvariantCulture);
    }
}
