using System.Collections.Concurrent;

#pragma warning disable IDE0130 // Namespace does not match folder structure
namespace ArmaRAMDb
#pragma warning restore IDE0130 // Namespace does not match folder structure
{
    internal class ListStore
    {
        private static readonly ConcurrentDictionary<string, List<string>> _lists = RAMDb._lists;

        public static async Task ListAddAsync(string listName, string value)
        {
            await Task.Yield();
            
            lock (_lists)
            {
                if (!_lists.TryGetValue(listName, out List<string> list))
                {
                    list = [];
                    _lists[listName] = list;
                }

                lock (list)
                {
                    if (value.StartsWith('[') && value.EndsWith(']'))
                    {
                        list.Add(value);
                    }
                    else
                    {
                        list.Add($"[\"{value}\"]");
                    }
                    Main.Log($"ListAdd: {listName} - Value: {value}", "debug");
                }
            }
        }

        public static async Task ListDeleteAsync(string listName)
        {
            await Task.Yield();
            bool result = _lists.TryRemove(listName, out _);
            
            Main.Log($"ListDelete: {listName} - Success: {result}", "debug");
        }

        public static async Task ListIndexAsync(string listName, string index, string function, string uniqueId, string entity = null, string call = "false", int bufferSize = Main.ARDB_BUFFERSIZE)
        {
            await Task.Yield();
            
            if (_lists.TryGetValue(listName, out var list))
            {
                lock (list)
                {
                    int idx = int.Parse(index);
                    string value = idx >= 0 && idx < list.Count ? list[idx] : string.Empty;
                    Main.Log($"ListIndex: {listName} - Index: {idx} - Value: {value}", "debug");
                    Utils.CheckByteCount(uniqueId, value, function, entity, Convert.ToBoolean(call), bufferSize);
                }
            }
        }

        public static async Task ListRangeAsync(string listName, string startIndex, string endIndex, string function, string uniqueId, string entity = null, string call = "false", int bufferSize = Main.ARDB_BUFFERSIZE)
        {            
            await Task.Yield();
            
            if (_lists.TryGetValue(listName, out var list))
            {
                lock (list)
                {
                    int start = int.Parse(startIndex);
                    int end = int.Parse(endIndex);
                    start = Math.Max(0, start);
                    end = Math.Min(list.Count - 1, end);

                    if (start <= end)
                    {
                        int count = end - start + 1;
                        var value = list.GetRange(start, count);
                        string data = string.Join(",", value);
                        Main.Log($"ListRange: {listName} - StartIndex: {start} - EndIndex: {end} - Count: {count}", "debug");
                        Utils.CheckByteCount(uniqueId, $"[{data}]", function, entity, Convert.ToBoolean(call), bufferSize);
                    }
                }
            }
        }

        public static async Task ListSetAsync(string listName, string index, string value)
        {
            await Task.Yield();
            
            if (_lists.TryGetValue(listName, out var list))
            {
                lock (list)
                {
                    int idx = int.Parse(index);
                    if (idx >= 0 && idx < list.Count)
                    {
                        if (value.StartsWith('[') && value.EndsWith(']'))
                        {
                            list[idx] = value;
                        }
                        else
                        {
                            list[idx] = $"[\"{value}\"]";
                        }
                        Main.Log($"ListSet: {listName} - Index: {idx} - Value: {value}", "debug");
                    }
                }
            }
        }

        public static async Task ListRemoveAsync(string listName, string value)
        {
            await Task.Yield();
            
            if (_lists.TryGetValue(listName, out var list))
            {
                lock (list)
                {
                    int removedCount = list.RemoveAll(item => item == value);
                    Main.Log($"ListRemove: {listName} - Value: {value} - Removed Count: {removedCount}", "debug");
                }
            }
        }
    }
}