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("range", Description = "Fetch records between explicit start and end timestamps.")]
    public sealed class RangeCommand : ReadCommandBase, ICommand
    {
        [CommandOption("from", IsRequired = true, Description = "Start timestamp (ISO-8601 local time, e.g. 2026-05-03T14:00:00).")]
        public DateTime From { get; init; }

        [CommandOption("to", Description = "End timestamp (ISO-8601 local time). Defaults to now.")]
        public DateTime? To { get; init; }

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

        public ValueTask ExecuteAsync(IConsole console)
        {
            var to = To ?? DateTime.Now;
            if (to <= From)
                throw new CommandException("--to must be later than --from.", 2);

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

            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 = "range",
                    from = From.ToString("yyyy-MM-ddTHH:mm:ss"),
                    to = to.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;
        }
    }
}
