/*******************************************************************************
 * 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.IO;
using System.Text.RegularExpressions;
using System.Xml;
using OfficeOpenXml.Packaging;
using OfficeOpenXml.Utils;

namespace OfficeOpenXml;

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

  internal ExcelWorksheets(ExcelPackage pck, XmlNamespaceManager nsm, XmlNode topNode)
      : base(nsm, topNode) {
    _pck = pck;
    _namespaceManager = nsm;
    _worksheets = new();
    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 = pck.Workbook.Part.GetRelationship(relId);
        Uri uriWorksheet = UriHelper.ResolvePartUri(
            pck.Workbook.WorkbookUri,
            sheetRelation.TargetUri);

        //add the worksheet
        if (sheetRelation.RelationshipType.EndsWith("chartsheet")) {
          _worksheets.Add(
              positionId,
              new ExcelChartsheet(
                  _namespaceManager,
                  _pck,
                  relId,
                  uriWorksheet,
                  name,
                  sheetId,
                  positionId,
                  hidden));
        } else {
          _worksheets.Add(
              positionId,
              new(_namespaceManager, _pck, relId, 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";
  internal const string _chartsheetContenttype =
      "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+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) {
    int sheetId;
    Uri uriWorksheet;
    lock (_worksheets) {
      name = ValidateFixSheetName(name);
      if (GetByName(name) != null) {
        throw (new InvalidOperationException(_errDupWorksheet + " : " + name));
      }
      GetSheetUri(ref name, out sheetId, out uriWorksheet, false);
      ZipPackagePart worksheetPart = _pck.Package.CreatePart(
          uriWorksheet,
          _worksheetContenttype,
          _pck.Compression);

      //Create the new, empty worksheet and save it to the package
      StreamWriter streamWorksheet = new StreamWriter(
          worksheetPart.GetStream(FileMode.Create, FileAccess.Write));
      XmlDocument worksheetXml = CreateNewWorksheet(false);
      worksheetXml.Save(streamWorksheet);

      string rel = CreateWorkbookRel(name, sheetId, uriWorksheet, false);

      int positionId = _worksheets.Count + 1;
      ExcelWorksheet worksheet;

      {
        worksheet = new(
            _namespaceManager,
            _pck,
            rel,
            uriWorksheet,
            name,
            sheetId,
            positionId,
            eWorkSheetHidden.Visible);
      }

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

  private string CreateWorkbookRel(string name, int sheetId, Uri uriWorksheet, bool isChart) {
    //Create the relationship between the workbook and the new worksheet
    var rel = _pck.Workbook.Part.CreateRelationship(
        UriHelper.GetRelativeUri(_pck.Workbook.WorkbookUri, uriWorksheet),
        TargetMode.Internal,
        ExcelPackage._schemaRelationships + "/" + (isChart ? "chartsheet" : "worksheet"));

    //Create the new sheet node
    XmlElement worksheetNode = _pck.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);
    return rel.Id;
  }

  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] {
    get { return 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);
  }

  /// <summary>
  /// Moves the source worksheet to the position before the target worksheet
  /// </summary>
  /// <param name="sourceName">The name of the source worksheet</param>
  /// <param name="targetName">The name of the target worksheet</param>
  public void MoveBefore(string sourceName, string targetName) {
    Move(sourceName, targetName, false);
  }

  /// <summary>
  /// Moves the source worksheet to the position before the target worksheet
  /// </summary>
  /// <param name="sourcePositionId">The id of the source worksheet</param>
  /// <param name="targetPositionId">The id of the target worksheet</param>
  public void MoveBefore(int sourcePositionId, int targetPositionId) {
    Move(sourcePositionId, targetPositionId, false);
  }

  /// <summary>
  /// Moves the source worksheet to the position after the target worksheet
  /// </summary>
  /// <param name="sourceName">The name of the source worksheet</param>
  /// <param name="targetName">The name of the target worksheet</param>
  public void MoveAfter(string sourceName, string targetName) {
    Move(sourceName, targetName, true);
  }

  /// <summary>
  /// Moves the source worksheet to the position after the target worksheet
  /// </summary>
  /// <param name="sourcePositionId">The id of the source worksheet</param>
  /// <param name="targetPositionId">The id of the target worksheet</param>
  public void MoveAfter(int sourcePositionId, int targetPositionId) {
    Move(sourcePositionId, targetPositionId, true);
  }

  /// <summary>
  ///
  /// </summary>
  /// <param name="sourceName"></param>
  public void MoveToStart(string sourceName) {
    var sourceSheet = this[sourceName];
    if (sourceSheet == null) {
      throw new(
          string.Format(
              "Move worksheet error: Could not find worksheet to move '{0}'",
              sourceName));
    }
    Move(sourceSheet.PositionID, 1, false);
  }

  /// <summary>
  ///
  /// </summary>
  /// <param name="sourcePositionId"></param>
  public void MoveToStart(int sourcePositionId) {
    Move(sourcePositionId, 1, false);
  }

  /// <summary>
  ///
  /// </summary>
  /// <param name="sourceName"></param>
  public void MoveToEnd(string sourceName) {
    var sourceSheet = this[sourceName];
    if (sourceSheet == null) {
      throw new(
          string.Format(
              "Move worksheet error: Could not find worksheet to move '{0}'",
              sourceName));
    }
    Move(sourceSheet.PositionID, _worksheets.Count, true);
  }

  /// <summary>
  ///
  /// </summary>
  /// <param name="sourcePositionId"></param>
  public void MoveToEnd(int sourcePositionId) {
    Move(sourcePositionId, _worksheets.Count, true);
  }

  private void Move(string sourceName, string targetName, bool placeAfter) {
    var sourceSheet = this[sourceName];
    if (sourceSheet == null) {
      throw new(
          string.Format(
              "Move worksheet error: Could not find worksheet to move '{0}'",
              sourceName));
    }
    var targetSheet = this[targetName];
    if (targetSheet == null) {
      throw new(
          string.Format(
              "Move worksheet error: Could not find worksheet to move '{0}'",
              targetName));
    }
    Move(sourceSheet.PositionID, targetSheet.PositionID, placeAfter);
  }

  private void Move(int sourcePositionId, int targetPositionId, bool placeAfter) {
    // Bugfix: if source and target are the same worksheet the following code will create a duplicate
    //         which will cause a corrupt workbook. /swmal 2014-05-10
    if (sourcePositionId == targetPositionId) {
      return;
    }

    lock (_worksheets) {
      var sourceSheet = this[sourcePositionId];
      if (sourceSheet == null) {
        throw new(
            string.Format(
                "Move worksheet error: Could not find worksheet at position '{0}'",
                sourcePositionId));
      }
      var targetSheet = this[targetPositionId];
      if (targetSheet == null) {
        throw new(
            string.Format(
                "Move worksheet error: Could not find worksheet at position '{0}'",
                targetPositionId));
      }
      if (sourcePositionId == targetPositionId && _worksheets.Count < 2) {
        return; //--- no reason to attempt to re-arrange a single item with itself
      }

      var index = 1;
      var newOrder = new Dictionary<int, ExcelWorksheet>();
      foreach (var entry in _worksheets) {
        if (entry.Key == targetPositionId) {
          if (!placeAfter) {
            sourceSheet.PositionID = index;
            newOrder.Add(index++, sourceSheet);
          }

          entry.Value.PositionID = index;
          newOrder.Add(index++, entry.Value);

          if (placeAfter) {
            sourceSheet.PositionID = index;
            newOrder.Add(index++, sourceSheet);
          }
        } else if (entry.Key == sourcePositionId) {
          //--- do nothing
        } else {
          entry.Value.PositionID = index;
          newOrder.Add(index++, entry.Value);
        }
      }
      _worksheets = newOrder;

      MoveSheetXmlNode(sourceSheet, targetSheet, placeAfter);
    }
  }

  private void MoveSheetXmlNode(
      ExcelWorksheet sourceSheet,
      ExcelWorksheet targetSheet,
      bool placeAfter) {
    lock (TopNode.OwnerDocument) {
      var sourceNode = TopNode.SelectSingleNode(
          string.Format("d:sheet[@sheetId = '{0}']", sourceSheet.SheetID),
          _namespaceManager);
      var targetNode = TopNode.SelectSingleNode(
          string.Format("d:sheet[@sheetId = '{0}']", targetSheet.SheetID),
          _namespaceManager);
      if (sourceNode == null || targetNode == null) {
        throw new("Source SheetId and Target SheetId must be valid");
      }
      if (placeAfter) {
        TopNode.InsertAfter(sourceNode, targetNode);
      } else {
        TopNode.InsertBefore(sourceNode, targetNode);
      }
    }
  }
} // end class Worksheets
