using System.Diagnostics;
using LindtLeerformPlugin.Services;
using OpenCvSharp;
using Serilog;
using VisionBuilder.UI.Common.Processing;
using VisionBuilder.UI.Common.ViewModel.Classes;

namespace LindtLeerformPlugin;

public class LeerformRecognitionControl : BaseRecognitionControl
{
    private readonly IImageSource _imageSource;
    private Mat? _cameraMatrix;
    private Mat? _distCoeffs;

    public LeerformRecognitionControl(
        LeerformRecognitionControlSettings settings,
        IImageSource imageSource,
        ILoadingService loadingService) : base(settings, loadingService)
    {
        _imageSource = imageSource;
    }

    public override List<RecipeData> GetRecipesData()
    {
        return [new RecipeData { RecipeName = "Default" }];
    }

    protected override void Initialize(RecipeData currentRecipe)
    {
        _cameraMatrix?.Dispose();
        _distCoeffs?.Dispose();
        _cameraMatrix = null;
        _distCoeffs = null;

        var calibrationData = CalibrationDataStore.Load();
        if (calibrationData != null)
        {
            (_cameraMatrix, _distCoeffs) = CameraCalibrationService.LoadCalibrationMats(calibrationData);
            Log.Information("Calibration data loaded (RMS error: {RmsError:F3})", calibrationData.RmsError);
        }
    }

    protected override void WarmUp()
    {
    }

    protected override (Mat originalImage, Mat analysisImage, TimeSpan processingTime, TimeSpan acquisitionTime, string[] errorNames)?
        ProcessImage(CancellationToken token)
    {
        var sw = Stopwatch.StartNew();
        var image = _imageSource.GetImage(token).Result;
        

        if (image == null)
            return null;

        var acquisitionTime = sw.Elapsed;

        if (_cameraMatrix != null && _distCoeffs != null)
        {
            
            var undistorted = new Mat();
            Cv2.Undistort(image, undistorted, _cameraMatrix, _distCoeffs);
            sw.Stop();

            return (image, undistorted, sw.Elapsed, acquisitionTime, []);
        }
        sw.Stop();
        return (image, image, TimeSpan.Zero, acquisitionTime, []);
    }
}
