using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Beam.Abstractions;

namespace Beam.Dynamic {
    public static class CommonStateChangers {
        public static IStateChangeBehaviour LastAsNumber => new NumberedStateChanger((x, i) => {
            object last = x.GetState()[^1];
            if (!int.TryParse(last.ToString(), out var number))
                throw new InvalidOperationException(Exceptions.Exceptions.state_change_error); // TODO use more specific exception
            x.GetState()[^1] = (number + i).ToString();
        });

        public static IStateChangeBehaviour Constant => new ConstantStateChanger();

        public static IStateChangeBehaviour NthAsNumber(Index n, bool keepSuffix = true)
            => new NumberedStateChanger((x, i) => {
                string? nth = x.GetState()[n]?.ToString();
                string[] xState = x.GetState();
                if (nth is null)
                    throw new InvalidOperationException(Exceptions.Exceptions.state_change_error); // TODO use more specific exception
                if (!int.TryParse(nth, out var number))
                    if (keepSuffix) {
                        string[] split = nth.Split('.');
                        if (!int.TryParse(split[0], out number))
                            throw new InvalidOperationException(Exceptions.Exceptions.state_change_error); // TODO use more specific exception
                        xState[n] = (number + i) + split[1..].Aggregate((x, y) => $"{x}.{y}");
                        return;
                    } else
                        throw new InvalidOperationException(Exceptions.Exceptions.state_change_error); // TODO use more specific exception
                xState[n] = (number + i).ToString();
            });


    }
}
