/*******************************************************************************
 * 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;
using OfficeOpenXml.Utils;

namespace OfficeOpenXml;

/// <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
