using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using FastReport;
using FastReport.Utils;
using ikvm.extensions;
using InABox.WPF;
using TheArtOfDev.HtmlRenderer.Core;
using TheArtOfDev.HtmlRenderer.WPF;
using Color = System.Drawing.Color;
using FontFamily = System.Drawing.FontFamily;
using FontStyle = System.Drawing.FontStyle;
using Size = System.Windows.Size;

namespace InABox.Wpf.Reports.CustomObjects;

internal class HTMLViewSmartTag : DataColumnSmartTag
{
    protected override void ItemClicked()
    {
        (Obj as HTMLView).DataColumn = DataColumn;
        base.ItemClicked();
    }

    public HTMLViewSmartTag(ComponentBase obj) : base(obj)
    {
        DataColumn = (Obj as HTMLView).DataColumn;
    }
}

public class HTMLView : ReportComponentBase
{

    [Category("Data")]
    [Editor("FastReport.TypeEditors.DataColumnEditor, FastReport", typeof(UITypeEditor))]
    public string? DataColumn { get; set; }
    
    [Category("Layout")]
    public Padding Padding { get; set; }
    
    public HTMLView()
    {
        Padding = Padding.Empty;
        SetFlags(Flags.HasSmartTag, true);
        CanGrow = true;
        Width = 10.0f;
    }
    
    public override SmartTagBase GetSmartTag()
    {
        return new HTMLViewSmartTag(this);
    }
    
    public override SizeF GetPreferredSize()
    {
        if ((Page as ReportPage).IsImperialUnitsUsed)
            return new SizeF(Page.Width / Units.Inches,  Units.Inches * 0.5f);
        return new SizeF(Page.Width / Units.Millimeters, Units.Millimeters * 10f);
    }
    
    public override void Serialize(FRWriter writer)
    {
        base.Serialize(writer);
        if (writer.DiffObject is HTMLView view)
        {
            if (Padding != view.Padding)
                writer.WriteValue("Padding", Padding);
            if (!string.Equals(DataColumn,view.DataColumn))
                writer.WriteValue("DataColumn", DataColumn);
        }
    }
    
    public override void Assign(Base source)
    {
        base.Assign(source);
        if (source is HTMLView src)
        {
            Padding = src.Padding;
            DataColumn = src.DataColumn;
        }
    }
    
    // public override void GetData()
    // {
    //     base.GetData();
    //     if (!string.IsNullOrEmpty(DataColumn))
    //     {
    //         object data = Report.GetColumnValueNullable(DataColumn);
    //         Text = data as string;
    //     }
    // }

    public override float CalcHeight()
    {
        if (IsDesigning || !CanGrow)
            return base.CalcHeight();
        var data = Report.GetColumnValueNullable(DataColumn.Replace("[","").Replace("]","")) as string;
        if (String.IsNullOrWhiteSpace(data))
            return base.CalcHeight();
        var size = HtmlRender.Measure(data, (Width - Padding.Horizontal) * 2f);
        return ((float)(size.Height + Padding.Vertical) * 2f);

    }
    
    public static BitmapSource CreateBitmap(
        int width, int height, double dpiX, double dpiY, Action<DrawingContext> render)
    {
        DrawingVisual drawingVisual = new DrawingVisual();
        using (DrawingContext drawingContext = drawingVisual.RenderOpen())
        {
            render(drawingContext);
        }

        RenderTargetBitmap bitmap = new RenderTargetBitmap(width * 2, height * 2, dpiX, dpiY, PixelFormats.Pbgra32);
            //width * (int)(dpiX/96.0), height * (int)(dpiY/96.0), 96.0, 96.0, PixelFormats.Pbgra32);
        bitmap.Render(drawingVisual);

        return bitmap;
    }
    
    public override void Draw(FRPaintEventArgs e)
    {
        base.Draw(e);
        DrawMarkers(e);
        
        IGraphics g = e.Graphics;
        
        RectangleF rect = new RectangleF(
            AbsLeft + Padding.Left,
            AbsTop + Padding.Top,
            Width - Padding.Horizontal,
            Height - Padding.Vertical
        );
        
        StringFormat format = e.Cache.GetStringFormat(
            StringAlignment.Near, 
            StringAlignment.Near, 
            StringTrimming.None, 
            StringFormatFlags.NoWrap, 
            0f, 
            48f);
            
        Font font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular);
        var textBrush = new SolidBrush(Color.Black);
        
        if (IsDesigning)
        {
            g.DrawString(DataColumn ?? "", font, textBrush, rect, format);
        }
        else
        {
            
            
            g.ResetClip();
            g.SetClip(rect);
            Report report = Report;
            if (report != null && report.SmoothGraphics)
            {
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.SmoothingMode = SmoothingMode.AntiAlias;
            }

            if (!string.IsNullOrWhiteSpace(DataColumn))
            {
                var data = Report.GetColumnValueNullable(DataColumn.Replace("[","").Replace("]","")) as string;
                BitmapSource image = CreateBitmap((int)rect.Width, (int)rect.Height, 96f, 96f,
                    //(int)(Width * e.ScaleX * (e.Graphics.DpiX / 96f)) , (int)(Height * e.ScaleY * (e.Graphics.DpiY / 96f)), e.Graphics.DpiX , e.Graphics.DpiY ,
                    context =>
                    {
                        HtmlRender.Render(context, data,0,0,(int)(Width));
                    });
                
                var bmp = ImageUtils.BitmapSourceToBitmap(image);
                bmp.Save("c:\\development\\html.png");
                g.DrawImage(bmp, rect.X, rect.Y, bmp.Width, bmp.Height);
            }
            
        }
            
        Border.Draw(e, new RectangleF(AbsLeft, AbsTop, Width, Height));


    }

    

    
}