using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using DramaLing.Api.Models.DTOs;
using DramaLing.Api.Services.AI;
using DramaLing.Api.Services.Caching;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;

namespace DramaLing.Api.Controllers;

/// <summary>
/// 優化後的 AI 控制器，使用新的架構和快取策略
/// </summary>
[ApiController]
[Route("api/v2/ai")]
public class OptimizedAIController : ControllerBase
{
    private readonly IAIProviderManager _aiProviderManager;
    private readonly ICacheService _cacheService;
    private readonly ILogger<OptimizedAIController> _logger;

    public OptimizedAIController(
        IAIProviderManager aiProviderManager,
        ICacheService cacheService,
        ILogger<OptimizedAIController> logger)
    {
        _aiProviderManager = aiProviderManager ?? throw new ArgumentNullException(nameof(aiProviderManager));
        _cacheService = cacheService ?? throw new ArgumentNullException(nameof(cacheService));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    /// <summary>
    /// 智能分析英文句子 (優化版本)
    /// </summary>
    /// <param name="request">分析請求</param>
    /// <returns>分析結果</returns>
    [HttpPost("analyze-sentence")]
    [AllowAnonymous]
    public async Task<ActionResult<SentenceAnalysisResponse>> AnalyzeSentenceOptimized(
        [FromBody] SentenceAnalysisRequest request)
    {
        var requestId = Guid.NewGuid().ToString();
        var stopwatch = Stopwatch.StartNew();

        try
        {
            _logger.LogInformation("Processing optimized sentence analysis request {RequestId}", requestId);

            // 輸入驗證
            if (!ModelState.IsValid)
            {
                return BadRequest(CreateErrorResponse("INVALID_INPUT", "輸入格式錯誤", requestId));
            }

            // 生成快取鍵
            var cacheKey = GenerateCacheKey(request.InputText, request.Options);

            // 嘗試從快取取得結果
            var cachedResult = await _cacheService.GetAsync<SentenceAnalysisData>(cacheKey);
            if (cachedResult != null)
            {
                stopwatch.Stop();
                _logger.LogInformation("Cache hit for request {RequestId} in {ElapsedMs}ms",
                    requestId, stopwatch.ElapsedMilliseconds);

                return Ok(new SentenceAnalysisResponse
                {
                    Success = true,
                    ProcessingTime = stopwatch.Elapsed.TotalSeconds,
                    Data = cachedResult,
                    FromCache = true
                });
            }

            // 快取未命中，執行 AI 分析
            _logger.LogInformation("Cache miss, calling AI service for request {RequestId}", requestId);

            var options = request.Options ?? new AnalysisOptions();
            var analysisData = await _aiProviderManager.AnalyzeSentenceAsync(
                request.InputText,
                options,
                ProviderSelectionStrategy.Performance);

            // 更新 metadata
            analysisData.Metadata.ProcessingDate = DateTime.UtcNow;

            // 將結果存入快取
            await _cacheService.SetAsync(cacheKey, analysisData, TimeSpan.FromHours(2));

            stopwatch.Stop();

            _logger.LogInformation("Sentence analysis completed for request {RequestId} in {ElapsedMs}ms",
                requestId, stopwatch.ElapsedMilliseconds);

            return Ok(new SentenceAnalysisResponse
            {
                Success = true,
                ProcessingTime = stopwatch.Elapsed.TotalSeconds,
                Data = analysisData,
                FromCache = false
            });
        }
        catch (ArgumentException ex)
        {
            _logger.LogWarning(ex, "Invalid input for request {RequestId}", requestId);
            return BadRequest(CreateErrorResponse("INVALID_INPUT", ex.Message, requestId));
        }
        catch (InvalidOperationException ex) when (ex.Message.Contains("AI"))
        {
            _logger.LogError(ex, "AI service error for request {RequestId}", requestId);
            return StatusCode(502, CreateErrorResponse("AI_SERVICE_ERROR", "AI服務暫時不可用", requestId));
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Unexpected error processing request {RequestId}", requestId);
            return StatusCode(500, CreateErrorResponse("INTERNAL_ERROR", "伺服器內部錯誤", requestId));
        }
    }

    /// <summary>
    /// 取得 AI 服務健康狀態
    /// </summary>
    [HttpGet("health")]
    [AllowAnonymous]
    public async Task<ActionResult> GetAIHealth()
    {
        try
        {
            var healthReport = await _aiProviderManager.CheckAllProvidersHealthAsync();

            var response = new
            {
                Status = healthReport.HealthyProviders > 0 ? "Healthy" : "Unhealthy",
                TotalProviders = healthReport.TotalProviders,
                HealthyProviders = healthReport.HealthyProviders,
                CheckedAt = healthReport.CheckedAt,
                Providers = healthReport.ProviderHealthInfos.Select(p => new
                {
                    Name = p.ProviderName,
                    IsHealthy = p.IsHealthy,
                    ResponseTimeMs = p.ResponseTimeMs,
                    ErrorMessage = p.ErrorMessage,
                    Stats = new
                    {
                        TotalRequests = p.Stats.TotalRequests,
                        SuccessRate = p.Stats.SuccessRate,
                        AverageResponseTimeMs = p.Stats.AverageResponseTimeMs
                    }
                })
            };

            return Ok(response);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error checking AI service health");
            return StatusCode(500, new { Status = "Error", Message = "無法檢查AI服務狀態" });
        }
    }

    /// <summary>
    /// 取得快取統計資訊
    /// </summary>
    [HttpGet("cache-stats")]
    [AllowAnonymous]
    public async Task<ActionResult> GetCacheStats()
    {
        try
        {
            var stats = await _cacheService.GetStatsAsync();
            return Ok(new
            {
                Success = true,
                Data = new
                {
                    TotalKeys = stats.TotalKeys,
                    HitRate = stats.HitRate,
                    TotalRequests = stats.TotalRequests,
                    HitCount = stats.HitCount,
                    MissCount = stats.MissCount,
                    LastUpdated = stats.LastUpdated
                }
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting cache stats");
            return StatusCode(500, new { Success = false, Error = "無法取得快取統計資訊" });
        }
    }

    #region 私有方法

    private string GenerateCacheKey(string inputText, AnalysisOptions? options)
    {
        // 使用輸入文本和選項組合生成唯一快取鍵
        var optionsString = options != null
            ? $"{options.IncludeGrammarCheck}_{options.IncludeVocabularyAnalysis}_{options.IncludeIdiomDetection}"
            : "default";

        var combinedInput = $"{inputText}_{optionsString}";

        // 使用 SHA256 生成穩定的快取鍵
        using var sha256 = SHA256.Create();
        var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(combinedInput));
        var hash = Convert.ToHexString(hashBytes)[..16]; // 取前16個字符

        return $"analysis:{hash}";
    }

    private object CreateErrorResponse(string code, string message, string requestId)
    {
        return new
        {
            Success = false,
            Error = new
            {
                Code = code,
                Message = message,
                Suggestions = GetSuggestionsForError(code)
            },
            RequestId = requestId,
            Timestamp = DateTime.UtcNow
        };
    }

    private List<string> GetSuggestionsForError(string errorCode)
    {
        return errorCode switch
        {
            "INVALID_INPUT" => new List<string> { "請檢查輸入格式", "確保文本長度在限制內" },
            "AI_SERVICE_ERROR" => new List<string> { "請稍後重試", "如果問題持續，請聯繫客服" },
            "RATE_LIMIT_EXCEEDED" => new List<string> { "請降低請求頻率", "稍後再試" },
            _ => new List<string> { "請稍後重試" }
        };
    }

    #endregion
}