using System.Collections;

namespace InnovEnergy.Lib.Units;

public readonly struct State : IReadOnlyList<String>
{
    public IReadOnlyList<String> Values { get; }
    
    public State(IReadOnlyList<String> values)
    {
        if (values.Any(v => v.Contains(";")))
            throw new ArgumentException("State values cannot contain the character ;", nameof(values));
        
        Values = values;
    }

    public State(params String[] values) : this((IReadOnlyList<String>)values){}
    public State(params State[]  states) : this((IReadOnlyList<String>)states.SelectMany(s => s.Values).ToList()){}

    public static implicit operator State(String s)       => new(s);
    public static implicit operator State(Enum e)         => new(e.ToString());
    public static implicit operator State(Boolean s)      => new(s.ToString());
    public static implicit operator State(List<String> s) => new((IReadOnlyList<String>)s);
    public static implicit operator State(String[] s)     => new((IReadOnlyList<String>)s);
    public static implicit operator State(List<Enum> es)  => new(es.Select(e => e.ToString()).ToList());
    public static implicit operator State(Enum[] es)      => new(es.Select(e => e.ToString()).ToList());
    
    public static State operator |(State left, State right) => new(left, right);

    public IEnumerator<String> GetEnumerator() => Values.GetEnumerator();

    public override String ToString() => String.Join("; ", Values);
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

    public Int32 Count => Values.Count;
    public String this[Int32 index] => Values[index];

    public static State<T> From<T>(T t) where T : Enum
    {
        return new State<T>(t);
    }
}