/* 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);
    var retVal = 0d;
    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(
      IEnumerable<FunctionArgument> range,
      string criteria,
      IEnumerable<FunctionArgument> sumRange,
      ParsingContext context) {
    var retVal = 0d;
    var flattenedRange = ArgsToDoubleEnumerable(range, context);
    var flattenedSumRange = ArgsToDoubleEnumerable(sumRange, context);
    for (var x = 0; x < flattenedRange.Count(); x++) {
      var candidate = flattenedSumRange.ElementAt(x);
      if (_evaluator.Evaluate(flattenedRange.ElementAt(x), criteria)) {
        retVal += candidate;
      }
    }
    return retVal;
  }

  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) {
            throw (new ExcelErrorValueException((ExcelErrorValue)v));
          }
          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;
  //}
}
