/* 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;
using OfficeOpenXml.FormulaParsing.ExcelUtilities;
using OfficeOpenXml.FormulaParsing.Exceptions;
using OfficeOpenXml.FormulaParsing.ExpressionGraph;
using OfficeOpenXml.FormulaParsing.Utilities;
using Util = OfficeOpenXml.Utils;

namespace OfficeOpenXml.FormulaParsing.Excel.Functions.Math;

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 += Util.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;
  //}
}
