/*******************************************************************************
 * 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
 * ******************************************************************************
 * Mats Alm   		                Added       		        2011-01-01
 * Jan Källman		                License changed GPL-->LGPL  2011-12-27
 *******************************************************************************/

using System;
using System.Collections.Immutable;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Xml;

namespace AppsheetEpplus;

/// <summary>
/// Excel datavalidation
/// </summary>
public abstract class ExcelDataValidation : XmlHelper, IExcelDataValidation {
  private const string _itemElementNodeName = "d:dataValidation";

  private readonly string _errorStylePath = "@errorStyle";
  private readonly string _errorTitlePath = "@errorTitle";
  private readonly string _errorPath = "@error";
  private readonly string _promptTitlePath = "@promptTitle";
  private readonly string _promptPath = "@prompt";
  private readonly string _operatorPath = "@operator";
  private readonly string _showErrorMessagePath = "@showErrorMessage";
  private readonly string _showInputMessagePath = "@showInputMessage";
  private readonly string _typeMessagePath = "@type";
  private readonly string _sqrefPath = "@sqref";
  private readonly string _allowBlankPath = "@allowBlank";
  protected readonly string _formula1Path = "d:formula1";
  protected readonly string _formula2Path = "d:formula2";

  protected override ImmutableArray<string> SchemaNodeOrder { get; } = [
    "type",
    "errorStyle",
    "operator",
    "allowBlank",
    "showInputMessage",
    "showErrorMessage",
    "errorTitle",
    "error",
    "promptTitle",
    "prompt",
    "sqref",
    "formula1",
    "formula2",
  ];

  internal ExcelDataValidation(
      ExcelWorksheet worksheet,
      string address,
      ExcelDataValidationType validationType)
      : this(worksheet, address, validationType, null) {}

  /// <summary>
  /// Constructor
  /// </summary>
  /// <param name="worksheet">worksheet that owns the validation</param>
  /// <param name="itemElementNode">Xml top node (dataValidations)</param>
  /// <param name="validationType">Data validation type</param>
  /// <param name="address">address for data validation</param>
  internal ExcelDataValidation(
      ExcelWorksheet worksheet,
      string address,
      ExcelDataValidationType validationType,
      XmlNode itemElementNode)
      : this(worksheet, address, validationType, itemElementNode, null) {}

  /// <summary>
  /// Constructor
  /// </summary>
  /// <param name="worksheet">worksheet that owns the validation</param>
  /// <param name="itemElementNode">Xml top node (dataValidations) when importing xml</param>
  /// <param name="validationType">Data validation type</param>
  /// <param name="address">address for data validation</param>
  /// <param name="namespaceManager">Xml Namespace manager</param>
  internal ExcelDataValidation(
      ExcelWorksheet worksheet,
      string address,
      ExcelDataValidationType validationType,
      XmlNode itemElementNode,
      XmlNamespaceManager namespaceManager)
      : base(namespaceManager ?? worksheet.NameSpaceManager) {
    ArgumentException.ThrowIfNullOrEmpty(address);
    address = CheckAndFixRangeAddress(address);
    if (itemElementNode == null) {
      //var xmlDoc = worksheet.WorksheetXml;
      TopNode = worksheet.WorksheetXml.SelectSingleNode(
          "//d:dataValidations",
          worksheet.NameSpaceManager);
      // did not succeed using the XmlHelper methods here... so I'm creating the new node using XmlDocument...
      var nsUri = NameSpaceManager.LookupNamespace("d");
      //itemElementNode = TopNode.OwnerDocument.CreateElement(_itemElementNodeName, nsUri);
      itemElementNode = TopNode.OwnerDocument.CreateElement(
          _itemElementNodeName.Split(':')[1],
          nsUri);
      TopNode.AppendChild(itemElementNode);
    }
    TopNode = itemElementNode;
    ValidationType = validationType;
    Address = new(address);
  }

  private string CheckAndFixRangeAddress(string address) {
    if (address.Contains(',')) {
      throw new FormatException("Multiple addresses may not be commaseparated, use space instead");
    }
    address = address.ToUpper(CultureInfo.InvariantCulture);
    if (Regex.IsMatch(address, "[A-Z]+:[A-Z]+")) {
      address = AddressUtility.ParseEntireColumnSelections(address);
    }
    return address;
  }

  private void SetNullableBoolValue(string path, bool? val) {
    if (val.HasValue) {
      SetXmlNodeBool(path, val.Value);
    } else {
      DeleteNode(path);
    }
  }

  /// <summary>
  /// This method will validate the state of the validation
  /// </summary>
  /// <exception cref="InvalidOperationException">If the state breaks the rules of the validation</exception>
  public virtual void Validate() {
    var address = Address.Address;
    // validate Formula1
    if (string.IsNullOrEmpty(Formula1Internal)) {
      throw new InvalidOperationException(
          "Validation of " + address + " failed: Formula1 cannot be empty");
    }
  }

  /// <summary>
  /// True if the validation type allows operator to be set.
  /// </summary>
  public bool AllowsOperator => ValidationType.AllowOperator;

  /// <summary>
  /// Address of data validation
  /// </summary>
  public ExcelAddress Address {
    get => new(GetXmlNodeString(_sqrefPath));
    private set {
      var address = AddressUtility.ParseEntireColumnSelections(value.Address);
      SetXmlNodeString(_sqrefPath, address);
    }
  }

  /// <summary>
  /// Validation type
  /// </summary>
  public ExcelDataValidationType ValidationType {
    get {
      var typeString = GetXmlNodeString(_typeMessagePath);
      return ExcelDataValidationType.GetBySchemaName(typeString);
    }
    private set => SetXmlNodeString(_typeMessagePath, value.SchemaName, true);
  }

  /// <summary>
  /// Operator for comparison between the entered value and Formula/Formulas.
  /// </summary>
  public ExcelDataValidationOperator Operator {
    get {
      var operatorString = GetXmlNodeString(_operatorPath);
      return Enum.TryParse<ExcelDataValidationOperator>(operatorString, true, out var op)
          ? op
          : ExcelDataValidationOperator.Any;
    }
  }

  /// <summary>
  /// Warning style
  /// </summary>
  public ExcelDataValidationWarningStyle ErrorStyle {
    get {
      var errorStyleString = GetXmlNodeString(_errorStylePath);
      return Enum.TryParse<ExcelDataValidationWarningStyle>(errorStyleString, true, out var style)
          ? style
          : ExcelDataValidationWarningStyle.Undefined;
    }
  }

  /// <summary>
  /// True if blanks should be allowed
  /// </summary>
  public bool? AllowBlank {
    get => GetXmlNodeBoolNullable(_allowBlankPath);
    set => SetNullableBoolValue(_allowBlankPath, value);
  }

  /// <summary>
  /// True if input message should be shown
  /// </summary>
  public bool? ShowInputMessage {
    get => GetXmlNodeBoolNullable(_showInputMessagePath);
    set => SetNullableBoolValue(_showInputMessagePath, value);
  }

  /// <summary>
  /// True if error message should be shown
  /// </summary>
  public bool? ShowErrorMessage {
    get => GetXmlNodeBoolNullable(_showErrorMessagePath);
    set => SetNullableBoolValue(_showErrorMessagePath, value);
  }

  /// <summary>
  /// Title of error message box
  /// </summary>
  public string ErrorTitle {
    get => GetXmlNodeString(_errorTitlePath);
    set => SetXmlNodeString(_errorTitlePath, value);
  }

  /// <summary>
  /// Error message box text
  /// </summary>
  public string Error {
    get => GetXmlNodeString(_errorPath);
    set => SetXmlNodeString(_errorPath, value);
  }

  public string PromptTitle {
    get => GetXmlNodeString(_promptTitlePath);
    set => SetXmlNodeString(_promptTitlePath, value);
  }

  public string Prompt {
    get => GetXmlNodeString(_promptPath);
    set => SetXmlNodeString(_promptPath, value);
  }

  /// <summary>
  /// Formula 1
  /// </summary>
  protected string Formula1Internal => GetXmlNodeString(_formula1Path);

  /// <summary>
  /// Formula 2
  /// </summary>
  protected string Formula2Internal => GetXmlNodeString(_formula2Path);

  protected void SetValue<T>(T? val, string path)
      where T : struct {
    if (!val.HasValue) {
      DeleteNode(path);
    }
    var stringValue = val.Value.ToString().Replace(',', '.');
    SetXmlNodeString(path, stringValue);
  }
}
