using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Maui.Views;
using Scry.Core.Models;
using Scry.Services;
using Scry.Views;

namespace Scry.ViewModels;

public partial class ScanViewModel : ObservableObject
{
    private readonly ICardRecognitionService _recognitionService;
    private readonly ICardRepository _cardRepository;

    [ObservableProperty]
    private bool _isScanning;

    [ObservableProperty]
    private bool _isProcessing;

    [ObservableProperty]
    private string? _statusMessage;

    [ObservableProperty]
    private Card? _lastScannedCard;

    [ObservableProperty]
    private float _lastConfidence;

    [ObservableProperty]
    private bool _hasResult;

    [ObservableProperty]
    private bool _isFoil;

    public ScanViewModel(
        ICardRecognitionService recognitionService, 
        ICardRepository cardRepository)
    {
        _recognitionService = recognitionService;
        _cardRepository = cardRepository;
        StatusMessage = "Point camera at a card and tap Scan";
    }

    [RelayCommand]
    private async Task CaptureAndRecognizeAsync(CameraView cameraView)
    {
        if (IsProcessing) return;

        try
        {
            IsProcessing = true;
            StatusMessage = "Capturing...";

            // Capture image from camera
            using var imageStream = await cameraView.CaptureImage(CancellationToken.None);
            if (imageStream == null)
            {
                StatusMessage = "Failed to capture image";
                return;
            }

            StatusMessage = "Recognizing card...";

            // Copy to memory stream since the camera stream might not be seekable
            using var memoryStream = new MemoryStream();
            await imageStream.CopyToAsync(memoryStream);
            memoryStream.Position = 0;

            var result = await _recognitionService.RecognizeCardAsync(memoryStream);

            if (result.Success && result.Card != null)
            {
                LastScannedCard = result.Card;
                LastConfidence = result.Confidence;
                HasResult = true;
                StatusMessage = $"Found: {result.Card.Name} ({result.Confidence:P0})";
            }
            else
            {
                HasResult = false;
                StatusMessage = result.ErrorMessage ?? "Recognition failed";
            }
        }
        catch (Exception ex)
        {
            StatusMessage = $"Error: {ex.Message}";
            HasResult = false;
        }
        finally
        {
            IsProcessing = false;
        }
    }

    [RelayCommand]
    private async Task AddToCollectionAsync()
    {
        if (LastScannedCard == null) return;

        _cardRepository.Add(LastScannedCard, 1, IsFoil);

        var foilText = IsFoil ? " (Foil)" : "";
        StatusMessage = $"Added {LastScannedCard.Name}{foilText} to collection!";

        // Reset for next scan
        await Task.Delay(1500);
        HasResult = false;
        LastScannedCard = null;
        IsFoil = false;
        StatusMessage = "Point camera at a card and tap Scan";
    }

    [RelayCommand]
    private void CancelResult()
    {
        HasResult = false;
        LastScannedCard = null;
        IsFoil = false;
        StatusMessage = "Point camera at a card and tap Scan";
    }

    [RelayCommand]
    private async Task ViewCardDetailsAsync()
    {
        if (LastScannedCard == null) return;

        await Shell.Current.GoToAsync($"{nameof(CardDetailPage)}?cardId={LastScannedCard.Id}");
    }
}
