using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Emgu.CV;
using Emgu.CV.Structure;

namespace XplorePlane.Services
{
    public static class ImageConverter
    {
        public static byte[] ExtractGray8Pixels(BitmapSource bitmapSource, out int width, out int height)
        {
            if (bitmapSource == null) throw new ArgumentNullException(nameof(bitmapSource));

            var formatted = new FormatConvertedBitmap(bitmapSource, PixelFormats.Gray8, null, 0);
            width = formatted.PixelWidth;
            height = formatted.PixelHeight;
            int stride = width;
            byte[] pixels = new byte[height * stride];
            formatted.CopyPixels(pixels, stride, 0);
            return pixels;
        }

        public static Image<Gray, byte> ToEmguCV(BitmapSource bitmapSource)
        {
            if (bitmapSource == null) throw new ArgumentNullException(nameof(bitmapSource));

            var formatted = new FormatConvertedBitmap(bitmapSource, PixelFormats.Gray8, null, 0);
            int width = formatted.PixelWidth;
            int height = formatted.PixelHeight;
            int stride = width;
            byte[] pixels = new byte[height * stride];
            formatted.CopyPixels(pixels, stride, 0);

            var image = new Image<Gray, byte>(width, height);
            image.Bytes = pixels;
            return image;
        }

        public static Image<Gray, byte> ToEmguCVFromPixels(byte[] pixels, int width, int height)
        {
            var image = new Image<Gray, byte>(width, height);
            image.Bytes = pixels;
            return image;
        }

        public static BitmapSource ToBitmapSource(Image<Gray, byte> emguImage)
        {
            if (emguImage == null) throw new ArgumentNullException(nameof(emguImage));

            int width = emguImage.Width;
            int height = emguImage.Height;
            int stride = width;
            byte[] pixels = emguImage.Bytes;

            return BitmapSource.Create(width, height, 96, 96, PixelFormats.Gray8, null, pixels, stride);
        }

        public static Image<Gray, ushort> ToEmguCV16(BitmapSource bitmapSource)
        {
            if (bitmapSource == null) throw new ArgumentNullException(nameof(bitmapSource));

            var formatted = new FormatConvertedBitmap(bitmapSource, PixelFormats.Gray16, null, 0);
            int width = formatted.PixelWidth;
            int height = formatted.PixelHeight;
            int stride = width * 2; // 2 bytes per pixel for 16-bit
            byte[] rawBytes = new byte[height * stride];
            formatted.CopyPixels(rawBytes, stride, 0);

            ushort[] pixels = new ushort[width * height];
            Buffer.BlockCopy(rawBytes, 0, pixels, 0, rawBytes.Length);

            var image = new Image<Gray, ushort>(width, height);
            // Copy pixel data row by row
            for (int y = 0; y < height; y++)
                for (int x = 0; x < width; x++)
                    image.Data[y, x, 0] = pixels[y * width + x];

            return image;
        }
    }
}
