using Microsoft.EntityFrameworkCore;
using LogCentral.Server.Data;
using LogCentral.Server.Models;
using System.Text.Json;

namespace LogCentral.Server.Services;

public class LogService : ILogService
{
    private readonly LogCentralDbContext _context;

    public LogService(LogCentralDbContext context)
    {
        _context = context;
    }

    public async Task AddLogsAsync(List<LogEntry> entries)
    {
        await _context.LogEntries.AddRangeAsync(entries);
        await _context.SaveChangesAsync();
    }

    public async Task<LogEntry?> GetLogByIdAsync(string id)
    {
        return await _context.LogEntries.FindAsync(id);
    }

    public async Task<PagedResult<LogEntry>> GetLogsAsync(LogQueryParams queryParams)
    {
        var query = _context.LogEntries.AsQueryable();

        if (!string.IsNullOrEmpty(queryParams.Search))
        {
            query = query.Where(l =>
                l.Message.Contains(queryParams.Search) ||
                l.Exception!.Contains(queryParams.Search) ||
                l.Category.Contains(queryParams.Search));
        }

        if (!string.IsNullOrEmpty(queryParams.Application))
            query = query.Where(l => l.ApplicationName == queryParams.Application);

        if (!string.IsNullOrEmpty(queryParams.Environment))
            query = query.Where(l => l.Environment == queryParams.Environment);

        if (queryParams.Level.HasValue)
            query = query.Where(l => l.Level == queryParams.Level.Value);

        if (queryParams.StartDate.HasValue)
            query = query.Where(l => l.Timestamp >= queryParams.StartDate.Value);

        if (queryParams.EndDate.HasValue)
            query = query.Where(l => l.Timestamp <= queryParams.EndDate.Value);

        var totalCount = await query.CountAsync();
        var items = await query
            .OrderByDescending(l => l.Timestamp)
            .Skip((queryParams.Page - 1) * queryParams.PageSize)
            .Take(queryParams.PageSize)
            .ToListAsync();

        return new PagedResult<LogEntry>
        {
            Items = items,
            TotalCount = totalCount,
            Page = queryParams.Page,
            PageSize = queryParams.PageSize
        };
    }

    public async Task<Dictionary<string, object>> GetStatsAsync(string? app, string? env)
    {
        var query = _context.LogEntries.AsQueryable();

        if (!string.IsNullOrEmpty(app))
            query = query.Where(l => l.ApplicationName == app);

        if (!string.IsNullOrEmpty(env))
            query = query.Where(l => l.Environment == env);

        var last24Hours = DateTime.UtcNow.AddHours(-24);
        var stats = new Dictionary<string, object>
        {
            ["totalLogs"] = await query.CountAsync(),
            ["last24Hours"] = await query.Where(l => l.Timestamp >= last24Hours).CountAsync(),
            ["errorCount"] = await query.Where(l => l.Level >= 4).CountAsync(),
            ["warningCount"] = await query.Where(l => l.Level == 3).CountAsync(),
            ["applications"] = await _context.LogEntries
                .Select(l => l.ApplicationName)
                .Distinct()
                .CountAsync(),
            ["byLevel"] = await query
                .GroupBy(l => l.Level)
                .Select(g => new { Level = g.Key, Count = g.Count() })
                .ToListAsync()
        };

        return stats;
    }

    public async Task<bool> ValidateApiKeyAsync(string apiKey)
    {
        return await _context.Applications
            .AnyAsync(a => a.ApiKey == apiKey && a.IsActive);
    }
}