using System;
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.Exceptions;
using CliFx.Infrastructure;

namespace AaLog.Cli.Commands
{
    [Command("tail", Description = "Fetch records from the last N minutes.")]
    public sealed class TailCommand : ReadCommandBase, ICommand
    {
        [CommandOption("minutes", 'm', Description = "How many minutes back from now to read. Default 10.")]
        public int Minutes { get; init; } = 10;

        [CommandOption("max", Description = "Hard cap on records returned to keep LLM payloads bounded. Default 1000.")]
        public int Max { get; init; } = 1000;

        public ValueTask ExecuteAsync(IConsole console)
        {
            if (Minutes <= 0)
                throw new CommandException("--minutes must be a positive integer.", 2);

            var end = DateTime.Now;
            var start = end.AddMinutes(-Minutes);

            using var reader = LogReaderFactory.Open(LogDirectory);
            var raw = reader.GetRecordsByStartAndEndTimeStamp(start, end) ?? new List<aaLogReader.LogRecord>();

            // Newest first, then cap.
            var ordered = raw.OrderByDescending(r => r.EventDateTimeUtc).Take(Max);
            var dtos = ordered.Select(LogRecordDto.From);
            var filtered = RecordFilter.Apply(dtos, Component, Level, Message, UseRegex);

            if (LlmJson)
            {
                var query = new
                {
                    command = "tail",
                    minutes = Minutes,
                    start = start.ToString("yyyy-MM-ddTHH:mm:ss"),
                    end = end.ToString("yyyy-MM-ddTHH:mm:ss"),
                    max = Max,
                    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;
        }
    }
}
