namespace TaxBaik.Application.Services;

using Microsoft.Extensions.Caching.Memory;
using TaxBaik.Domain.Entities;

public record AdminDashboardSummary(
    int ThisMonthInquiries,
    int NewInquiries,
    int TotalPosts,
    int PublishedPosts,
    IReadOnlyList<Inquiry> RecentInquiries);

public class AdminDashboardService(
    InquiryService inquiryService,
    BlogService blogService,
    IMemoryCache memoryCache)
{
    private static readonly TimeSpan CacheDuration = TimeSpan.FromSeconds(30);
    public const string CacheKey = "admin-dashboard-summary";

    public async Task<AdminDashboardSummary> GetSummaryAsync(CancellationToken ct = default)
    {
        if (memoryCache.TryGetValue(CacheKey, out AdminDashboardSummary? cached) && cached != null)
            return cached;

        var recentTask = inquiryService.GetPagedAsync(1, 5, ct: ct);
        var thisMonthTask = inquiryService.CountThisMonthAsync(ct);
        var newTask = inquiryService.CountByStatusAsync("new", ct);
        var statsTask = blogService.GetStatsAsync(ct);

        var (recentInquiries, _) = await recentTask;
        var stats = await statsTask;
        var summary = new AdminDashboardSummary(
            ThisMonthInquiries: await thisMonthTask,
            NewInquiries: await newTask,
            TotalPosts: stats.TotalPosts,
            PublishedPosts: stats.PublishedPosts,
            RecentInquiries: recentInquiries.OrderByDescending(x => x.CreatedAt).Take(5).ToList());

        memoryCache.Set(CacheKey, summary, CacheDuration);
        return summary;
    }

    /// <summary>
    /// 최근 문의 조회
    /// </summary>
    public async Task<IReadOnlyList<Inquiry>> GetRecentInquiriesAsync(int limit, CancellationToken ct = default)
    {
        var (inquiries, _) = await inquiryService.GetPagedAsync(1, limit, ct: ct);
        return inquiries.OrderByDescending(x => x.CreatedAt).ToList();
    }

    /// <summary>
    /// 월별 통계 (접수 건수, 진행 중, 완료)
    /// </summary>
    public async Task<object> GetMonthlyStatsAsync(string? month, CancellationToken ct = default)
    {
        var targetMonth = month != null && DateTime.TryParse($"{month}-01", out var dt)
            ? dt
            : DateTime.Today;

        var startDate = new DateTime(targetMonth.Year, targetMonth.Month, 1);
        var endDate = startDate.AddMonths(1).AddDays(-1);

        // 캐시 시도 (일 단위)
        var cacheKey = $"admin-stats-{startDate:yyyy-MM}";
        if (memoryCache.TryGetValue(cacheKey, out object? cachedStats) && cachedStats != null)
            return cachedStats;

        var total = await inquiryService.CountByDateRangeAsync(startDate, endDate, ct);
        var consulting = await inquiryService.CountByStatusAndDateAsync("consulting", startDate, endDate, ct);
        var completed = await inquiryService.CountByStatusAndDateAsync("contracted", startDate, endDate, ct);

        var result = new
        {
            month = startDate.ToString("yyyy-MM"),
            totalInquiries = total,
            consultingCount = consulting,
            completedCount = completed,
            newCount = total - consulting - completed,
            completionRate = total > 0 ? (completed * 100.0 / total) : 0.0
        };

        memoryCache.Set(cacheKey, result, TimeSpan.FromHours(1));
        return result;
    }
}
