/* 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		                2013-12-03
 *******************************************************************************/

using System.Collections.Generic;
using System.Linq;

namespace AppsheetEpplus;

public class SumIf : HiddenValuesHandlingFunction {
  private readonly NumericExpressionEvaluator _evaluator;

  public SumIf()
      : this(new()) {}

  public SumIf(NumericExpressionEvaluator evaluator) {
    Require.That(evaluator).Named("evaluator").IsNotNull();
    _evaluator = evaluator;
  }

  public override CompileResult Execute(
      IEnumerable<FunctionArgument> arguments,
      ParsingContext context) {
    ValidateArguments(arguments, 2);
    var args = arguments.ElementAt(0).Value as ExcelDataProvider.IRangeInfo; //IEnumerable<FunctionArgument>;
    var criteria = arguments.ElementAt(1).Value;
    ThrowExcelErrorValueExceptionIf(
        () => criteria == null || criteria.ToString().Length > 255,
        eErrorType.Value);
    double retVal;
    if (arguments.Count() > 2) {
      var sumRange = arguments.ElementAt(2).Value as ExcelDataProvider.IRangeInfo; //IEnumerable<FunctionArgument>;
      retVal = CalculateWithSumRange(args, criteria.ToString(), sumRange, context);
    } else {
      if (args != null) {
        retVal = CalculateSingleRange(args, criteria.ToString(), context);
      } else {
        retVal = CalculateSingleRange(
            (arguments.ElementAt(0).Value as IEnumerable<FunctionArgument>),
            criteria.ToString(),
            context);
      }
    }
    return CreateResult(retVal, DataType.Decimal);
  }

  private double CalculateWithSumRange(
      ExcelDataProvider.IRangeInfo range,
      string criteria,
      ExcelDataProvider.IRangeInfo sumRange,
      ParsingContext context) {
    var retVal = 0d;
    foreach (var cell in range) {
      if (_evaluator.Evaluate(cell.Value, criteria)) {
        var or = cell.Row - range.Address._fromRow;
        var oc = cell.Column - range.Address._fromCol;
        if (sumRange.Address._fromRow + or <= sumRange.Address._toRow
            && sumRange.Address._fromCol + oc <= sumRange.Address._toCol) {
          var v = sumRange.GetOffset(or, oc);
          if (v is ExcelErrorValue value) {
            throw (new ExcelErrorValueException(value));
          }
          retVal += ConvertUtil.GetValueDouble(v, true);
        }
      }
    }
    return retVal;
  }

  private double CalculateSingleRange(
      IEnumerable<FunctionArgument> args,
      string expression,
      ParsingContext context) {
    var retVal = 0d;
    var flattendedRange = ArgsToDoubleEnumerable(args, context);
    foreach (var candidate in flattendedRange) {
      if (_evaluator.Evaluate(candidate, expression)) {
        retVal += candidate;
      }
    }
    return retVal;
  }

  private double CalculateSingleRange(
      ExcelDataProvider.IRangeInfo range,
      string expression,
      ParsingContext context) {
    var retVal = 0d;
    foreach (var candidate in range) {
      if (_evaluator.Evaluate(candidate.Value, expression)) {
        if (candidate.IsExcelError) {
          throw (new ExcelErrorValueException((ExcelErrorValue)candidate.Value));
        }
        retVal += candidate.ValueDouble;
      }
    }
    return retVal;
  }

  //private double Calculate(FunctionArgument arg, string expression)
  //{
  //    var retVal = 0d;
  //    if (ShouldIgnore(arg) || !_evaluator.Evaluate(arg.Value, expression))
  //    {
  //        return retVal;
  //    }
  //    if (arg.Value is double || arg.Value is int)
  //    {
  //        retVal += Convert.ToDouble(arg.Value);
  //    }
  //    else if (arg.Value is System.DateTime)
  //    {
  //        retVal += Convert.ToDateTime(arg.Value).ToOADate();
  //    }
  //    else if (arg.Value is IEnumerable<FunctionArgument>)
  //    {
  //        foreach (var item in (IEnumerable<FunctionArgument>)arg.Value)
  //        {
  //            retVal += Calculate(item, expression);
  //        }
  //    }
  //    return retVal;
  //}
}
