/*******************************************************************************
 * You may amend and distribute as you like, but don't remove this header!
 *
 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
 * See http://www.codeplex.com/EPPlus for details.
 *
 * Copyright (C) 2011  Jan Källman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
 *
 * All code and executables are provided "as is" with no warranty either express or implied.
 * The author accepts no liability for any damage or loss of business that this product may cause.
 *
 * Code change notes:
 *
 * Author							Change						Date
 * ******************************************************************************
 * Jan Källman		Added		21-MAR-2011
 * Jan Källman		License changed GPL-->LGPL 2011-12-16
 *******************************************************************************/

using System;
using System.Globalization;
using System.Xml;

namespace AppsheetEpplus;

/// <summary>
/// Defines the axis for a PivotTable
/// </summary>
public enum ePivotFieldAxis {
  /// <summary>
  /// None
  /// </summary>
  None = -1,

  /// <summary>
  /// Column axis
  /// </summary>
  Column,

  /// <summary>
  /// Page axis (Include Count Filter)
  ///
  /// </summary>
  Page,

  /// <summary>
  /// Row axis
  /// </summary>
  Row,

  /// <summary>
  /// Values axis
  /// </summary>
  Values,
}

/// <summary>
/// Build-in table row functions
/// </summary>
public enum DataFieldFunctions {
  Average,
  Count,
  CountNums,
  Max,
  Min,
  Product,
  None,
  StdDev,
  StdDevP,
  Sum,
  Var,
  VarP,
}

/// <summary>
/// Defines the data formats for a field in the PivotTable
/// </summary>
public enum eShowDataAs {
  /// <summary>
  /// Indicates the field is shown as the "difference from" a value.
  /// </summary>
  Difference,

  /// <summary>
  /// Indicates the field is shown as the "index.
  /// </summary>
  Index,

  /// <summary>
  /// Indicates that the field is shown as its normal datatype.
  /// </summary>
  Normal,

  /// <summary>
  /// /Indicates the field is show as the "percentage of" a value
  /// </summary>
  Percent,

  /// <summary>
  /// Indicates the field is shown as the "percentage difference from" a value.
  /// </summary>
  PercentDiff,

  /// <summary>
  /// Indicates the field is shown as the percentage of column.
  /// </summary>
  PercentOfCol,

  /// <summary>
  /// Indicates the field is shown as the percentage of row
  /// </summary>
  PercentOfRow,

  /// <summary>
  /// Indicates the field is shown as percentage of total.
  /// </summary>
  PercentOfTotal,

  /// <summary>
  /// Indicates the field is shown as running total in the table.
  /// </summary>
  RunTotal,
}

/// <summary>
/// Built-in subtotal functions
/// </summary>
[Flags]
public enum eSubTotalFunctions {
  None = 1,
  Count = 2,
  CountA = 4,
  Avg = 8,
  Default = 16,
  Min = 32,
  Max = 64,
  Product = 128,
  StdDev = 256,
  StdDevP = 512,
  Sum = 1024,
  Var = 2048,
  VarP = 4096,
}

/// <summary>
/// Data grouping
/// </summary>
[Flags]
public enum eDateGroupBy {
  Years = 1,
  Quarters = 2,
  Months = 4,
  Days = 8,
  Hours = 16,
  Minutes = 32,
  Seconds = 64,
}

/// <summary>
/// Sorting
/// </summary>
public enum eSortType {
  None,
  Ascending,
  Descending,
}

/// <summary>
/// A pivot table field.
/// </summary>
public class ExcelPivotTableField : XmlHelper {
  internal ExcelPivotTable _table;

  internal ExcelPivotTableField(
      XmlNamespaceManager ns,
      XmlNode topNode,
      ExcelPivotTable table,
      int index,
      int baseIndex)
      : base(ns, topNode) {
    Index = index;
    BaseIndex = baseIndex;
    _table = table;
  }

  public int Index { get; set; }

  internal int BaseIndex { get; set; }

  /// <summary>
  /// Name of the field
  /// </summary>
  public string Name {
    get {
      string v = GetXmlNodeString("@name");
      if (v == "") {
        return _cacheFieldHelper.GetXmlNodeString("@name");
      }
      return v;
    }
    set => SetXmlNodeString("@name", value);
  }

  /// <summary>
  /// Compact mode
  /// </summary>
  public bool Compact {
    get => GetXmlNodeBool("@compact");
    set => SetXmlNodeBool("@compact", value);
  }

  /// <summary>
  /// A boolean that indicates whether the items in this field should be shown in Outline form
  /// </summary>
  public bool Outline {
    get => GetXmlNodeBool("@outline");
    set => SetXmlNodeBool("@outline", value);
  }

  /// <summary>
  /// The custom text that is displayed for the subtotals label
  /// </summary>
  public bool SubtotalTop {
    get => GetXmlNodeBool("@subtotalTop");
    set => SetXmlNodeBool("@subtotalTop", value);
  }

  /// <summary>
  /// A boolean that indicates whether to show all items for this field
  /// </summary>
  public bool ShowAll {
    get => GetXmlNodeBool("@showAll");
    set => SetXmlNodeBool("@showAll", value);
  }

  /// <summary>
  /// The type of sort that is applied to this field
  /// </summary>
  public eSortType Sort {
    get {
      string v = GetXmlNodeString("@sortType");
      return v == "" ? eSortType.None : (eSortType)Enum.Parse(typeof(eSortType), v, true);
    }
    set {
      if (value == eSortType.None) {
        DeleteNode("@sortType");
      } else {
        SetXmlNodeString("@sortType", value.ToString().ToLower(CultureInfo.InvariantCulture));
      }
    }
  }

  /// <summary>
  /// A boolean that indicates whether manual filter is in inclusive mode
  /// </summary>
  public bool IncludeNewItemsInFilter {
    get => GetXmlNodeBool("@includeNewItemsInFilter");
    set => SetXmlNodeBool("@includeNewItemsInFilter", value);
  }

  /// <summary>
  /// Enumeration of the different subtotal operations that can be applied to page, row or column fields
  /// </summary>
  public eSubTotalFunctions SubTotalFunctions {
    get {
      eSubTotalFunctions ret = 0;
      XmlNodeList nl = TopNode.SelectNodes("d:items/d:item/@t", NameSpaceManager);
      if (nl.Count == 0) {
        return eSubTotalFunctions.None;
      }
      foreach (XmlAttribute item in nl) {
        try {
          ret |= (eSubTotalFunctions)Enum.Parse(typeof(eSubTotalFunctions), item.Value, true);
        } catch (ArgumentException ex) {
          throw new ArgumentException(
              "Unable to parse value of "
                  + item.Value
                  + " to a valid pivot table subtotal function",
              ex);
        }
      }
      return ret;
    }
    set {
      if ((value & eSubTotalFunctions.None) == eSubTotalFunctions.None
          && (value != eSubTotalFunctions.None)) {
        throw (new ArgumentException("Value None can not be combined with other values."));
      }
      if ((value & eSubTotalFunctions.Default) == eSubTotalFunctions.Default
          && (value != eSubTotalFunctions.Default)) {
        throw (new ArgumentException("Value Default can not be combined with other values."));
      }

      // remove old attribute
      XmlNodeList nl = TopNode.SelectNodes("d:items/d:item/@t", NameSpaceManager);
      if (nl.Count > 0) {
        foreach (XmlAttribute item in nl) {
          DeleteNode("@" + item.Value + "Subtotal");
          item.OwnerElement.ParentNode.RemoveChild(item.OwnerElement);
        }
      }

      if (value == eSubTotalFunctions.None) {
        // for no subtotals, set defaultSubtotal to off
        SetXmlNodeBool("@defaultSubtotal", false);
        TopNode.InnerXml = "";
      } else {
        string innerXml = "";
        int count = 0;
        foreach (eSubTotalFunctions e in Enum.GetValues(typeof(eSubTotalFunctions))) {
          if ((value & e) == e) {
            var newTotalType = e.ToString();
            var totalType =
                char.ToLower(newTotalType[0], CultureInfo.InvariantCulture)
                    + newTotalType.Substring(1);
            // add new attribute
            SetXmlNodeBool("@" + totalType + "Subtotal", true);
            innerXml += "<item t=\"" + totalType + "\" />";
            count++;
          }
        }
        TopNode.InnerXml = string.Format("<items count=\"{0}\">{1}</items>", count, innerXml);
      }
    }
  }

  /// <summary>
  /// Type of axis
  /// </summary>
  public ePivotFieldAxis Axis {
    get {
      switch (GetXmlNodeString("@axis")) {
        case "axisRow":
          return ePivotFieldAxis.Row;
        case "axisCol":
          return ePivotFieldAxis.Column;
        case "axisPage":
          return ePivotFieldAxis.Page;
        case "axisValues":
          return ePivotFieldAxis.Values;
        default:
          return ePivotFieldAxis.None;
      }
    }
    internal set {
      switch (value) {
        case ePivotFieldAxis.Row:
          SetXmlNodeString("@axis", "axisRow");
          break;
        case ePivotFieldAxis.Column:
          SetXmlNodeString("@axis", "axisCol");
          break;
        case ePivotFieldAxis.Values:
          SetXmlNodeString("@axis", "axisValues");
          break;
        case ePivotFieldAxis.Page:
          SetXmlNodeString("@axis", "axisPage");
          break;
        default:
          DeleteNode("@axis");
          break;
      }
    }
  }

  /// <summary>
  /// If the field is a row field
  /// </summary>
  public bool IsRowField {
    get =>
      (TopNode.SelectSingleNode(
              string.Format("../../d:rowFields/d:field[@x={0}]", Index),
              NameSpaceManager) != null);
    internal set {
      if (value) {
        var rowsNode = TopNode.SelectSingleNode("../../d:rowFields", NameSpaceManager);
        if (rowsNode == null) {
          _table.CreateNode("d:rowFields");
        }
        rowsNode = TopNode.SelectSingleNode("../../d:rowFields", NameSpaceManager);

        AppendField(rowsNode, Index, "field", "x");
        if (BaseIndex == Index) {
          TopNode.InnerXml = "<items count=\"1\"><item t=\"default\" /></items>";
        } else {
          TopNode.InnerXml = "<items count=\"0\"></items>";
        }
      } else {
        XmlElement node =
            TopNode.SelectSingleNode(
                string.Format("../../d:rowFields/d:field[@x={0}]", Index),
                NameSpaceManager) as XmlElement;
        if (node != null) {
          node.ParentNode.RemoveChild(node);
        }
      }
    }
  }

  /// <summary>
  /// If the field is a column field
  /// </summary>
  public bool IsColumnField {
    get =>
      (TopNode.SelectSingleNode(
              string.Format("../../d:colFields/d:field[@x={0}]", Index),
              NameSpaceManager) != null);
    internal set {
      if (value) {
        var columnsNode = TopNode.SelectSingleNode("../../d:colFields", NameSpaceManager);
        if (columnsNode == null) {
          _table.CreateNode("d:colFields");
        }
        columnsNode = TopNode.SelectSingleNode("../../d:colFields", NameSpaceManager);

        AppendField(columnsNode, Index, "field", "x");
        if (BaseIndex == Index) {
          TopNode.InnerXml = "<items count=\"1\"><item t=\"default\" /></items>";
        } else {
          TopNode.InnerXml = "<items count=\"0\"></items>";
        }
      } else {
        XmlElement node =
            TopNode.SelectSingleNode(
                string.Format("../../d:colFields/d:field[@x={0}]", Index),
                NameSpaceManager) as XmlElement;
        if (node != null) {
          node.ParentNode.RemoveChild(node);
        }
      }
    }
  }

  /// <summary>
  /// If the field is a datafield
  /// </summary>
  public bool IsDataField => GetXmlNodeBool("@dataField", false);

  /// <summary>
  /// If the field is a page field.
  /// </summary>
  public bool IsPageField {
    get => (Axis == ePivotFieldAxis.Page);
    internal set {
      if (value) {
        var dataFieldsNode = TopNode.SelectSingleNode("../../d:pageFields", NameSpaceManager);
        if (dataFieldsNode == null) {
          _table.CreateNode("d:pageFields");
          dataFieldsNode = TopNode.SelectSingleNode("../../d:pageFields", NameSpaceManager);
        }

        TopNode.InnerXml = "<items count=\"1\"><item t=\"default\" /></items>";

        XmlElement node = AppendField(dataFieldsNode, Index, "pageField", "fld");
        _pageFieldSettings = new(NameSpaceManager, node, this, Index);
      } else {
        _pageFieldSettings = null;
        XmlElement node =
            TopNode.SelectSingleNode(
                string.Format("../../d:pageFields/d:pageField[@fld={0}]", Index),
                NameSpaceManager) as XmlElement;
        if (node != null) {
          node.ParentNode.RemoveChild(node);
        }
      }
    }
  }

  //public ExcelPivotGrouping DateGrouping
  //{

  //}
  internal ExcelPivotTablePageFieldSettings _pageFieldSettings;

  public ExcelPivotTablePageFieldSettings PageFieldSettings => _pageFieldSettings;

  internal eDateGroupBy DateGrouping { get; set; }

  private ExcelPivotTableFieldGroup _grouping;

  /// <summary>
  /// Grouping settings.
  /// Null if the field has no grouping otherwise ExcelPivotTableFieldNumericGroup or ExcelPivotTableFieldNumericGroup.
  /// </summary>
  public ExcelPivotTableFieldGroup Grouping => _grouping;

  internal XmlElement AppendField(
      XmlNode rowsNode,
      int index,
      string fieldNodeText,
      string indexAttrText) {
    XmlElement prevField = null,
        newElement;
    foreach (XmlElement field in rowsNode.ChildNodes) {
      string x = field.GetAttribute(indexAttrText);
      if (int.TryParse(x, out var fieldIndex)) {
        if (fieldIndex
            == index) //Row already exists
        {
          return field;
        }
        //else if (fieldIndex > index)
        //{
        //    newElement = rowsNode.OwnerDocument.CreateElement(fieldNodeText, ExcelPackage.schemaMain);
        //    newElement.SetAttribute(indexAttrText, index.ToString());
        //    rowsNode.InsertAfter(newElement, field);
        //}
      }
      prevField = field;
    }
    newElement = rowsNode.OwnerDocument.CreateElement(fieldNodeText, ExcelPackage._schemaMain);
    newElement.SetAttribute(indexAttrText, index.ToString());
    rowsNode.InsertAfter(newElement, prevField);

    return newElement;
  }

  internal XmlHelperInstance _cacheFieldHelper;

  internal void SetCacheFieldNode(XmlNode cacheField) {
    _cacheFieldHelper = new(NameSpaceManager, cacheField);
    var groupNode = cacheField.SelectSingleNode("d:fieldGroup", NameSpaceManager);
    if (groupNode != null) {
      var groupBy = groupNode.SelectSingleNode("d:rangePr/@groupBy", NameSpaceManager);
      if (groupBy == null) {
        _grouping = new ExcelPivotTableFieldNumericGroup(NameSpaceManager, cacheField);
      } else {
        DateGrouping = (eDateGroupBy)Enum.Parse(typeof(eDateGroupBy), groupBy.Value, true);
        _grouping = new ExcelPivotTableFieldDateGroup(NameSpaceManager, groupNode);
      }
    }
  }

  internal ExcelPivotTableFieldCollectionBase<ExcelPivotTableFieldItem> _items;

  /// <summary>
  /// Pivottable field Items. Used for grouping.
  /// </summary>
  public ExcelPivotTableFieldCollectionBase<ExcelPivotTableFieldItem> Items {
    get {
      if (_items == null) {
        _items = new(_table);
        foreach (XmlNode node in TopNode.SelectNodes("d:items//d:item", NameSpaceManager)) {
          var item = new ExcelPivotTableFieldItem(NameSpaceManager, node, this);
          if (item.T == "") {
            _items.AddInternal(item);
          }
        }
      }
      return _items;
    }
  }
}
