using Microsoft.Maui.Graphics;
using Microsoft.Maui.Graphics.Skia;
using System.Collections.Generic;

namespace LSFE.MobApp.Views.CoveragePlan
{
    public class SignaturePadView : GraphicsView
    {
        private readonly List<List<PointF>> _strokes = new();
        private List<PointF> _currentStroke;
        private readonly SignatureDrawable _drawable;

        public SignaturePadView()
        {
            _drawable = new SignatureDrawable(_strokes, () => _currentStroke);
            Drawable = _drawable;
            BackgroundColor = Colors.White;

            // Set minimum size to ensure it's touchable
            MinimumHeightRequest = 200;
            MinimumWidthRequest = 200;

            StartInteraction += OnStartInteraction;
            DragInteraction += OnDragInteraction;
            EndInteraction += OnEndInteraction;
        }

        private void OnStartInteraction(object sender, TouchEventArgs e)
        {
            if (e.Touches.Length > 0)
            {
                _currentStroke = new List<PointF> { e.Touches[0] };
                Invalidate();
            }
        }

        private void OnDragInteraction(object sender, TouchEventArgs e)
        {
            if (_currentStroke != null && e.Touches.Length > 0)
            {
                foreach (var touch in e.Touches)
                {
                    _currentStroke.Add(touch);
                }
                Invalidate();
            }
        }

        private void OnEndInteraction(object sender, TouchEventArgs e)
        {
            if (_currentStroke != null && _currentStroke.Count > 0)
            {
                _strokes.Add(new List<PointF>(_currentStroke));
                _currentStroke = null;
                Invalidate();
            }
        }

        public void Clear()
        {
            _strokes.Clear();
            _currentStroke = null;
            Invalidate();
        }

        public bool IsEmpty()
        {
            return _strokes.Count == 0 && (_currentStroke == null || _currentStroke.Count == 0);
        }

        public async Task<byte[]> GetSignatureImageAsync()
        {
            // if nothing drawn, return null
            if (IsEmpty())
                return null;

            // Determine size (fall back to default if not laid out yet)
            var width = (int)Width;
            var height = (int)Height;
            if (width <= 0 || height <= 0)
            {
                width = 800;
                height = 400;
            }

            // Choose display scale (1.0f is fine; you can use DeviceDisplay.MainDisplayInfo.Density if needed)
            float displayScale = 1.0f;

            try
            {
                // Create Skia bitmap export context
                using var bmp = new SkiaBitmapExportContext(width, height, displayScale, dpi: 72, disposeBitmap: true, transparent: false);
                var canvas = bmp.Canvas;

                // Draw white background
                canvas.FillColor = Colors.White;
                canvas.FillRectangle(0, 0, width, height);

                // Draw stored strokes
                _drawable.Draw(canvas, new RectF(0, 0, width, height));

                // Write PNG to memory stream
                using var ms = new MemoryStream();
                bmp.WriteToStream(ms);

                return await Task.FromResult(ms.ToArray());
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"Error creating signature image: {ex.Message}");
                return null;
            }
        }

        private class SignatureDrawable : IDrawable
        {
            private readonly List<List<PointF>> _strokes;
            private readonly Func<List<PointF>> _getCurrentStroke;

            public SignatureDrawable(List<List<PointF>> strokes, Func<List<PointF>> getCurrentStroke)
            {
                _strokes = strokes;
                _getCurrentStroke = getCurrentStroke;
            }

            public void Draw(ICanvas canvas, RectF dirtyRect)
            {
                canvas.StrokeColor = Colors.Black;
                canvas.StrokeSize = 3;
                canvas.StrokeLineCap = LineCap.Round;
                canvas.StrokeLineJoin = LineJoin.Round;

                // Draw completed strokes
                foreach (var stroke in _strokes)
                {
                    DrawStroke(canvas, stroke);
                }

                // Draw current stroke being drawn in real-time
                var currentStroke = _getCurrentStroke();
                if (currentStroke != null && currentStroke.Count > 0)
                {
                    DrawStroke(canvas, currentStroke);
                }
            }

            private void DrawStroke(ICanvas canvas, List<PointF> stroke)
            {
                if (stroke.Count > 1)
                {
                    var path = new PathF();
                    path.MoveTo(stroke[0]);

                    for (int i = 1; i < stroke.Count; i++)
                    {
                        path.LineTo(stroke[i]);
                    }

                    canvas.DrawPath(path);
                }
                else if (stroke.Count == 1)
                {
                    // Draw single point as small dot
                    var p = stroke[0];
                    canvas.FillRectangle(p.X - 1.5f, p.Y - 1.5f, 3, 3);
                }
            }
        }
    }
}
