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();

    // We attempt to use the legacy namespace to maximize compatibility.
    // If using the newer CSMic.StandardLibrary with different namespaces,
    // update the using directives and type names here.
    private readonly csmic.InputInterpreter _interpreter = new();

    public Task<InterpretResult> InterpretAsync(string input)
    {
        return Task.Run(() =>
        {
            lock (_lock)
            {
                _interpreter.Interpret(input);
                var output = _interpreter.Output ?? string.Empty;

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

                    var isExpression = variable?.Type == csmic.VariableType.Equation;
                    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.Output ?? string.Empty;
                        item.Icon = IconFont.Function;
                    }

                    variables.Add(item);
                }

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

