using System.Collections.Generic;

namespace AppsheetEpplus;

/// <summary>
/// This class should be implemented to be able to deliver excel data
/// to the formula parser.
/// </summary>
public abstract class ExcelDataProvider {
  /// <summary>
  /// A range of cells in a worksheet.
  /// </summary>
  public interface IRangeInfo : IEnumerator<ICellInfo>, IEnumerable<ICellInfo> {
    bool IsEmpty { get; }

    bool IsMulti { get; }

    int GetNCells();

    ExcelAddressBase Address { get; }

    object GetValue(int row, int col);

    object GetOffset(int rowOffset, int colOffset);

    ExcelWorksheet Worksheet { get; }
  }

  /// <summary>
  /// Information and help methods about a cell
  /// </summary>
  public interface ICellInfo {
    string Address { get; }

    int Row { get; }

    int Column { get; }

    string Formula { get; }

    object Value { get; }

    double ValueDouble { get; }

    double ValueDoubleLogical { get; }

    bool IsHiddenRow { get; }

    bool IsExcelError { get; }

    IList<Token> Tokens { get; }
  }

  public interface INameInfo {
    ulong Id { get; set; }

    string Worksheet { get; set; }

    string Name { get; set; }

    string Formula { get; set; }

    IList<Token> Tokens { get; }

    object Value { get; set; }
  }

  /// <summary>
  /// Returns the names of all worksheet names
  /// </summary>
  /// <returns></returns>
  public abstract ExcelNamedRangeCollection GetWorksheetNames(string worksheet);

  /// <summary>
  /// Returns all defined names in a workbook
  /// </summary>
  /// <returns></returns>
  public abstract ExcelNamedRangeCollection GetWorkbookNameValues();

  /// <summary>
  /// Returns values from the required range.
  /// </summary>
  /// <param name="worksheetName">The name of the worksheet</param>
  /// <param name="row">Row</param>
  /// <param name="column">Column</param>
  /// <param name="address">The reference address</param>
  /// <returns></returns>
  public abstract IRangeInfo GetRange(string worksheetName, int row, int column, string address);

  public abstract INameInfo GetName(string worksheet, string name);

  public abstract IEnumerable<object> GetRangeValues(string address);

  public abstract string GetRangeFormula(string worksheetName, int row, int column);

  public abstract List<Token> GetRangeFormulaTokens(string worksheetName, int row, int column);

  public abstract bool IsRowHidden(string worksheetName, int row);

  ///// <summary>
  ///// Returns a single cell value
  ///// </summary>
  ///// <param name="address"></param>
  ///// <returns></returns>
  //public abstract object GetCellValue(int sheetID, string address);

  /// <summary>
  /// Returns a single cell value
  /// </summary>
  /// <param name="sheetName"></param>
  /// <param name="row"></param>
  /// <param name="col"></param>
  /// <returns></returns>
  public abstract object GetCellValue(string sheetName, int row, int col);

  ///// <summary>
  ///// Sets the value on the cell
  ///// </summary>
  ///// <param name="address"></param>
  ///// <param name="value"></param>
  //public abstract void SetCellValue(string address, object value);

  /// <summary>
  /// Returns the address of the lowest rightmost cell on the worksheet.
  /// </summary>
  /// <param name="worksheet"></param>
  /// <returns></returns>
  public abstract ExcelCellAddress GetDimensionEnd(string worksheet);

  /// <summary>
  /// Max number of columns in a worksheet that the Excel data provider can handle.
  /// </summary>
  public abstract int ExcelMaxColumns { get; }

  /// <summary>
  /// Max number of rows in a worksheet that the Excel data provider can handle
  /// </summary>
  public abstract int ExcelMaxRows { get; }

  public abstract object GetRangeValue(string worksheetName, int row, int column);

  public abstract string GetFormat(object value, string format);

  public abstract void Reset();

  public abstract IRangeInfo GetRange(
      string worksheet,
      int fromRow,
      int fromCol,
      int toRow,
      int toCol);
}
