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)
                {
                    // Store the raw value without any formatting
                    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;
                    
                    // Format the value if it's not already formatted as an array
                    if (!string.IsNullOrEmpty(value) && !(value.StartsWith('[') && value.EndsWith(']')))
                    {
                        value = $"[\"{value.Replace("\"", "\\\"")}\"]";
                    }
                    
                    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);

                    if (end == -1)
                        end = list.Count - 1;

                    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);
                        
                        // Format each item as a JSON string if it's not already
                        var formattedItems = value.Select(item => (item.StartsWith('[') && item.EndsWith(']')) ? item : $"[\"{item.Replace("\"", "\\\"")}\"]");
                        
                        string data = string.Join(",", formattedItems);
                        Main.Log($"ListRange: {listName} - StartIndex: {start} - EndIndex: {end} - Count: {count}", "debug");
                        Utils.CheckByteCount(uniqueId, $"[{data}]", function, entity, Convert.ToBoolean(call), bufferSize);
                    }
                    else
                    {
                        Main.Log($"ListRange: {listName} - Invalid range or empty result", "debug");
                        Utils.CheckByteCount(uniqueId, "[]", function, entity, Convert.ToBoolean(call), bufferSize);
                    }
                }
            }
            else
            {
                Main.Log($"ListRange: {listName} - List not found", "debug");
                Utils.CheckByteCount(uniqueId, "[]", 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)
                    {
                        // Store the value as-is, just like ListAddAsync
                        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");
                }
            }
        }
    }
}