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

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using OfficeOpenXml.DataValidation.Formulas.Contracts;
using OfficeOpenXml.Utils;

namespace OfficeOpenXml.DataValidation.Formulas;

internal class ExcelDataValidationFormulaList
    : ExcelDataValidationFormula,
      IExcelDataValidationFormulaList {
  private class DataValidationList : IList<string>, ICollection {
    private readonly IList<string> _items = new List<string>();
    private EventHandler<EventArgs> _listChanged;

    public event EventHandler<EventArgs> ListChanged {
      add => _listChanged += value;
      remove => _listChanged -= value;
    }

    private void OnListChanged() {
      if (_listChanged != null) {
        _listChanged(this, EventArgs.Empty);
      }
    }

    int IList<string>.IndexOf(string item) {
      return _items.IndexOf(item);
    }

    void IList<string>.Insert(int index, string item) {
      _items.Insert(index, item);
      OnListChanged();
    }

    void IList<string>.RemoveAt(int index) {
      _items.RemoveAt(index);
      OnListChanged();
    }

    string IList<string>.this[int index] {
      get => _items[index];
      set {
        _items[index] = value;
        OnListChanged();
      }
    }

    void ICollection<string>.Add(string item) {
      _items.Add(item);
      OnListChanged();
    }

    void ICollection<string>.Clear() {
      _items.Clear();
      OnListChanged();
    }

    bool ICollection<string>.Contains(string item) {
      return _items.Contains(item);
    }

    void ICollection<string>.CopyTo(string[] array, int arrayIndex) {
      _items.CopyTo(array, arrayIndex);
    }

    int ICollection<string>.Count => _items.Count;

    bool ICollection<string>.IsReadOnly => false;

    bool ICollection<string>.Remove(string item) {
      var retVal = _items.Remove(item);
      OnListChanged();
      return retVal;
    }

    IEnumerator<string> IEnumerable<string>.GetEnumerator() {
      return _items.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator() {
      return _items.GetEnumerator();
    }

    public void CopyTo(Array array, int index) {
      _items.CopyTo((string[])array, index);
    }

    int ICollection.Count => _items.Count;

    public bool IsSynchronized => ((ICollection)_items).IsSynchronized;

    public object SyncRoot => ((ICollection)_items).SyncRoot;
  }

  public ExcelDataValidationFormulaList(
      XmlNamespaceManager namespaceManager,
      XmlNode itemNode,
      string formulaPath)
      : base(namespaceManager, itemNode, formulaPath) {
    Require.Argument(formulaPath).IsNotNullOrEmpty("formulaPath");
    _formulaPath = formulaPath;
    var values = new DataValidationList();
    values.ListChanged += values_ListChanged;
    Values = values;
    SetInitialValues();
  }

  private readonly string _formulaPath;

  private void SetInitialValues() {
    var value = GetXmlNodeString(_formulaPath);
    if (!string.IsNullOrEmpty(value)) {
      if (value.StartsWith("\"") && value.EndsWith("\"")) {
        value = value.TrimStart('"').TrimEnd('"');
        var items = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
        foreach (var item in items) {
          Values.Add(item);
        }
      } else {
        ExcelFormula = value;
      }
    }
  }

  private void values_ListChanged(object sender, EventArgs e) {
    if (Values.Count > 0) {
      State = FormulaState.Value;
    }
    var valuesAsString = GetValueAsString();
    // Excel supports max 255 characters in this field.
    if (valuesAsString.Length > 255) {
      throw new InvalidOperationException(
          "The total length of a DataValidation list cannot exceed 255 characters");
    }
    SetXmlNodeString(_formulaPath, valuesAsString);
  }

  public IList<string> Values { get; private set; }

  protected override string GetValueAsString() {
    var sb = new StringBuilder();
    foreach (var val in Values) {
      if (sb.Length == 0) {
        sb.Append("\"");
        sb.Append(val);
      } else {
        sb.AppendFormat(",{0}", val);
      }
    }
    sb.Append("\"");
    return sb.ToString();
  }

  internal override void ResetValue() {
    Values.Clear();
  }
}
