/*******************************************************************************
 * 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		    Initial Release		       2009-10-01
 * Jan Källman		    License changed GPL-->LGPL 2011-12-27
 *******************************************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Xml;

namespace AppsheetEpplus;

/// <summary>
/// The collection of worksheets for the workbook
/// </summary>
public class ExcelWorksheets : XmlHelper, IEnumerable<ExcelWorksheet> {
  private readonly ExcelPackage _pck;
  private readonly ExcelWorkbook _workbook;
  private Dictionary<int, ExcelWorksheet> _worksheets = new();
  private readonly XmlNamespaceManager _namespaceManager;

  internal ExcelWorksheets(
      ExcelPackage pck,
      ExcelWorkbook workbook,
      XmlNamespaceManager nsm,
      XmlNode topNode)
      : base(nsm, topNode) {
    _pck = pck;
    _workbook = workbook;
    _namespaceManager = nsm;
    int positionId = 1;

    foreach (XmlNode sheetNode in topNode.ChildNodes) {
      if (sheetNode.NodeType == XmlNodeType.Element) {
        string name = sheetNode.Attributes["name"].Value;
        //Get the relationship id
        string relId = sheetNode.Attributes["r:id"].Value;
        int sheetId = Convert.ToInt32(sheetNode.Attributes["sheetId"].Value);

        //Hidden property
        eWorkSheetHidden hidden = eWorkSheetHidden.Visible;
        XmlNode attr = sheetNode.Attributes["state"];
        if (attr != null) {
          hidden = TranslateHidden(attr.Value);
        }

        var sheetRelation = _workbook.Part.GetRelationship(relId);
        Uri uriWorksheet = UriHelper.ResolvePartUri(
            ExcelWorkbook.WorkbookUri,
            sheetRelation.TargetUri);

        //add the worksheet
        if (sheetRelation.RelationshipType.EndsWith("chartsheet")) {
          _worksheets.Add(
              positionId,
              new ExcelChartsheet(
                  _namespaceManager,
                  pck,
                  _workbook,
                  uriWorksheet,
                  name,
                  sheetId,
                  positionId,
                  hidden));
        } else {
          _worksheets.Add(
              positionId,
              new(
                  _namespaceManager,
                  pck,
                  _workbook,
                  uriWorksheet,
                  name,
                  sheetId,
                  positionId,
                  hidden));
        }
        positionId++;
      }
    }
  }

  private eWorkSheetHidden TranslateHidden(string value) {
    switch (value) {
      case "hidden":
        return eWorkSheetHidden.Hidden;
      case "veryHidden":
        return eWorkSheetHidden.VeryHidden;
      default:
        return eWorkSheetHidden.Visible;
    }
  }

  /// <summary>
  /// Returns the number of worksheets in the workbook
  /// </summary>
  public int Count => (_worksheets.Count);

  private const string _errDupWorksheet =
      "A worksheet with this name already exists in the workbook";
  internal const string _worksheetContentType =
      "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml";

  /// <summary>
  /// Foreach support
  /// </summary>
  /// <returns>An enumerator</returns>
  public IEnumerator<ExcelWorksheet> GetEnumerator() {
    return (_worksheets.Values.GetEnumerator());
  }

  IEnumerator IEnumerable.GetEnumerator() {
    return (_worksheets.Values.GetEnumerator());
  }

  /// <summary>
  /// Adds a new blank worksheet.
  /// </summary>
  /// <param name="name">The name of the workbook</param>
  public ExcelWorksheet Add(string name) {
    name = ValidateFixSheetName(name);
    if (GetByName(name) != null) {
      throw (new InvalidOperationException(_errDupWorksheet + " : " + name));
    }
    GetSheetUri(ref name, out var sheetId, out var uriWorksheet, false);

    // Create the new worksheet
    var rel = _pck.CreateXmlDocument(
        uriWorksheet,
        _worksheetContentType,
        ExcelPackage._schemaRelationships + "/worksheet",
        CreateNewWorksheet(false));

    // Add worksheet to the workbook
    XmlElement worksheetNode = _workbook.WorkbookXml.CreateElement(
        "sheet",
        ExcelPackage._schemaMain);
    worksheetNode.SetAttribute("name", name);
    worksheetNode.SetAttribute("sheetId", sheetId.ToString());
    worksheetNode.SetAttribute("id", ExcelPackage._schemaRelationships, rel.Id);
    TopNode.AppendChild(worksheetNode);

    int positionId = _worksheets.Count + 1;

    ExcelWorksheet worksheet = new(
        _namespaceManager,
        _pck,
        _workbook,
        uriWorksheet,
        name,
        sheetId,
        positionId,
        eWorkSheetHidden.Visible);

    _worksheets.Add(positionId, worksheet);
    return worksheet;
  }

  private void GetSheetUri(ref string name, out int sheetId, out Uri uriWorksheet, bool isChart) {
    name = ValidateFixSheetName(name);

    //First find maximum existing sheetID
    sheetId = 0;
    foreach (var ws in this) {
      if (ws.SheetID > sheetId) {
        sheetId = ws.SheetID;
      }
    }
    // we now have the max existing values, so add one
    sheetId++;

    // add the new worksheet to the package
    if (isChart) {
      uriWorksheet = new("/xl/chartsheets/chartsheet" + sheetId + ".xml", UriKind.Relative);
    } else {
      uriWorksheet = new("/xl/worksheets/sheet" + sheetId + ".xml", UriKind.Relative);
    }
  }

  internal string ValidateFixSheetName(string name) {
    //remove invalid characters
    if (ValidateName(name)) {
      if (name.IndexOf(':') > -1) {
        name = name.Replace(":", " ");
      }
      if (name.IndexOf('/') > -1) {
        name = name.Replace("/", " ");
      }
      if (name.IndexOf('\\') > -1) {
        name = name.Replace("\\", " ");
      }
      if (name.IndexOf('?') > -1) {
        name = name.Replace("?", " ");
      }
      if (name.IndexOf('[') > -1) {
        name = name.Replace("[", " ");
      }
      if (name.IndexOf(']') > -1) {
        name = name.Replace("]", " ");
      }
    }

    if (name.Trim() == "") {
      throw new ArgumentException("The worksheet can not have an empty name");
    }
    if (name.Length > 31) {
      name = name.Substring(0, 31); //A sheet can have max 31 char's
    }
    return name;
  }

  /// <summary>
  /// Validate the sheetname
  /// </summary>
  /// <param name="name">The Name</param>
  /// <returns>True if valid</returns>
  private bool ValidateName(string name) {
    return Regex.IsMatch(name, @":|\?|/|\\|\[|\]");
  }

  /// <summary>
  /// Creates the XML document representing a new empty worksheet
  /// </summary>
  /// <returns></returns>
  internal XmlDocument CreateNewWorksheet(bool isChart) {
    XmlDocument xmlDoc = new XmlDocument();
    XmlElement elemWs = xmlDoc.CreateElement(
        isChart ? "chartsheet" : "worksheet",
        ExcelPackage._schemaMain);
    elemWs.SetAttribute("xmlns:r", ExcelPackage._schemaRelationships);
    xmlDoc.AppendChild(elemWs);

    if (isChart) {
      XmlElement elemSheetPr = xmlDoc.CreateElement("sheetPr", ExcelPackage._schemaMain);
      elemWs.AppendChild(elemSheetPr);

      XmlElement elemSheetViews = xmlDoc.CreateElement("sheetViews", ExcelPackage._schemaMain);
      elemWs.AppendChild(elemSheetViews);

      XmlElement elemSheetView = xmlDoc.CreateElement("sheetView", ExcelPackage._schemaMain);
      elemSheetView.SetAttribute("workbookViewId", "0");
      elemSheetView.SetAttribute("zoomToFit", "1");

      elemSheetViews.AppendChild(elemSheetView);
    } else {
      XmlElement elemSheetViews = xmlDoc.CreateElement("sheetViews", ExcelPackage._schemaMain);
      elemWs.AppendChild(elemSheetViews);

      XmlElement elemSheetView = xmlDoc.CreateElement("sheetView", ExcelPackage._schemaMain);
      elemSheetView.SetAttribute("workbookViewId", "0");
      elemSheetViews.AppendChild(elemSheetView);

      XmlElement elemSheetFormatPr = xmlDoc.CreateElement(
          "sheetFormatPr",
          ExcelPackage._schemaMain);
      elemSheetFormatPr.SetAttribute("defaultRowHeight", "15");
      elemWs.AppendChild(elemSheetFormatPr);

      XmlElement elemSheetData = xmlDoc.CreateElement("sheetData", ExcelPackage._schemaMain);
      elemWs.AppendChild(elemSheetData);
    }
    return xmlDoc;
  }

  /// <summary>
  /// Returns the worksheet at the specified position.
  /// </summary>
  /// <param name="positionId">The position of the worksheet. 1-base</param>
  /// <returns></returns>
  public ExcelWorksheet this[int positionId] {
    get {
      if (_worksheets.ContainsKey(positionId)) {
        return _worksheets[positionId];
      }
      throw (new IndexOutOfRangeException("Worksheet position out of range."));
    }
  }

  /// <summary>
  /// Returns the worksheet matching the specified name
  /// </summary>
  /// <param name="name">The name of the worksheet</param>
  /// <returns></returns>
  public ExcelWorksheet this[string name] => GetByName(name);

  internal ExcelWorksheet GetBySheetId(int localSheetId) {
    foreach (ExcelWorksheet ws in this) {
      if (ws.SheetID == localSheetId) {
        return ws;
      }
    }
    return null;
  }

  private ExcelWorksheet GetByName(string name) {
    if (string.IsNullOrEmpty(name)) {
      return null;
    }
    ExcelWorksheet xlWorksheet = null;
    foreach (ExcelWorksheet worksheet in _worksheets.Values) {
      if (worksheet.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) {
        xlWorksheet = worksheet;
      }
    }
    return (xlWorksheet);
  }
} // end class Worksheets
