/*******************************************************************************
 * 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.Collections.Immutable;
using System.Text.RegularExpressions;
using System.Xml;

namespace AppsheetEpplus;

/// <summary>
/// An Excel Pivottable
/// </summary>
public class ExcelPivotTable : XmlHelper {
  protected override ImmutableArray<string> SchemaNodeOrder { get; } = [
    "location",
    "pivotFields",
    "rowFields",
    "rowItems",
    "colFields",
    "colItems",
    "pageFields",
    "pageItems",
    "dataFields",
    "dataItems",
    "formats",
    "pivotTableStyleInfo",
  ];

  internal ExcelPivotTable(ZipPackageRelationship rel, ExcelWorksheet sheet)
      : base(sheet.NameSpaceManager) {
    WorkSheet = sheet;
    PivotTableUri = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);
    Relationship = rel;
    var package = sheet._package;
    PivotTableXml = package.GetXmlDocument(PivotTableUri);
    TopNode = PivotTableXml.DocumentElement;
    Address = new(GetXmlNodeString("d:location/@ref"));

    CacheDefinition = new(sheet.NameSpaceManager, this);
    LoadFields();

    //Add row fields.
    foreach (XmlElement rowElem in TopNode.SelectNodes("d:rowFields/d:field", NameSpaceManager)) {
      if (int.TryParse(rowElem.GetAttribute("x"), out var x) && x >= 0) {
        RowFields.AddInternal(Fields[x]);
      } else {
        rowElem.ParentNode.RemoveChild(rowElem);
      }
    }

    ////Add column fields.
    foreach (XmlElement colElem in TopNode.SelectNodes("d:colFields/d:field", NameSpaceManager)) {
      if (int.TryParse(colElem.GetAttribute("x"), out var x) && x >= 0) {
        ColumnFields.AddInternal(Fields[x]);
      } else {
        colElem.ParentNode.RemoveChild(colElem);
      }
    }

    //Add Page elements
    //int index = 0;
    foreach (XmlElement pageElem in TopNode.SelectNodes(
        "d:pageFields/d:pageField",
        NameSpaceManager)) {
      if (int.TryParse(pageElem.GetAttribute("fld"), out var fld) && fld >= 0) {
        var field = Fields[fld];
        field._pageFieldSettings = new(NameSpaceManager, pageElem, field, fld);
        PageFields.AddInternal(field);
      }
    }

    //Add data elements
    //index = 0;
    foreach (XmlElement dataElem in TopNode.SelectNodes(
        "d:dataFields/d:dataField",
        NameSpaceManager)) {
      if (int.TryParse(dataElem.GetAttribute("fld"), out var fld) && fld >= 0) {
        var field = Fields[fld];
        var dataField = new ExcelPivotTableDataField(NameSpaceManager, dataElem, field);
        DataFields.AddInternal(dataField);
      }
    }
  }

  private void LoadFields() {
    //Fields.Clear();
    //int ix=0;
    //foreach(XmlElement fieldNode in PivotXml.SelectNodes("//d:pivotFields/d:pivotField",NameSpaceManager))
    //{
    //    Fields.AddInternal(new ExcelPivotTableField(NameSpaceManager, fieldNode, this, ix++));
    //}

    int index = 0;
    //Add fields.
    foreach (XmlElement fieldElem in TopNode.SelectNodes(
        "d:pivotFields/d:pivotField",
        NameSpaceManager)) {
      var fld = new ExcelPivotTableField(NameSpaceManager, fieldElem, this, index, index++);
      Fields.AddInternal(fld);
    }

    //Add fields.
    index = 0;
    foreach (XmlElement fieldElem in CacheDefinition.TopNode.SelectNodes(
        "d:cacheFields/d:cacheField",
        NameSpaceManager)) {
      var fld = Fields[index++];
      fld.SetCacheFieldNode(fieldElem);
    }
  }

  private XmlDocument GetStartXml(
      string name,
      int id,
      ExcelAddressBase address,
      ExcelAddressBase sourceAddress) {
    string xml = $"""
         <pivotTableDefinition xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" name="
         {name}" cacheId="{id
         }" dataOnRows="1" applyNumberFormats="0" applyBorderFormats="0" applyFontFormats="0" applyPatternFormats="0" applyAlignmentFormats="0" applyWidthHeightFormats="1" dataCaption="Data"  createdVersion="4" showMemberPropertyTips="0" useAutoFormatting="1" itemPrintTitles="1" indent="0" compact="0" compactData="0" gridDropZones="1">

         """;
    xml +=
        $"""<location ref="{address.FirstAddress
    }" firstHeaderRow="1" firstDataRow="1" firstDataCol="1" />""";
    xml += $"""<pivotFields count="{sourceAddress._toCol - sourceAddress._fromCol + 1}">""";
    for (int col = sourceAddress._fromCol; col <= sourceAddress._toCol; col++) {
      xml += """<pivotField showAll="0" />""";
    }
    xml += "</pivotFields>";
    xml +=
        """<pivotTableStyleInfo name="PivotStyleMedium9" showRowHeaders="1" showColHeaders="1" showRowStripes="0" showColStripes="0" showLastColumn="1" />""";
    xml += "</pivotTableDefinition>";
    var result = new XmlDocument();
    result.LoadXml(xml);
    return result;
  }

  internal ZipPackagePart Part { get; }

  /// <summary>
  /// Provides access to the XML data representing the pivottable in the package.
  /// </summary>
  public XmlDocument PivotTableXml { get; private set; }

  /// <summary>
  /// The package internal URI to the pivottable Xml Document.
  /// </summary>
  public Uri PivotTableUri { get; internal set; }

  internal ZipPackageRelationship Relationship { get; set; }

  //const string ID_PATH = "@id";
  //internal int Id
  //{
  //    get
  //    {
  //        return GetXmlNodeInt(ID_PATH);
  //    }
  //    set
  //    {
  //        SetXmlNodeString(ID_PATH, value.ToString());
  //    }
  //}
  private const string _namePath = "@name";
  private const string _displayNamePath = "@displayName";

  /// <summary>
  /// Name of the pivottable object in Excel
  /// </summary>
  public string Name {
    get => GetXmlNodeString(_namePath);
    set {
      if (WorkSheet.Workbook.ExistsTableName(value)) {
        throw (new ArgumentException("PivotTable name is not unique"));
      }
      string prevName = Name;
      if (WorkSheet.Tables._tableNames.ContainsKey(prevName)) {
        int ix = WorkSheet.Tables._tableNames[prevName];
        WorkSheet.Tables._tableNames.Remove(prevName);
        WorkSheet.Tables._tableNames.Add(value, ix);
      }
      SetXmlNodeString(_namePath, value);
      SetXmlNodeString(_displayNamePath, CleanDisplayName(value));
    }
  }

  /// <summary>
  /// Reference to the pivot table cache definition object
  /// </summary>
  public ExcelPivotCacheDefinition CacheDefinition { get; }

  private string CleanDisplayName(string name) {
    return Regex.Replace(name, @"[^\w\.-_]", "_");
  }

  /// <summary>
  /// The worksheet where the pivottable is located
  /// </summary>
  public ExcelWorksheet WorkSheet { get; set; }

  /// <summary>
  /// The location of the pivot table
  /// </summary>
  public ExcelAddressBase Address { get; internal set; }

  /// <summary>
  /// If multiple datafields are displayed in the row area or the column area
  /// </summary>
  public bool DataOnRows {
    get => GetXmlNodeBool("@dataOnRows");
    set => SetXmlNodeBool("@dataOnRows", value);
  }

  /// <summary>
  /// if true apply legacy table autoformat number format properties.
  /// </summary>
  public bool ApplyNumberFormats {
    get => GetXmlNodeBool("@applyNumberFormats");
    set => SetXmlNodeBool("@applyNumberFormats", value);
  }

  /// <summary>
  /// If true apply legacy table autoformat border properties
  /// </summary>
  public bool ApplyBorderFormats {
    get => GetXmlNodeBool("@applyBorderFormats");
    set => SetXmlNodeBool("@applyBorderFormats", value);
  }

  /// <summary>
  /// If true apply legacy table autoformat font properties
  /// </summary>
  public bool ApplyFontFormats {
    get => GetXmlNodeBool("@applyFontFormats");
    set => SetXmlNodeBool("@applyFontFormats", value);
  }

  /// <summary>
  /// If true apply legacy table autoformat pattern properties
  /// </summary>
  public bool ApplyPatternFormats {
    get => GetXmlNodeBool("@applyPatternFormats");
    set => SetXmlNodeBool("@applyPatternFormats", value);
  }

  /// <summary>
  /// If true apply legacy table autoformat width/height properties.
  /// </summary>
  public bool ApplyWidthHeightFormats {
    get => GetXmlNodeBool("@applyWidthHeightFormats");
    set => SetXmlNodeBool("@applyWidthHeightFormats", value);
  }

  /// <summary>
  /// Show member property information
  /// </summary>
  public bool ShowMemberPropertyTips {
    get => GetXmlNodeBool("@showMemberPropertyTips");
    set => SetXmlNodeBool("@showMemberPropertyTips", value);
  }

  /// <summary>
  /// Show the drill indicators
  /// </summary>
  public bool ShowCalcMember {
    get => GetXmlNodeBool("@showCalcMbrs");
    set => SetXmlNodeBool("@showCalcMbrs", value);
  }

  /// <summary>
  /// If the user is prevented from drilling down on a PivotItem or aggregate value
  /// </summary>
  public bool EnableDrill {
    get => GetXmlNodeBool("@enableDrill", true);
    set => SetXmlNodeBool("@enableDrill", value);
  }

  /// <summary>
  /// Show the drill down buttons
  /// </summary>
  public bool ShowDrill {
    get => GetXmlNodeBool("@showDrill", true);
    set => SetXmlNodeBool("@showDrill", value);
  }

  /// <summary>
  /// If the tooltips should be displayed for PivotTable data cells.
  /// </summary>
  public bool ShowDataTips {
    get => GetXmlNodeBool("@showDataTips", true);
    set => SetXmlNodeBool("@showDataTips", value, true);
  }

  /// <summary>
  /// If the row and column titles from the PivotTable should be printed.
  /// </summary>
  public bool FieldPrintTitles {
    get => GetXmlNodeBool("@fieldPrintTitles");
    set => SetXmlNodeBool("@fieldPrintTitles", value);
  }

  /// <summary>
  /// If the row and column titles from the PivotTable should be printed.
  /// </summary>
  public bool ItemPrintTitles {
    get => GetXmlNodeBool("@itemPrintTitles");
    set => SetXmlNodeBool("@itemPrintTitles", value);
  }

  /// <summary>
  /// If the grand totals should be displayed for the PivotTable columns
  /// </summary>
  public bool ColumGrandTotals {
    get => GetXmlNodeBool("@colGrandTotals");
    set => SetXmlNodeBool("@colGrandTotals", value);
  }

  /// <summary>
  /// If the grand totals should be displayed for the PivotTable rows
  /// </summary>
  public bool RowGrandTotals {
    get => GetXmlNodeBool("@rowGrandTotals");
    set => SetXmlNodeBool("@rowGrandTotals", value);
  }

  /// <summary>
  /// If the drill indicators expand collapse buttons should be printed.
  /// </summary>
  public bool PrintDrill {
    get => GetXmlNodeBool("@printDrill");
    set => SetXmlNodeBool("@printDrill", value);
  }

  /// <summary>
  /// Indicates whether to show error messages in cells.
  /// </summary>
  public bool ShowError {
    get => GetXmlNodeBool("@showError");
    set => SetXmlNodeBool("@showError", value);
  }

  /// <summary>
  /// The string to be displayed in cells that contain errors.
  /// </summary>
  public string ErrorCaption {
    get => GetXmlNodeString("@errorCaption");
    set => SetXmlNodeString("@errorCaption", value);
  }

  /// <summary>
  /// Specifies the name of the value area field header in the PivotTable.
  /// This caption is shown when the PivotTable when two or more fields are in the values area.
  /// </summary>
  public string DataCaption {
    get => GetXmlNodeString("@dataCaption");
    set => SetXmlNodeString("@dataCaption", value);
  }

  /// <summary>
  /// Show field headers
  /// </summary>
  public bool ShowHeaders {
    get => GetXmlNodeBool("@showHeaders");
    set => SetXmlNodeBool("@showHeaders", value);
  }

  /// <summary>
  /// The number of page fields to display before starting another row or column
  /// </summary>
  public int PageWrap {
    get => GetXmlNodeInt("@pageWrap");
    set {
      if (value < 0) {
        throw new("Value can't be negative");
      }
      SetXmlNodeString("@pageWrap", value.ToString());
    }
  }

  /// <summary>
  /// A boolean that indicates whether legacy auto formatting has been applied to the PivotTable view
  /// </summary>
  public bool UseAutoFormatting {
    get => GetXmlNodeBool("@useAutoFormatting");
    set => SetXmlNodeBool("@useAutoFormatting", value);
  }

  /// <summary>
  /// A boolean that indicates whether the in-grid drop zones should be displayed at runtime, and whether classic layout is applied
  /// </summary>
  public bool GridDropZones {
    get => GetXmlNodeBool("@gridDropZones");
    set => SetXmlNodeBool("@gridDropZones", value);
  }

  /// <summary>
  /// Specifies the indentation increment for compact axis and can be used to set the Report Layout to Compact Form
  /// </summary>
  public int Indent {
    get => GetXmlNodeInt("@indent");
    set => SetXmlNodeString("@indent", value.ToString());
  }

  /// <summary>
  /// A boolean that indicates whether data fields in the PivotTable should be displayed in outline form
  /// </summary>
  public bool OutlineData {
    get => GetXmlNodeBool("@outlineData");
    set => SetXmlNodeBool("@outlineData", value);
  }

  /// <summary>
  /// a boolean that indicates whether new fields should have their outline flag set to true
  /// </summary>
  public bool Outline {
    get => GetXmlNodeBool("@outline");
    set => SetXmlNodeBool("@outline", value);
  }

  /// <summary>
  /// A boolean that indicates whether the fields of a PivotTable can have multiple filters set on them
  /// </summary>
  public bool MultipleFieldFilters {
    get => GetXmlNodeBool("@multipleFieldFilters");
    set => SetXmlNodeBool("@multipleFieldFilters", value);
  }

  /// <summary>
  /// A boolean that indicates whether new fields should have their compact flag set to true
  /// </summary>
  public bool Compact {
    get => GetXmlNodeBool("@compact");
    set => SetXmlNodeBool("@compact", value);
  }

  /// <summary>
  /// A boolean that indicates whether the field next to the data field in the PivotTable should be displayed in the same column of the spreadsheet
  /// </summary>
  public bool CompactData {
    get => GetXmlNodeBool("@compactData");
    set => SetXmlNodeBool("@compactData", value);
  }

  /// <summary>
  /// Specifies the string to be displayed for grand totals.
  /// </summary>
  public string GrandTotalCaption {
    get => GetXmlNodeString("@grandTotalCaption");
    set => SetXmlNodeString("@grandTotalCaption", value);
  }

  /// <summary>
  /// Specifies the string to be displayed in row header in compact mode.
  /// </summary>
  public string RowHeaderCaption {
    get => GetXmlNodeString("@rowHeaderCaption");
    set => SetXmlNodeString("@rowHeaderCaption", value);
  }

  /// <summary>
  /// Specifies the string to be displayed in cells with no value
  /// </summary>
  public string MissingCaption {
    get => GetXmlNodeString("@missingCaption");
    set => SetXmlNodeString("@missingCaption", value);
  }

  private const string _firstheaderrowPath = "d:location/@firstHeaderRow";

  /// <summary>
  /// Specifies the first row of the PivotTable header, relative to the top left cell in the ref value
  /// </summary>
  public int FirstHeaderRow {
    get => GetXmlNodeInt(_firstheaderrowPath);
    set => SetXmlNodeString(_firstheaderrowPath, value.ToString());
  }

  private const string _firstdatarowPath = "d:location/@firstDataRow";

  /// <summary>
  /// Specifies the first column of the PivotTable data, relative to the top left cell in the ref value
  /// </summary>
  public int FirstDataRow {
    get => GetXmlNodeInt(_firstdatarowPath);
    set => SetXmlNodeString(_firstdatarowPath, value.ToString());
  }

  private const string _firstdatacolPath = "d:location/@firstDataCol";

  /// <summary>
  /// Specifies the first column of the PivotTable data, relative to the top left cell in the ref value
  /// </summary>
  public int FirstDataCol {
    get => GetXmlNodeInt(_firstdatacolPath);
    set => SetXmlNodeString(_firstdatacolPath, value.ToString());
  }

  private ExcelPivotTableFieldCollection _fields;

  /// <summary>
  /// The fields in the table
  /// </summary>
  public ExcelPivotTableFieldCollection Fields {
    get {
      if (_fields == null) {
        _fields = new(this, "");
      }
      return _fields;
    }
  }

  private ExcelPivotTableRowColumnFieldCollection _rowFields;

  /// <summary>
  /// Row label fields
  /// </summary>
  public ExcelPivotTableRowColumnFieldCollection RowFields {
    get {
      if (_rowFields == null) {
        _rowFields = new(this, "rowFields");
      }
      return _rowFields;
    }
  }

  private ExcelPivotTableRowColumnFieldCollection _columnFields;

  /// <summary>
  /// Column label fields
  /// </summary>
  public ExcelPivotTableRowColumnFieldCollection ColumnFields {
    get {
      if (_columnFields == null) {
        _columnFields = new(this, "colFields");
      }
      return _columnFields;
    }
  }

  private ExcelPivotTableDataFieldCollection _dataFields;

  /// <summary>
  /// Value fields
  /// </summary>
  public ExcelPivotTableDataFieldCollection DataFields {
    get {
      if (_dataFields == null) {
        _dataFields = new(this);
      }
      return _dataFields;
    }
  }

  private ExcelPivotTableRowColumnFieldCollection _pageFields;

  /// <summary>
  /// Report filter fields
  /// </summary>
  public ExcelPivotTableRowColumnFieldCollection PageFields {
    get {
      if (_pageFields == null) {
        _pageFields = new(this, "pageFields");
      }
      return _pageFields;
    }
  }

  private const string _stylenamePath = "d:pivotTableStyleInfo/@name";

  /// <summary>
  /// Pivot style name. Used for custom styles
  /// </summary>
  public string StyleName {
    get => GetXmlNodeString(_stylenamePath);
    set {
      if (value.StartsWith("PivotStyle")) {
        try {
          _tableStyle = (TableStyles)
            Enum.Parse(typeof(TableStyles), value.Substring(10, value.Length - 10), true);
        } catch {
          _tableStyle = TableStyles.Custom;
        }
      } else if (value == "None") {
        _tableStyle = TableStyles.None;
        value = "";
      } else {
        _tableStyle = TableStyles.Custom;
      }
      SetXmlNodeString(_stylenamePath, value, true);
    }
  }

  private TableStyles _tableStyle = TableStyles.Medium6;

  /// <summary>
  /// The table style. If this property is cusom the style from the StyleName propery is used.
  /// </summary>
  public TableStyles TableStyle {
    get => _tableStyle;
    set {
      _tableStyle = value;
      if (value != TableStyles.Custom) {
        SetXmlNodeString(_stylenamePath, "PivotStyle" + value);
      }
    }
  }

  internal int CacheID {
    get => GetXmlNodeInt("@cacheId");
    set => SetXmlNodeString("@cacheId", value.ToString());
  }
}
