using System;
using System.Threading.Tasks;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.Input;
using FootwearTest.Models;
using FootwearTest.Services;
using Microsoft.Extensions.Logging;

namespace FootwearTest.ViewModels;

public partial class MainWindowViewModel : ViewModelBase
{
    private readonly IDeviceClient _deviceClient;
    private readonly ILogger<MainWindowViewModel> _logger;
    private readonly DispatcherTimer _pollTimer;
    private bool _snapshotReadFailed;

    public MainWindowViewModel(
        IDeviceClient deviceClient,
        ILogger<MainWindowViewModel> logger,
        DashboardViewModel dashboard,
        MethodAViewModel methodA,
        MethodBViewModel methodB,
        HistoryViewModel history,
        ReportViewModel report,
        SettingsViewModel settings)
    {
        _deviceClient = deviceClient;
        _logger = logger;
        Dashboard = dashboard;
        MethodA = methodA;
        MethodB = methodB;
        History = history;
        Report = report;
        Settings = settings;
        CurrentPage = Dashboard;
        CurrentPageTitle = "运行总览";
        ShowDashboardCommand = new RelayCommand(ShowDashboard);
        ShowMethodACommand = new RelayCommand(ShowMethodA);
        ShowMethodBCommand = new RelayCommand(ShowMethodB);
        ShowHistoryCommand = new RelayCommand(ShowHistory);
        ShowReportCommand = new RelayCommand(ShowReport);
        ShowSettingsCommand = new RelayCommand(ShowSettings);
        ConnectDeviceCommand = new AsyncRelayCommand(ConnectDeviceAsync);
        DisconnectDeviceCommand = new AsyncRelayCommand(DisconnectDeviceAsync);

        _pollTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
        _pollTimer.Tick += async (_, _) => await RefreshSnapshotAsync();
        _pollTimer.Start();
        _logger.LogInformation("Main window view model initialized");
    }

    public DashboardViewModel Dashboard { get; }
    public MethodAViewModel MethodA { get; }
    public MethodBViewModel MethodB { get; }
    public HistoryViewModel History { get; }
    public ReportViewModel Report { get; }
    public SettingsViewModel Settings { get; }
    public IRelayCommand ShowDashboardCommand { get; }
    public IRelayCommand ShowMethodACommand { get; }
    public IRelayCommand ShowMethodBCommand { get; }
    public IRelayCommand ShowHistoryCommand { get; }
    public IRelayCommand ShowReportCommand { get; }
    public IRelayCommand ShowSettingsCommand { get; }
    public IAsyncRelayCommand ConnectDeviceCommand { get; }
    public IAsyncRelayCommand DisconnectDeviceCommand { get; }

    private ViewModelBase _currentPage = null!;
    private string _currentPageTitle = "";
    private DeviceSnapshot _snapshot = DeviceSnapshot.Initial;
    private string _connectionText = "未连接";
    private string _selectedPageKey = "Dashboard";

    public ViewModelBase CurrentPage
    {
        get => _currentPage;
        set => SetProperty(ref _currentPage, value);
    }

    public string CurrentPageTitle
    {
        get => _currentPageTitle;
        set => SetProperty(ref _currentPageTitle, value);
    }

    public DeviceSnapshot Snapshot
    {
        get => _snapshot;
        set => SetProperty(ref _snapshot, value);
    }

    public string ConnectionText
    {
        get => _connectionText;
        set => SetProperty(ref _connectionText, value);
    }

    public bool IsDashboardSelected => _selectedPageKey == "Dashboard";

    public bool IsMethodASelected => _selectedPageKey == "MethodA";

    public bool IsMethodBSelected => _selectedPageKey == "MethodB";

    public bool IsHistorySelected => _selectedPageKey == "History";

    public bool IsReportSelected => _selectedPageKey == "Report";

    public bool IsSettingsSelected => _selectedPageKey == "Settings";

    private void ShowDashboard() => Navigate(Dashboard, "运行总览", "Dashboard");

    private void ShowMethodA() => Navigate(MethodA, "方法 A - 热阻/湿阻", "MethodA");

    private void ShowMethodB() => Navigate(MethodB, "方法 B - 吸湿透水汽/保暖", "MethodB");

    private void ShowHistory() => Navigate(History, "历史记录", "History");

    private void ShowReport() => Navigate(Report, "试验报告", "Report");

    private void ShowSettings() => Navigate(Settings, "系统设置", "Settings");

    private async Task ConnectDeviceAsync()
    {
        try
        {
            _logger.LogInformation("Operator requested device connection");
            await _deviceClient.ConnectAsync();
            await RefreshSnapshotAsync();
        }
        catch (Exception ex)
        {
            ConnectionText = $"连接失败: {ex.Message}";
            _logger.LogError(ex, "Device connection command failed");
        }
    }

    private async Task DisconnectDeviceAsync()
    {
        try
        {
            _logger.LogInformation("Operator requested device disconnection");
            await _deviceClient.DisconnectAsync();
            ConnectionText = _deviceClient.ConnectionText;
        }
        catch (Exception ex)
        {
            ConnectionText = $"断开失败: {ex.Message}";
            _logger.LogError(ex, "Device disconnection command failed");
        }
    }

    private void Navigate(ViewModelBase page, string title, string pageKey)
    {
        _logger.LogInformation("Navigating. PageTitle={PageTitle}", title);
        CurrentPage = page;
        CurrentPageTitle = title;
        SetSelectedPageKey(pageKey);
    }

    private void SetSelectedPageKey(string pageKey)
    {
        if (_selectedPageKey == pageKey)
        {
            return;
        }

        _selectedPageKey = pageKey;
        OnPropertyChanged(nameof(IsDashboardSelected));
        OnPropertyChanged(nameof(IsMethodASelected));
        OnPropertyChanged(nameof(IsMethodBSelected));
        OnPropertyChanged(nameof(IsHistorySelected));
        OnPropertyChanged(nameof(IsReportSelected));
        OnPropertyChanged(nameof(IsSettingsSelected));
    }

    private async Task RefreshSnapshotAsync()
    {
        try
        {
            if (_deviceClient.IsConnected)
            {
                Snapshot = await _deviceClient.ReadSnapshotAsync();
                Dashboard.Snapshot = Snapshot;
                if (_snapshotReadFailed)
                {
                    _logger.LogInformation("Realtime snapshot refresh recovered. ConnectionText={ConnectionText}", _deviceClient.ConnectionText);
                    _snapshotReadFailed = false;
                }
            }

            ConnectionText = _deviceClient.ConnectionText;
        }
        catch (Exception ex)
        {
            ConnectionText = $"刷新失败: {ex.Message}";
            if (!_snapshotReadFailed)
            {
                _logger.LogError(ex, "Realtime snapshot refresh failed");
                _snapshotReadFailed = true;
            }
        }
    }

}
