namespace WebApi.Controllers;

[ApiController]
[Route("api/[controller]/[action]")]
public class LogController(ILogger<LogController> logger) : ControllerBase
{
    /// <summary>
    /// 获取日志列表（分页）
    /// </summary>
    [HttpGet]
    public async Task<PagedResponse<LogEntry>> GetListAsync(
        [FromQuery] int pageIndex = 1,
        [FromQuery] int pageSize = 50,
        [FromQuery] string? searchKeyword = null,
        [FromQuery] string? logLevel = null,
        [FromQuery] string? date = null
    )
    {
        try
        {
            // 获取日志目录
            var logDirectory = Path.Combine(Directory.GetCurrentDirectory(), "logs");
            if (!Directory.Exists(logDirectory))
            {
                return PagedResponse<LogEntry>.Fail("日志目录不存在");
            }

            // 确定要读取的日志文件
            string logFilePath;
            if (!string.IsNullOrEmpty(date))
            {
                logFilePath = Path.Combine(logDirectory, $"log-{date}.txt");
            }
            else
            {
                // 默认读取今天的日志
                var today = DateTime.Now.ToString("yyyyMMdd");
                logFilePath = Path.Combine(logDirectory, $"log-{today}.txt");
            }

            // 检查文件是否存在
            if (!System.IO.File.Exists(logFilePath))
            {
                return PagedResponse<LogEntry>.Done([], 0);
            }

            // 流式读取日志（边读边过滤，满足条件后停止）
            var (logEntries, total) = await ReadLogsAsync(
                logFilePath,
                pageIndex,
                pageSize,
                searchKeyword,
                logLevel);

            var pagedData = logEntries;

            return PagedResponse<LogEntry>.Done(pagedData.ToArray(), total);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取日志失败");
            return PagedResponse<LogEntry>.Fail($"获取日志失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 获取可用的日志日期列表
    /// </summary>
    [HttpGet]
    public BaseResponse<string[]> GetAvailableDates()
    {
        try
        {
            var logDirectory = Path.Combine(Directory.GetCurrentDirectory(), "logs");
            if (!Directory.Exists(logDirectory))
            {
                return ((string[])[]).Ok();
            }

            var logFiles = Directory.GetFiles(logDirectory, "log-*.txt");
            var dates = logFiles
                .Select(f => Path.GetFileNameWithoutExtension(f))
                .Select(name => name.Replace("log-", ""))
                .OrderByDescending(d => d)
                .ToList();

            return dates.ToArray().Ok();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取日志日期列表失败");
            return $"获取日志日期列表失败: {ex.Message}".Fail<string[]>();
        }
    }

    /// <summary>
    /// 合并多行日志（已废弃，现在在流式读取中处理）
    /// </summary>
    private List<string> MergeMultiLineLog(string[] lines)
    {
        var mergedLines = new List<string>();
        var currentLog = new StringBuilder();

        // 日志行开始的正则表达式
        var logStartPattern = new System.Text.RegularExpressions.Regex(
            @"^\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} [+-]\d{2}:\d{2}\]"
        );

        foreach (var line in lines)
        {
            if (string.IsNullOrWhiteSpace(line))
                continue;

            // 检查是否是新的日志条目
            if (logStartPattern.IsMatch(line))
            {
                // 保存之前的日志
                if (currentLog.Length > 0)
                {
                    mergedLines.Add(currentLog.ToString());
                    currentLog.Clear();
                }
                currentLog.Append(line);
            }
            else
            {
                // 这是上一条日志的延续,添加换行符后追加
                if (currentLog.Length > 0)
                {
                    currentLog.Append('\n').Append(line);
                }
            }
        }

        // 添加最后一条日志
        if (currentLog.Length > 0)
        {
            mergedLines.Add(currentLog.ToString());
        }

        return mergedLines;
    }

    /// <summary>
    /// 解析单行日志
    /// </summary>
    private LogEntry? ParseLogLine(string line)
    {
        try
        {
            // 日志格式示例: [2025-12-29 16:38:45.730 +08:00] [INF] Message here
            // 使用正则表达式解析
            // 使用 Singleline 模式使 '.' 可以匹配换行，这样 multi-line 消息可以被完整捕获。
            var match = System.Text.RegularExpressions.Regex.Match(
                line,
                @"^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} [+-]\d{2}:\d{2})\] \[([A-Z]{2,5})\] ([\s\S]*)$",
                System.Text.RegularExpressions.RegexOptions.Singleline
            );

            if (match.Success)
            {
                return new LogEntry
                {
                    Timestamp = match.Groups[1].Value,
                    Level = match.Groups[2].Value,
                    Message = match.Groups[3].Value
                };
            }

            // 如果不匹配标准格式，将整行作为消息
            return new LogEntry
            {
                Timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff zzz"),
                Level = "LOG",
                Message = line
            };
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// 读取日志
    /// </summary>
    private async Task<(List<LogEntry> entries, int total)> ReadLogsAsync(
        string path,
        int pageIndex,
        int pageSize,
        string? searchKeyword,
        string? logLevel)
    {
        var allLines = await ReadAllLinesAsync(path);

        var merged = MergeMultiLineLog(allLines);

        var parsed = new List<LogEntry>();
        foreach (var line in merged)
        {
            var entry = ParseLogLine(line);
            if (entry != null && PassFilter(entry, searchKeyword, logLevel))
            {
                parsed.Add(entry);
            }
        }

        parsed.Reverse();

        var total = parsed.Count;
        var skip = Math.Max(0, (pageIndex - 1) * pageSize);
        var pagedData = parsed.Skip(skip).Take(pageSize).ToList();

        return (pagedData, total);
    }

    /// <summary>
    /// 检查日志条目是否通过过滤条件
    /// </summary>
    private bool PassFilter(LogEntry logEntry, string? searchKeyword, string? logLevel)
    {
        if (!string.IsNullOrEmpty(searchKeyword) &&
            !logEntry.Message.Contains(searchKeyword, StringComparison.OrdinalIgnoreCase))
        {
            return false;
        }

        if (!string.IsNullOrEmpty(logLevel) &&
            !logEntry.Level.Equals(logLevel, StringComparison.OrdinalIgnoreCase))
        {
            return false;
        }

        return true;
    }

    /// <summary>
    /// 读取文件所有行（支持共享读取）
    /// </summary>
    private async Task<string[]> ReadAllLinesAsync(string path)
    {
        var lines = new List<string>();

        using (var fileStream = new FileStream(
            path,
            FileMode.Open,
            FileAccess.Read,
            FileShare.ReadWrite))
        using (var streamReader = new StreamReader(fileStream))
        {
            string? line;
            while ((line = await streamReader.ReadLineAsync()) != null)
            {
                lines.Add(line);
            }
        }

        return lines.ToArray();
    }
}

/// <summary>
/// 日志条目
/// </summary>
public class LogEntry
{
    /// <summary>
    /// 时间戳
    /// </summary>
    public string Timestamp { get; set; } = string.Empty;

    /// <summary>
    /// 日志级别
    /// </summary>
    public string Level { get; set; } = string.Empty;

    /// <summary>
    /// 日志消息
    /// </summary>
    public string Message { get; set; } = string.Empty;
}