using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using DramaLing.Api.Data;
using DramaLing.Api.Models.Entities;
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;

namespace DramaLing.Api.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class CardSetsController : ControllerBase
{
    private readonly DramaLingDbContext _context;

    public CardSetsController(DramaLingDbContext context)
    {
        _context = context;
    }

    private Guid GetUserId()
    {
        var userIdString = User.FindFirst(ClaimTypes.NameIdentifier)?.Value ??
                          User.FindFirst("sub")?.Value;

        if (Guid.TryParse(userIdString, out var userId))
            return userId;

        throw new UnauthorizedAccessException("Invalid user ID");
    }

    private async Task EnsureDefaultCardSetAsync(Guid userId)
    {
        // 檢查用戶是否已有預設卡組
        var hasDefaultCardSet = await _context.CardSets
            .AnyAsync(cs => cs.UserId == userId && cs.IsDefault);

        if (!hasDefaultCardSet)
        {
            // 創建預設「未分類」卡組
            var defaultCardSet = new CardSet
            {
                Id = Guid.NewGuid(),
                UserId = userId,
                Name = "未分類",
                Description = "系統預設卡組，用於存放尚未分類的詞卡",
                Color = "bg-slate-700",
                IsDefault = true
            };

            _context.CardSets.Add(defaultCardSet);
            await _context.SaveChangesAsync();
        }
    }

    [HttpGet]
    public async Task<ActionResult> GetCardSets()
    {
        try
        {
            var userId = GetUserId();

            // 確保用戶有預設卡組
            await EnsureDefaultCardSetAsync(userId);

            var cardSets = await _context.CardSets
                .Where(cs => cs.UserId == userId)
                .OrderBy(cs => cs.IsDefault ? 0 : 1) // 預設卡組排在最前面
                .ThenByDescending(cs => cs.CreatedAt)
                .Select(cs => new
                {
                    cs.Id,
                    cs.Name,
                    cs.Description,
                    cs.Color,
                    cs.CardCount,
                    cs.CreatedAt,
                    cs.UpdatedAt,
                    cs.IsDefault,
                    // 計算進度 (簡化版)
                    Progress = cs.CardCount > 0 ?
                        _context.Flashcards
                            .Where(f => f.CardSetId == cs.Id)
                            .Average(f => (double?)f.MasteryLevel) ?? 0 : 0,
                    LastStudied = cs.UpdatedAt,
                    Tags = new string[] { } // Phase 1 簡化
                })
                .ToListAsync();

            return Ok(new
            {
                Success = true,
                Data = new { Sets = cardSets }
            });
        }
        catch (UnauthorizedAccessException)
        {
            return Unauthorized(new { Success = false, Error = "Unauthorized" });
        }
        catch (Exception ex)
        {
            return StatusCode(500, new
            {
                Success = false,
                Error = "Failed to fetch card sets",
                Timestamp = DateTime.UtcNow
            });
        }
    }

    [HttpPost]
    public async Task<ActionResult> CreateCardSet([FromBody] CreateCardSetRequest request)
    {
        try
        {
            var userId = GetUserId();

            if (string.IsNullOrWhiteSpace(request.Name))
                return BadRequest(new { Success = false, Error = "Name is required" });

            if (request.Name.Length > 255)
                return BadRequest(new { Success = false, Error = "Name must be less than 255 characters" });

            var cardSet = new CardSet
            {
                Id = Guid.NewGuid(),
                UserId = userId,
                Name = request.Name.Trim(),
                Description = request.Description?.Trim(),
                Color = request.Color ?? "bg-blue-500"
            };

            _context.CardSets.Add(cardSet);
            await _context.SaveChangesAsync();

            return Ok(new
            {
                Success = true,
                Data = cardSet,
                Message = "Card set created successfully"
            });
        }
        catch (UnauthorizedAccessException)
        {
            return Unauthorized(new { Success = false, Error = "Unauthorized" });
        }
        catch (Exception ex)
        {
            return StatusCode(500, new
            {
                Success = false,
                Error = "Failed to create card set",
                Timestamp = DateTime.UtcNow
            });
        }
    }

    [HttpPut("{id}")]
    public async Task<ActionResult> UpdateCardSet(Guid id, [FromBody] UpdateCardSetRequest request)
    {
        try
        {
            var userId = GetUserId();

            var cardSet = await _context.CardSets
                .FirstOrDefaultAsync(cs => cs.Id == id && cs.UserId == userId);

            if (cardSet == null)
                return NotFound(new { Success = false, Error = "Card set not found" });

            if (!string.IsNullOrEmpty(request.Name))
                cardSet.Name = request.Name.Trim();
            if (request.Description != null)
                cardSet.Description = request.Description?.Trim();
            if (!string.IsNullOrEmpty(request.Color))
                cardSet.Color = request.Color;

            cardSet.UpdatedAt = DateTime.UtcNow;
            await _context.SaveChangesAsync();

            return Ok(new
            {
                Success = true,
                Data = cardSet,
                Message = "Card set updated successfully"
            });
        }
        catch (UnauthorizedAccessException)
        {
            return Unauthorized(new { Success = false, Error = "Unauthorized" });
        }
        catch (Exception ex)
        {
            return StatusCode(500, new
            {
                Success = false,
                Error = "Failed to update card set",
                Timestamp = DateTime.UtcNow
            });
        }
    }

    [HttpDelete("{id}")]
    public async Task<ActionResult> DeleteCardSet(Guid id)
    {
        try
        {
            var userId = GetUserId();

            var cardSet = await _context.CardSets
                .Include(cs => cs.Flashcards)
                .FirstOrDefaultAsync(cs => cs.Id == id && cs.UserId == userId);

            if (cardSet == null)
                return NotFound(new { Success = false, Error = "Card set not found" });

            // 防止刪除預設卡組
            if (cardSet.IsDefault)
                return BadRequest(new { Success = false, Error = "Cannot delete default card set" });

            _context.CardSets.Remove(cardSet);
            await _context.SaveChangesAsync();

            return Ok(new
            {
                Success = true,
                Message = "Card set deleted successfully"
            });
        }
        catch (UnauthorizedAccessException)
        {
            return Unauthorized(new { Success = false, Error = "Unauthorized" });
        }
        catch (Exception ex)
        {
            return StatusCode(500, new
            {
                Success = false,
                Error = "Failed to delete card set",
                Timestamp = DateTime.UtcNow
            });
        }
    }

    [HttpPost("ensure-default")]
    public async Task<ActionResult> EnsureDefaultCardSet()
    {
        try
        {
            var userId = GetUserId();
            await EnsureDefaultCardSetAsync(userId);

            // 返回預設卡組
            var defaultCardSet = await _context.CardSets
                .FirstOrDefaultAsync(cs => cs.UserId == userId && cs.IsDefault);

            if (defaultCardSet == null)
                return StatusCode(500, new { Success = false, Error = "Failed to create default card set" });

            return Ok(new
            {
                Success = true,
                Data = defaultCardSet,
                Message = "Default card set ensured"
            });
        }
        catch (UnauthorizedAccessException)
        {
            return Unauthorized(new { Success = false, Error = "Unauthorized" });
        }
        catch (Exception ex)
        {
            return StatusCode(500, new
            {
                Success = false,
                Error = "Failed to ensure default card set",
                Timestamp = DateTime.UtcNow
            });
        }
    }
}

// Request DTOs
public class CreateCardSetRequest
{
    public string Name { get; set; } = string.Empty;
    public string? Description { get; set; }
    public string? Color { get; set; }
}

public class UpdateCardSetRequest
{
    public string? Name { get; set; }
    public string? Description { get; set; }
    public string? Color { get; set; }
}