using System.Globalization;
using System.Numerics;
using System.Text;
using ICU4N.Text;
using ImageMagick;
using Kynareth.Models;
using Microsoft.AspNetCore.Mvc;

namespace Kynareth.Managers;

public static partial class ImageManager
{
	public static void Configure(IConfiguration configuration, IWebHostEnvironment appEnvironment)
	{
		ConfigureGeneration(configuration, appEnvironment);
		ConfigureManipulation(configuration, appEnvironment);
	}
	
	static BreakIterator lineBreakIterator = BreakIterator.GetLineInstance(CultureInfo.InvariantCulture);
	
	private static ObjectResult GetResult(int statusCode, object data) => new(data) { StatusCode = statusCode };

	private static string GetText(string text)
	{
		StringBuilder newText = new();
		
		// set the text to be broken
		lineBreakIterator.SetText(text);

		// get the first boundary
		int start = lineBreakIterator.First();

		// iterate over all boundaries
		for (int end = lineBreakIterator.Next(); end != BreakIterator.Done; start = end, end = lineBreakIterator.Next())
		{
			// get the current line
			string line = text.Substring(start, end - start);

			// do something with the line
			newText.AppendLine(line);
			Console.WriteLine(line);
		}

		return newText.ToString();
	}

	public static MagickImage WriteText(this MagickImage image, string text, PositionRect rect, MagickColor fontColor, Encoding encoding, string font = "Impact", int strokeWidth = 2, MagickColor? strokeColor = null, bool wrapText = true, Gravity textGravity = Gravity.Northwest)
	{
		using var label = new MagickImage($"{(wrapText ? "caption" : "label")}:{text}", new MagickReadSettings()
		{
			Width = rect.Width,
			Height = rect.Height,
			BackgroundColor = MagickColors.Transparent,
			FillColor = fontColor,
			TextGravity = textGravity,
			Font = font,
			TextEncoding = encoding,
			StrokeColor = new MagickColor(strokeColor ?? MagickColors.Black),
			StrokeWidth = strokeWidth,
		});
		
		image.Composite(label, rect.X, rect.Y, CompositeOperator.Over);
		
		return image;
	}

	public static MagickImage WriteText(this MagickImage image, string text, PositionRect rect, MagickColor fontColor, Encoding encoding, double fontSize, string font = "Impact", int strokeWidth = 2, MagickColor? strokeColor = null, bool wrapText = true, Gravity textGravity = Gravity.Northwest)
	{
		using var label = new MagickImage($"{(wrapText ? "caption" : "label")}:{text}", new MagickReadSettings()
		{
			Width = rect.Width,
			Height = rect.Height,
			BackgroundColor = MagickColors.Transparent,
			FillColor = fontColor,
			TextGravity = textGravity,
			FontPointsize = fontSize,
			Font = font,
			TextEncoding = encoding,
			StrokeColor = new MagickColor(strokeColor ?? MagickColors.Black),
			StrokeWidth = strokeWidth
		});

		image.Composite(label, rect.X, rect.Y, CompositeOperator.Over);
		
		return image;
	}
	
	public static MagickImage WriteText(this MagickImage image, string text, Vector2 position, MagickColor fontColor, Encoding encoding, string font = "Impact", int strokeWidth = 2, MagickColor? strokeColor = null, bool wrapText = true, Gravity textGravity = Gravity.Northwest)
	{
		using var label = new MagickImage($"{(wrapText ? "caption" : "label")}:{text}", new MagickReadSettings()
		{
			Width = image.Width,
			Height = image.Height,
			BackgroundColor = MagickColors.Transparent,
			FillColor = fontColor,
			TextGravity = textGravity,
			Font = font,
			TextEncoding = encoding,
			StrokeColor = new MagickColor(strokeColor ?? MagickColors.Black),
			StrokeWidth = strokeWidth
		});

		image.Composite(label, (int)position.X, (int)position.Y, CompositeOperator.Over);
		
		return image;
	}
	
	public static MagickImage WriteText(this MagickImage image, string text, Vector2 position, MagickColor fontColor, Encoding encoding, double fontSize, string font = "Impact", int strokeWidth = 2, MagickColor? strokeColor = null, bool wrapText = true, Gravity textGravity = Gravity.Northwest)
	{
		using var label = new MagickImage($"{(wrapText ? "caption" : "label")}:{text}", new MagickReadSettings()
		{
			Width = image.Width,
			Height = image.Height,
			BackgroundColor = MagickColors.Transparent,
			FillColor = fontColor,
			TextGravity = textGravity,
			FontPointsize = fontSize,
			Font = font,
			TextEncoding = encoding,
			StrokeColor = new MagickColor(strokeColor ?? MagickColors.Black),
			StrokeWidth = strokeWidth
		});

		image.Composite(label, (int)position.X, (int)position.Y, CompositeOperator.Over);
		
		return image;
	}
	
	public static MagickImage WriteText(this MagickImage image, string text, PointD position, MagickColor fontColor, Encoding encoding, string font = "Impact", int strokeWidth = 2, MagickColor? strokeColor = null, bool wrapText = true, Gravity textGravity = Gravity.Northwest)
	{
		using var label = new MagickImage($"{(wrapText ? "caption" : "label")}:{text}", new MagickReadSettings()
		{
			Width = image.Width,
			Height = image.Height,
			BackgroundColor = MagickColors.Transparent,
			FillColor = fontColor,
			TextGravity = textGravity,
			Font = font,
			TextEncoding = encoding,
			StrokeColor = new MagickColor(strokeColor ?? MagickColors.Black),
			StrokeWidth = strokeWidth
		});

		image.Composite(label, (int)position.X, (int)position.Y, CompositeOperator.Over);
		
		return image;
	}
	
	public static MagickImage WriteText(this MagickImage image, string text, PointD position, MagickColor fontColor, Encoding encoding, double fontSize, string font = "Impact", int strokeWidth = 2, MagickColor? strokeColor = null, bool wrapText = true, Gravity textGravity = Gravity.Northwest)
	{
		using var label = new MagickImage($"{(wrapText ? "caption" : "label")}:{text}", new MagickReadSettings()
		{
			Width = image.Width,
			Height = image.Height,
			BackgroundColor = MagickColors.Transparent,
			FillColor = fontColor,
			TextGravity = textGravity,
			FontPointsize = fontSize,
			Font = font,
			TextEncoding = encoding,
			StrokeColor = new MagickColor(strokeColor ?? MagickColors.Black),
			StrokeWidth = strokeWidth
		});

		image.Composite(label, (int)position.X, (int)position.Y, CompositeOperator.Over);
		
		return image;
	}
	
	public static MagickImage WriteText(this MagickImage image, string text, int x, int y, MagickColor fontColor, Encoding encoding, string font = "Impact", int strokeWidth = 2, MagickColor? strokeColor = null, bool wrapText = true, Gravity textGravity = Gravity.Northwest)
	{
		using var label = new MagickImage($"{(wrapText ? "caption" : "label")}:{text}", new MagickReadSettings()
		{
			Width = image.Width,
			Height = image.Height,
			BackgroundColor = MagickColors.Transparent,
			FillColor = fontColor,
			TextGravity = textGravity,
			Font = font,
			TextEncoding = encoding,
			StrokeColor = new MagickColor(strokeColor ?? MagickColors.Black),
			StrokeWidth = strokeWidth
		});

		image.Composite(label, x, y, CompositeOperator.Over);
		
		return image;
	}
	
	public static MagickImage WriteText(this MagickImage image, string text, int x, int y, MagickColor fontColor, Encoding encoding, double fontSize, string font = "Impact", int strokeWidth = 2, MagickColor? strokeColor = null, bool wrapText = true, Gravity textGravity = Gravity.Northwest)
	{
		using var label = new MagickImage($"{(wrapText ? "caption" : "label")}:{text}", new MagickReadSettings()
		{
			Width = image.Width,
			Height = image.Height,
			BackgroundColor = MagickColors.Transparent,
			FillColor = fontColor,
			TextGravity = textGravity,
			FontPointsize = fontSize,
			Font = font,
			TextEncoding = encoding,
			StrokeColor = new MagickColor(strokeColor ?? MagickColors.Black),
			StrokeWidth = strokeWidth
		});

		image.Composite(label, x, y, CompositeOperator.Over);
		
		return image;
	}
}