using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AaLog.Cli.Filtering;
using AaLog.Cli.Output;
using CliFx;
using CliFx.Attributes;
using CliFx.Infrastructure;

namespace AaLog.Cli.Commands
{
    [Command("unread", Description = "Fetch records the cache has not yet seen. Useful for incremental polling.")]
    public sealed class UnreadCommand : ReadCommandBase, ICommand
    {
        [CommandOption("max", Description = "Maximum number of unread records to return. Default 1000.")]
        public ulong Max { get; init; } = 1000;

        [CommandOption("ignore-cache", Description = "Re-read regardless of the cache file. The next call will pick up from the new high-water mark.")]
        public bool IgnoreCache { get; init; }

        [CommandOption("client-id", Description = "Optional client ID. Use distinct IDs to maintain independent cache files for parallel consumers.")]
        public string ClientId { get; init; }

        public ValueTask ExecuteAsync(IConsole console)
        {
            using var reader = LogReaderFactory.Open(LogDirectory);
            var raw = reader.GetUnreadRecords(Max, "", IgnoreCache, ClientId)
                      ?? new List<aaLogReader.LogRecord>();

            var dtos = raw.OrderByDescending(r => r.EventDateTimeUtc).Select(LogRecordDto.From);
            var filtered = RecordFilter.Apply(dtos, Component, Level, Message, UseRegex);

            if (LlmJson)
            {
                var query = new
                {
                    command = "unread",
                    max = Max,
                    ignore_cache = IgnoreCache,
                    client_id = ClientId,
                    component = Component,
                    level = Level,
                    message = Message,
                    regex = UseRegex,
                    log_dir = reader.Options.LogDirectory,
                };
                OutputWriter.WriteLlmJson(console, query, filtered);
            }
            else
            {
                OutputWriter.WriteHuman(console, filtered);
            }
            return default;
        }
    }
}
