using Microsoft.EntityFrameworkCore;
using DramaLing.Api.Data;
using DramaLing.Api.Models.Entities;

namespace DramaLing.Api.Services;

public interface IUsageTrackingService
{
    Task<bool> CheckUsageLimitAsync(Guid userId, bool isPremium = false);
    Task RecordSentenceAnalysisAsync(Guid userId);
    Task RecordWordQueryAsync(Guid userId, bool wasHighValue);
    Task<UserUsageStats> GetUsageStatsAsync(Guid userId);
}

public class UsageTrackingService : IUsageTrackingService
{
    private readonly DramaLingDbContext _context;
    private readonly ILogger<UsageTrackingService> _logger;

    // 免費用戶限制
    private const int FREE_USER_ANALYSIS_LIMIT = 5;
    private const int FREE_USER_RESET_HOURS = 3;

    public UsageTrackingService(DramaLingDbContext context, ILogger<UsageTrackingService> logger)
    {
        _context = context;
        _logger = logger;
    }

    /// <summary>
    /// 檢查用戶使用限制
    /// </summary>
    public async Task<bool> CheckUsageLimitAsync(Guid userId, bool isPremium = false)
    {
        try
        {
            if (isPremium)
            {
                return true; // 付費用戶無限制
            }

            var resetTime = DateTime.UtcNow.AddHours(-FREE_USER_RESET_HOURS);
            var recentUsage = await _context.WordQueryUsageStats
                .Where(stats => stats.UserId == userId && stats.CreatedAt >= resetTime)
                .SumAsync(stats => stats.SentenceAnalysisCount + stats.LowValueWordClicks);

            var canUse = recentUsage < FREE_USER_ANALYSIS_LIMIT;

            _logger.LogInformation("Usage check for user {UserId}: {RecentUsage}/{Limit}, Can use: {CanUse}",
                userId, recentUsage, FREE_USER_ANALYSIS_LIMIT, canUse);

            return canUse;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error checking usage limit for user {UserId}", userId);
            return false; // 出錯時拒絕使用
        }
    }

    /// <summary>
    /// 記錄句子分析使用
    /// </summary>
    public async Task RecordSentenceAnalysisAsync(Guid userId)
    {
        try
        {
            var today = DateOnly.FromDateTime(DateTime.Today);
            var stats = await GetOrCreateTodayStatsAsync(userId, today);

            stats.SentenceAnalysisCount++;
            stats.TotalApiCalls++;
            stats.UpdatedAt = DateTime.UtcNow;

            await _context.SaveChangesAsync();

            _logger.LogInformation("Recorded sentence analysis for user {UserId}, total today: {Count}",
                userId, stats.SentenceAnalysisCount);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error recording sentence analysis for user {UserId}", userId);
        }
    }

    /// <summary>
    /// 記錄單字查詢使用
    /// </summary>
    public async Task RecordWordQueryAsync(Guid userId, bool wasHighValue)
    {
        try
        {
            var today = DateOnly.FromDateTime(DateTime.Today);
            var stats = await GetOrCreateTodayStatsAsync(userId, today);

            if (wasHighValue)
            {
                stats.HighValueWordClicks++;
            }
            else
            {
                stats.LowValueWordClicks++;
                stats.TotalApiCalls++; // 低價值詞彙需要API調用
            }

            stats.UniqueWordsQueried++; // 簡化：每次查詢都算一個獨特詞彙
            stats.UpdatedAt = DateTime.UtcNow;

            await _context.SaveChangesAsync();

            _logger.LogInformation("Recorded word query for user {UserId}, high value: {IsHighValue}",
                userId, wasHighValue);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error recording word query for user {UserId}", userId);
        }
    }

    /// <summary>
    /// 獲取用戶使用統計
    /// </summary>
    public async Task<UserUsageStats> GetUsageStatsAsync(Guid userId)
    {
        try
        {
            var today = DateOnly.FromDateTime(DateTime.Today);
            var resetTime = DateTime.UtcNow.AddHours(-FREE_USER_RESET_HOURS);

            // 今日統計
            var todayStats = await _context.WordQueryUsageStats
                .FirstOrDefaultAsync(stats => stats.UserId == userId && stats.Date == today)
                ?? new WordQueryUsageStats { UserId = userId, Date = today };

            // 最近3小時使用量（用於限制檢查）
            var recentUsage = await _context.WordQueryUsageStats
                .Where(stats => stats.UserId == userId && stats.CreatedAt >= resetTime)
                .SumAsync(stats => stats.SentenceAnalysisCount + stats.LowValueWordClicks);

            // 本週統計
            var weekStart = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek);
            var weekStats = await _context.WordQueryUsageStats
                .Where(stats => stats.UserId == userId && stats.Date >= DateOnly.FromDateTime(weekStart))
                .GroupBy(stats => 1)
                .Select(g => new
                {
                    TotalAnalysis = g.Sum(s => s.SentenceAnalysisCount),
                    TotalWordClicks = g.Sum(s => s.HighValueWordClicks + s.LowValueWordClicks),
                    TotalApiCalls = g.Sum(s => s.TotalApiCalls),
                    UniqueWords = g.Sum(s => s.UniqueWordsQueried)
                })
                .FirstOrDefaultAsync();

            return new UserUsageStats
            {
                UserId = userId,
                Today = new DailyUsageStats
                {
                    Date = today,
                    SentenceAnalysisCount = todayStats.SentenceAnalysisCount,
                    HighValueWordClicks = todayStats.HighValueWordClicks,
                    LowValueWordClicks = todayStats.LowValueWordClicks,
                    TotalApiCalls = todayStats.TotalApiCalls,
                    UniqueWordsQueried = todayStats.UniqueWordsQueried
                },
                RecentUsage = new UsageLimitInfo
                {
                    UsedInWindow = recentUsage,
                    WindowLimit = FREE_USER_ANALYSIS_LIMIT,
                    WindowHours = FREE_USER_RESET_HOURS,
                    ResetTime = DateTime.UtcNow.AddHours(FREE_USER_RESET_HOURS -
                        ((DateTime.UtcNow - resetTime).TotalHours % FREE_USER_RESET_HOURS))
                },
                ThisWeek = weekStats != null ? new WeeklyUsageStats
                {
                    StartDate = DateOnly.FromDateTime(weekStart),
                    EndDate = DateOnly.FromDateTime(weekStart.AddDays(6)),
                    TotalSentenceAnalysis = weekStats.TotalAnalysis,
                    TotalWordClicks = weekStats.TotalWordClicks,
                    TotalApiCalls = weekStats.TotalApiCalls,
                    UniqueWordsQueried = weekStats.UniqueWords
                } : new WeeklyUsageStats()
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting usage stats for user {UserId}", userId);
            return new UserUsageStats { UserId = userId };
        }
    }

    /// <summary>
    /// 獲取或創建今日統計記錄
    /// </summary>
    private async Task<WordQueryUsageStats> GetOrCreateTodayStatsAsync(Guid userId, DateOnly date)
    {
        var stats = await _context.WordQueryUsageStats
            .FirstOrDefaultAsync(s => s.UserId == userId && s.Date == date);

        if (stats == null)
        {
            stats = new WordQueryUsageStats
            {
                Id = Guid.NewGuid(),
                UserId = userId,
                Date = date,
                CreatedAt = DateTime.UtcNow,
                UpdatedAt = DateTime.UtcNow
            };

            _context.WordQueryUsageStats.Add(stats);
        }

        return stats;
    }
}

// 回應用的 DTO 類別
public class UserUsageStats
{
    public Guid UserId { get; set; }
    public DailyUsageStats Today { get; set; } = new();
    public UsageLimitInfo RecentUsage { get; set; } = new();
    public WeeklyUsageStats ThisWeek { get; set; } = new();
}

public class DailyUsageStats
{
    public DateOnly Date { get; set; }
    public int SentenceAnalysisCount { get; set; }
    public int HighValueWordClicks { get; set; }
    public int LowValueWordClicks { get; set; }
    public int TotalApiCalls { get; set; }
    public int UniqueWordsQueried { get; set; }
}

public class UsageLimitInfo
{
    public int UsedInWindow { get; set; }
    public int WindowLimit { get; set; }
    public int WindowHours { get; set; }
    public DateTime ResetTime { get; set; }
    public bool CanUse => UsedInWindow < WindowLimit;
    public int Remaining => Math.Max(0, WindowLimit - UsedInWindow);
}

public class WeeklyUsageStats
{
    public DateOnly StartDate { get; set; }
    public DateOnly EndDate { get; set; }
    public int TotalSentenceAnalysis { get; set; }
    public int TotalWordClicks { get; set; }
    public int TotalApiCalls { get; set; }
    public int UniqueWordsQueried { get; set; }
}