using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AdvancedCalculator.Models;

// Intentionally keep the csmic/CSMic dependency surface in this file only.
// This allows easy adaptation if the interpreter API changes.
namespace AdvancedCalculator.Services;

public class CalculatorService : ICalculatorService
{
    private readonly object _lock = new();

    private readonly CSMic.InputInterpreter _interpreter = new();

    public CalculatorService()
    {
        CSMic.StandardLibrary.Initializer.InitializeAllFunctions(_interpreter);
    }

    public Task<InterpretResult> InterpretAsync(string input)
    {
        return Task.Run(() =>
        {
            lock (_lock)
            {
                _interpreter.Interpret(input);
                var output = string.IsNullOrWhiteSpace(_interpreter.StringValue) ? _interpreter.NumericValue.ToString() : _interpreter.StringValue;

                // Build variables list
                var variables = new List<VariableItem>();
                foreach (var csmicVariable in _interpreter.Variables)
                {
                    var name = csmicVariable.Name;
                    var variable = csmicVariable.Value;
                    var valueString = variable?.ToString() ?? string.Empty;

                    var isExpression = csmicVariable.Type == CSMic.VariableType.Expression;
                    var item = new VariableItem
                    {
                        VariableName = name,
                        Value = valueString,
                        IsExpression = isExpression,
                        ExpressionComputation = null,
                        Icon = IconFont.Variable
                    };

                    if (isExpression && !string.IsNullOrWhiteSpace(valueString))
                    {
                        // Compute the expression-based variable's current value
                        _interpreter.Interpret(valueString);
                        item.ExpressionComputation = _interpreter.StringValue ?? string.Empty;
                        item.Icon = IconFont.Function;
                    }

                    variables.Add(item);
                }

                return new InterpretResult
                {
                    Output = output,
                    Variables = variables
                };
            }
        });
    }
}

