using System;
using System.Collections.Immutable;
using System.Globalization;
using System.Xml;

namespace AppsheetEpplus;

public class ExcelDxfStyleConditionalFormatting : DxfStyleBase<ExcelDxfStyleConditionalFormatting> {
  private readonly DxfStyleXmlHelper _helper;

  private class DxfStyleXmlHelper(XmlNamespaceManager nameSpaceManager, XmlNode topNode)
      : XmlHelper(nameSpaceManager, topNode) {
    protected override ImmutableArray<string> SchemaNodeOrder { get; } = [
      "font",
      "numFmt",
      "fill",
      "border",
    ];
  }

  internal ExcelDxfStyleConditionalFormatting(
      XmlNamespaceManager nameSpaceManager,
      XmlNode topNode,
      ExcelStyles styles)
      : base(styles) {
    NumberFormat = new(_styles);
    Font = new(_styles);
    Border = new(_styles);
    Fill = new(_styles);
    if (topNode != null) {
      _helper = new(nameSpaceManager, topNode);
      NumberFormat.NumFmtID = _helper.GetXmlNodeInt("d:numFmt/@numFmtId");
      NumberFormat.Format = _helper.GetXmlNodeString("d:numFmt/@formatCode");
      if (NumberFormat.NumFmtID < 164 && string.IsNullOrEmpty(NumberFormat.Format)) {
        NumberFormat.Format = ExcelNumberFormat.GetFromBuildInFromId(NumberFormat.NumFmtID);
      }

      Font.Bold = _helper.GetXmlNodeBoolNullable("d:font/d:b/@val");
      Font.Italic = _helper.GetXmlNodeBoolNullable("d:font/d:i/@val");
      Font.Strike = _helper.GetXmlNodeBoolNullable("d:font/d:strike");
      Font.Underline = GetUnderLineEnum(_helper.GetXmlNodeString("d:font/d:u/@val"));
      Font.Color = GetColor(_helper, "d:font/d:color");

      Border.Left = GetBorderItem(_helper, "d:border/d:left");
      Border.Right = GetBorderItem(_helper, "d:border/d:right");
      Border.Bottom = GetBorderItem(_helper, "d:border/d:bottom");
      Border.Top = GetBorderItem(_helper, "d:border/d:top");

      Fill.PatternType = GetPatternTypeEnum(
          _helper.GetXmlNodeString("d:fill/d:patternFill/@patternType"));
      Fill.BackgroundColor = GetColor(_helper, "d:fill/d:patternFill/d:bgColor/");
      Fill.PatternColor = GetColor(_helper, "d:fill/d:patternFill/d:fgColor/");
    } else {
      _helper = new(nameSpaceManager, null);
    }
  }

  private ExcelDxfBorderItem GetBorderItem(XmlHelper helper, string path) {
    ExcelDxfBorderItem bi = new ExcelDxfBorderItem(_styles);
    bi.Style = GetBorderStyleEnum(helper.GetXmlNodeString(path + "/@style"));
    bi.Color = GetColor(helper, path + "/d:color");
    return bi;
  }

  private ExcelBorderStyle GetBorderStyleEnum(string style) =>
    Enum.TryParse<ExcelBorderStyle>(style, true, out var result) ? result : ExcelBorderStyle.None;

  private ExcelFillStyle GetPatternTypeEnum(string patternType) =>
    Enum.TryParse<ExcelFillStyle>(patternType, true, out var result) ? result : ExcelFillStyle.None;

  private ExcelDxfColor GetColor(XmlHelper helper, string path) {
    ExcelDxfColor ret = new ExcelDxfColor(_styles);
    ret.Theme = helper.GetXmlNodeIntNull(path + "/@theme");
    ret.Index = helper.GetXmlNodeIntNull(path + "/@indexed");
    ret.Rgb = helper.GetXmlNodeString(path + "/@rgb");
    ret.Auto = helper.GetXmlNodeBoolNullable(path + "/@auto");
    ret.Tint = helper.GetXmlNodeDoubleNull(path + "/@tint");
    return ret;
  }

  private ExcelUnderLineType? GetUnderLineEnum(string value) {
    switch (value.ToLower(CultureInfo.InvariantCulture)) {
      case "single":
        return ExcelUnderLineType.Single;
      case "double":
        return ExcelUnderLineType.Double;
      case "singleaccounting":
        return ExcelUnderLineType.SingleAccounting;
      case "doubleaccounting":
        return ExcelUnderLineType.DoubleAccounting;
      default:
        return null;
    }
  }

  internal int DxfId { get; set; }

  public ExcelDxfFontBase Font { get; set; }

  public ExcelDxfNumberFormat NumberFormat { get; set; }

  public ExcelDxfFill Fill { get; set; }

  public ExcelDxfBorderBase Border { get; set; }

  protected internal override string Id =>
    NumberFormat.Id + Font.Id + Border.Id + Fill.Id + (AllowChange ? "" : DxfId.ToString()); //If allowchange is false we add the dxfID to ensure it's not used when conditional formatting is updated);

  protected internal override ExcelDxfStyleConditionalFormatting Clone() {
    var s = new ExcelDxfStyleConditionalFormatting(_helper.NameSpaceManager, null, _styles);
    s.Font = Font.Clone();
    s.NumberFormat = NumberFormat.Clone();
    s.Fill = Fill.Clone();
    s.Border = Border.Clone();
    return s;
  }

  protected internal override void CreateNodes(XmlHelper helper, string path) {
    if (Font.HasValue) {
      Font.CreateNodes(helper, "d:font");
    }
    if (NumberFormat.HasValue) {
      NumberFormat.CreateNodes(helper, "d:numFmt");
    }
    if (Fill.HasValue) {
      Fill.CreateNodes(helper, "d:fill");
    }
    if (Border.HasValue) {
      Border.CreateNodes(helper, "d:border");
    }
  }

  protected internal override bool HasValue =>
    Font.HasValue || NumberFormat.HasValue || Fill.HasValue || Border.HasValue;
}
