using SvgPathProperties;
using System.Collections.Generic;
using System.Text;
using System.Xml.Linq;

namespace PCUT.Extensions.Converters
{
    internal class RectElementConverter : PathConverter
    {
        private static readonly string[] RectExcludedAttributes = new[] { "transform", "x", "y", "width", "height", "rx", "ry" };
        protected override IEnumerable<string> ExcludedAttributes => RectExcludedAttributes;

        internal RectElementConverter()
        {
        }

        protected override bool CanApply(XElement element) => element.Name.LocalName == "rect";

        protected override SvgPath GetPathFromElement(XElement element)
        {
            var x = double.Parse(element.Attribute("x")?.Value ?? "0");
            var y = double.Parse(element.Attribute("y")?.Value ?? "0");
            var width = double.Parse(element.Attribute("width")?.Value ?? "0");
            var height = double.Parse(element.Attribute("height")?.Value ?? "0");
            var (rx, ry) = CalculateRoundedCorner(element.Attribute("rx")?.Value, element.Attribute("ry")?.Value);
            if (width == 0 || height == 0)
                return null;

            var hasRoundCorner = rx > 0 && ry > 0;
            var arcCommonParam = $"{rx} {ry} 0 0 1 ";
            var builder = new StringBuilder();
            builder.Append("M ").Append($"{x + rx} {y} ");

            builder.Append("H ").Append($"{x + width - rx}");
            if (hasRoundCorner)
                builder.Append("A ").Append($"{arcCommonParam}").Append($"{x + width} {y + ry} ");

            builder.Append("V ").Append($"{y + height - ry} ");
            if (hasRoundCorner)
                builder.Append("A ").Append($"{arcCommonParam}").Append($"{x + width - rx} {y + height} ");

            builder.Append("H ").Append($"{x + rx}");
            if (hasRoundCorner)
                builder.Append("A ").Append($"{arcCommonParam}").Append($"{x} {y + height - ry} ");

            builder.Append("V ").Append($"{y + ry} ");
            if (hasRoundCorner)
                builder.Append("A ").Append($"{arcCommonParam}").Append($"{x + rx} {y} ");

            builder.Append("Z");
            return new SvgPath(builder.ToString(), unarc: true);
        }

        private (double Rx, double Ry) CalculateRoundedCorner(string rxValue, string ryValue)
        {
            if (rxValue == null) rxValue = "auto";
            if (ryValue == null) ryValue = "auto";

            if (rxValue == "auto" && ryValue == "auto")
                return (0, 0);

            double? rx = null, ry = null;
            if (rxValue != "auto")
                rx = double.Parse(rxValue);
            if (ryValue != "auto")
                ry = double.Parse(ryValue);

            if (rx == null)
                rx = ry;
            else if (ry == null)
                ry = rx;

            return (rx.Value, ry.Value);
        }
    }
}
