using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using BookmarkApi.Core.Interfaces;
using BookmarkApi.Shared.DTOs;
using BookmarkApi.Shared.DTOs.Bookmark;
using BookmarkApi.Shared.Enums;

namespace BookmarkApi.Controllers;

/// <summary>
/// 书签控制器
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class BookmarksController : ControllerBase
{
    private readonly IBookmarkService _bookmarkService;
    private readonly IDeviceService _deviceService;

    public BookmarksController(IBookmarkService bookmarkService, IDeviceService deviceService)
    {
        _bookmarkService = bookmarkService;
        _deviceService = deviceService;
    }

    /// <summary>
    /// 获取书签列表
    /// </summary>
    [HttpGet]
    [ProducesResponseType(typeof(ApiResponse<List<BookmarkDto>>), StatusCodes.Status200OK)]
    public async Task<ActionResult<ApiResponse<List<BookmarkDto>>>> GetBookmarks([FromQuery] string? tag = null)
    {
        var (userId, deviceId, isAdmin) = await GetCurrentContext();
        if (userId == null || deviceId == null)
        {
            return BadRequest(ApiResponse<List<BookmarkDto>>.Fail("无效的用户或设备"));
        }

        var bookmarks = await _bookmarkService.GetUserBookmarksAsync(userId.Value, deviceId.Value, isAdmin, tag);

        return Ok(ApiResponse<List<BookmarkDto>>.Ok(bookmarks));
    }

    /// <summary>
    /// 搜索书签
    /// </summary>
    [HttpGet("search")]
    [ProducesResponseType(typeof(ApiResponse<List<BookmarkDto>>), StatusCodes.Status200OK)]
    public async Task<ActionResult<ApiResponse<List<BookmarkDto>>>> SearchBookmarks([FromQuery] string keyword)
    {
        if (string.IsNullOrWhiteSpace(keyword))
        {
            return BadRequest(ApiResponse<List<BookmarkDto>>.Fail("搜索关键词不能为空"));
        }

        var (userId, deviceId, isAdmin) = await GetCurrentContext();
        if (userId == null || deviceId == null)
        {
            return BadRequest(ApiResponse<List<BookmarkDto>>.Fail("无效的用户或设备"));
        }

        var bookmarks = await _bookmarkService.SearchBookmarksAsync(userId.Value, deviceId.Value, isAdmin, keyword);

        return Ok(ApiResponse<List<BookmarkDto>>.Ok(bookmarks));
    }

    /// <summary>
    /// 获取书签详情
    /// </summary>
    [HttpGet("{id:guid}")]
    [ProducesResponseType(typeof(ApiResponse<BookmarkDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<ApiResponse<BookmarkDto>>> GetBookmark(Guid id)
    {
        var (userId, deviceId, isAdmin) = await GetCurrentContext();
        if (userId == null || deviceId == null)
        {
            return BadRequest(ApiResponse<BookmarkDto>.Fail("无效的用户或设备"));
        }

        var bookmark = await _bookmarkService.GetBookmarkAsync(id, userId.Value, deviceId.Value, isAdmin);

        if (bookmark == null)
        {
            return NotFound(ApiResponse<BookmarkDto>.Fail("书签不存在或无权访问"));
        }

        return Ok(ApiResponse<BookmarkDto>.Ok(bookmark));
    }

    /// <summary>
    /// 创建书签
    /// </summary>
    [HttpPost]
    [ProducesResponseType(typeof(ApiResponse<BookmarkDto>), StatusCodes.Status201Created)]
    public async Task<ActionResult<ApiResponse<BookmarkDto>>> CreateBookmark([FromBody] CreateBookmarkRequest request)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return BadRequest(ApiResponse<BookmarkDto>.Fail("无效的用户"));
        }

        var bookmark = await _bookmarkService.CreateBookmarkAsync(userId.Value, request);

        return CreatedAtAction(nameof(GetBookmark), new { id = bookmark.Id }, ApiResponse<BookmarkDto>.Ok(bookmark));
    }

    /// <summary>
    /// 更新书签
    /// </summary>
    [HttpPut("{id:guid}")]
    [ProducesResponseType(typeof(ApiResponse<BookmarkDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<ApiResponse<BookmarkDto>>> UpdateBookmark(Guid id, [FromBody] UpdateBookmarkRequest request)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return BadRequest(ApiResponse<BookmarkDto>.Fail("无效的用户"));
        }

        var bookmark = await _bookmarkService.UpdateBookmarkAsync(id, userId.Value, request);

        if (bookmark == null)
        {
            return NotFound(ApiResponse<BookmarkDto>.Fail("书签不存在"));
        }

        return Ok(ApiResponse<BookmarkDto>.Ok(bookmark));
    }

    /// <summary>
    /// 删除书签
    /// </summary>
    [HttpDelete("{id:guid}")]
    [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
    public async Task<ActionResult<ApiResponse>> DeleteBookmark(Guid id)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return BadRequest(ApiResponse.Fail("无效的用户"));
        }

        var success = await _bookmarkService.DeleteBookmarkAsync(id, userId.Value);

        if (!success)
        {
            return NotFound(ApiResponse.Fail("书签不存在"));
        }

        return Ok(ApiResponse.Ok("书签已删除"));
    }

    /// <summary>
    /// 批量删除书签
    /// </summary>
    [HttpPost("batch/delete")]
    [ProducesResponseType(typeof(ApiResponse<int>), StatusCodes.Status200OK)]
    public async Task<ActionResult<ApiResponse<int>>> BatchDeleteBookmarks([FromBody] Guid[] bookmarkIds)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return BadRequest(ApiResponse<int>.Fail("无效的用户"));
        }

        var count = await _bookmarkService.BatchDeleteBookmarksAsync(userId.Value, bookmarkIds);

        return Ok(ApiResponse<int>.Ok(count, $"已删除 {count} 个书签"));
    }

    /// <summary>
    /// 设置书签可见性
    /// </summary>
    [HttpPut("{id:guid}/visibility")]
    [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
    public async Task<ActionResult<ApiResponse>> SetVisibility(Guid id, [FromBody] SetVisibilityRequest request)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return BadRequest(ApiResponse.Fail("无效的用户"));
        }

        var success = await _bookmarkService.SetVisibilityAsync(id, userId.Value, request.Visibility, request.AllowedDevices);

        if (!success)
        {
            return NotFound(ApiResponse.Fail("书签不存在"));
        }

        return Ok(ApiResponse.Ok("可见性已更新"));
    }

    /// <summary>
    /// 记录访问
    /// </summary>
    [HttpPost("{id:guid}/visit")]
    [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
    public async Task<ActionResult<ApiResponse>> RecordVisit(Guid id)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return BadRequest(ApiResponse.Fail("无效的用户"));
        }

        var success = await _bookmarkService.RecordVisitAsync(id, userId.Value);

        if (!success)
        {
            return NotFound(ApiResponse.Fail("书签不存在"));
        }

        return Ok(ApiResponse.Ok());
    }

    /// <summary>
    /// 更新排序
    /// </summary>
    [HttpPut("{id:guid}/order")]
    [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
    public async Task<ActionResult<ApiResponse>> UpdateOrder(Guid id, [FromBody] UpdateOrderRequest request)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return BadRequest(ApiResponse.Fail("无效的用户"));
        }

        var success = await _bookmarkService.UpdateOrderAsync(id, userId.Value, request.Order);

        if (!success)
        {
            return NotFound(ApiResponse.Fail("书签不存在"));
        }

        return Ok(ApiResponse.Ok());
    }

    /// <summary>
    /// 检查 URL 是否已存在
    /// </summary>
    [HttpGet("check-url")]
    [ProducesResponseType(typeof(ApiResponse<bool>), StatusCodes.Status200OK)]
    public async Task<ActionResult<ApiResponse<bool>>> CheckUrl([FromQuery] string url)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return BadRequest(ApiResponse<bool>.Fail("无效的用户"));
        }

        var exists = await _bookmarkService.UrlExistsAsync(userId.Value, url);

        return Ok(ApiResponse<bool>.Ok(exists));
    }

    /// <summary>
    /// 导入书签
    /// </summary>
    [HttpPost("import")]
    [ProducesResponseType(typeof(ApiResponse<int>), StatusCodes.Status200OK)]
    public async Task<ActionResult<ApiResponse<int>>> ImportBookmarks([FromBody] List<CreateBookmarkRequest> bookmarks)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return BadRequest(ApiResponse<int>.Fail("无效的用户"));
        }

        var count = await _bookmarkService.ImportBookmarksAsync(userId.Value, bookmarks);

        return Ok(ApiResponse<int>.Ok(count, $"成功导入 {count} 个书签"));
    }

    /// <summary>
    /// 导出书签
    /// </summary>
    [HttpGet("export")]
    [ProducesResponseType(typeof(ApiResponse<List<BookmarkDto>>), StatusCodes.Status200OK)]
    public async Task<ActionResult<ApiResponse<List<BookmarkDto>>>> ExportBookmarks()
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return BadRequest(ApiResponse<List<BookmarkDto>>.Fail("无效的用户"));
        }

        var bookmarks = await _bookmarkService.ExportBookmarksAsync(userId.Value);

        return Ok(ApiResponse<List<BookmarkDto>>.Ok(bookmarks));
    }

    private Guid? GetCurrentUserId()
    {
        var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        return Guid.TryParse(userIdClaim, out var userId) ? userId : null;
    }

    private Guid? GetCurrentDeviceId()
    {
        var deviceIdClaim = User.FindFirst("device_id")?.Value;
        return Guid.TryParse(deviceIdClaim, out var deviceId) ? deviceId : null;
    }

    private async Task<(Guid? userId, Guid? deviceId, bool isAdmin)> GetCurrentContext()
    {
        var userId = GetCurrentUserId();
        var deviceId = GetCurrentDeviceId();

        if (userId == null || deviceId == null)
        {
            return (null, null, false);
        }

        var isAdmin = await _deviceService.IsAdminDeviceAsync(deviceId.Value);

        return (userId, deviceId, isAdmin);
    }
}

/// <summary>
/// 设置可见性请求
/// </summary>
public class SetVisibilityRequest
{
    /// <summary>
    /// 可见性类型
    /// </summary>
    public VisibilityType Visibility { get; set; }

    /// <summary>
    /// 允许的设备ID列表
    /// </summary>
    public Guid[]? AllowedDevices { get; set; }
}

/// <summary>
/// 更新排序请求
/// </summary>
public class UpdateOrderRequest
{
    /// <summary>
    /// 新的排序值
    /// </summary>
    public long Order { get; set; }
}

