using System.Security.Claims;
using HoneyBox.Core.Interfaces;
using HoneyBox.Model.Base;
using HoneyBox.Model.Models.UserCoupon;
using HoneyBox.Model.Models.Coupon;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace HoneyBox.Api.Controllers;

/// <summary>
/// 优惠券控制器 - 处理优惠券相关功能
/// </summary>
/// <remarks>
/// 提供优惠券列表查询、详情查询、领取、分享、合成等功能
/// </remarks>
[ApiController]
[Route("api")]
public class CouponController : ControllerBase
{
    private readonly ICouponService _couponService;
    private readonly ILogger<CouponController> _logger;

    public CouponController(
        ICouponService couponService,
        ILogger<CouponController> logger)
    {
        _couponService = couponService;
        _logger = logger;
    }

    /// <summary>
    /// 获取优惠券列表
    /// </summary>
    /// <remarks>
    /// POST /api/coupon_list
    /// 
    /// 获取当前用户的优惠券列表，支持按状态筛选
    /// Requirements: 3.1-3.4
    /// </remarks>
    /// <param name="request">优惠券列表请求参数</param>
    /// <returns>优惠券列表数据</returns>
    [HttpPost("coupon_list")]
    [Authorize]
    [ProducesResponseType(typeof(ApiResponse<UserCouponListResponse>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<UserCouponListResponse>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<UserCouponListResponse>> GetCouponList([FromBody] UserCouponListRequest? request)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse<UserCouponListResponse>.Unauthorized();
        }

        try
        {
            var status = request?.Status ?? 1;
            var page = request?.Page ?? 1;
            var limit = request?.Limit ?? 15;

            if (page < 1) page = 1;
            if (limit < 1) limit = 15;

            var result = await _couponService.GetCouponListAsync(userId.Value, status, page, limit);
            return ApiResponse<UserCouponListResponse>.Success(result);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get coupon list: UserId={UserId}", userId);
            return ApiResponse<UserCouponListResponse>.Fail("获取优惠券列表失败");
        }
    }


    /// <summary>
    /// 获取优惠券详情
    /// POST /api/coupon_detail
    /// Requirements: 4.1-4.4
    /// </summary>
    [HttpPost("coupon_detail")]
    [Authorize]
    public async Task<ApiResponse<CouponDetailResponse>> GetCouponDetail([FromBody] CouponDetailRequest? request)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse<CouponDetailResponse>.Unauthorized();
        }

        try
        {
            if (request == null || request.Id <= 0)
            {
                return ApiResponse<CouponDetailResponse>.Fail("缺少必要参数");
            }

            var result = await _couponService.GetCouponDetailAsync(userId.Value, request.Id);
            return ApiResponse<CouponDetailResponse>.Success(result);
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning("Get coupon detail failed: UserId={UserId}, Error={Error}", userId, ex.Message);
            return ApiResponse<CouponDetailResponse>.Fail(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get coupon detail: UserId={UserId}", userId);
            return ApiResponse<CouponDetailResponse>.Fail("获取优惠券详情失败");
        }
    }

    /// <summary>
    /// 分享优惠券
    /// POST /api/coupon_share
    /// Requirements: 5.1-5.3
    /// </summary>
    [HttpPost("coupon_share")]
    [Authorize]
    public async Task<ApiResponse> ShareCoupon([FromBody] ShareCouponRequest? request)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse.Unauthorized();
        }

        try
        {
            if (request == null || request.Id <= 0)
            {
                return ApiResponse.Fail("缺少必要参数");
            }

            await _couponService.ShareCouponAsync(userId.Value, request.Id);
            return ApiResponse.Success("分享成功");
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning("Share coupon failed: UserId={UserId}, Error={Error}", userId, ex.Message);
            return ApiResponse.Fail(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to share coupon: UserId={UserId}", userId);
            return ApiResponse.Fail("分享优惠券失败");
        }
    }


    /// <summary>
    /// 领取优惠券
    /// </summary>
    /// <remarks>
    /// POST /api/coupon_ling
    /// 
    /// 领取指定的优惠券
    /// Requirements: 6.1-6.7
    /// </remarks>
    /// <param name="request">领取优惠券请求参数</param>
    /// <returns>领取结果</returns>
    [HttpPost("coupon_ling")]
    [Authorize]
    [ProducesResponseType(typeof(ApiResponse<ClaimCouponResponse>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<ClaimCouponResponse>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<ClaimCouponResponse>> ClaimCoupon([FromBody] ClaimCouponRequest? request)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse<ClaimCouponResponse>.Unauthorized();
        }

        try
        {
            if (request == null || request.Id <= 0)
            {
                return ApiResponse<ClaimCouponResponse>.Fail("缺少必要参数");
            }

            var result = await _couponService.ClaimCouponAsync(userId.Value, request.Id);
            return ApiResponse<ClaimCouponResponse>.Success(result, "领取成功");
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning("Claim coupon failed: UserId={UserId}, Error={Error}", userId, ex.Message);
            // 特殊错误码处理
            if (ex.Message == "请勿开启自己的劵" || 
                ex.Message == "你已经领取过了" || 
                ex.Message == "来晚了, 已经被人领完了")
            {
                return ApiResponse<ClaimCouponResponse>.Fail(ex.Message, 2222);
            }
            return ApiResponse<ClaimCouponResponse>.Fail(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to claim coupon: UserId={UserId}", userId);
            return ApiResponse<ClaimCouponResponse>.Fail("领取优惠券失败");
        }
    }

    /// <summary>
    /// 计算优惠券合成
    /// POST /api/coupon_ji_suan
    /// Requirements: 7.1-7.4
    /// </summary>
    [HttpPost("coupon_ji_suan")]
    [Authorize]
    public async Task<ApiResponse<SynthesisCalculateResponse>> CalculateSynthesis([FromBody] SynthesisCalculateRequest? request)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse<SynthesisCalculateResponse>.Unauthorized();
        }

        try
        {
            if (request == null || string.IsNullOrEmpty(request.CouponIds))
            {
                return ApiResponse<SynthesisCalculateResponse>.Fail("缺少必要参数");
            }

            var result = await _couponService.CalculateSynthesisAsync(userId.Value, request.CouponIds);
            return ApiResponse<SynthesisCalculateResponse>.Success(result);
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning("Calculate synthesis failed: UserId={UserId}, Error={Error}", userId, ex.Message);
            return ApiResponse<SynthesisCalculateResponse>.Fail(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to calculate synthesis: UserId={UserId}", userId);
            return ApiResponse<SynthesisCalculateResponse>.Fail("计算合成失败");
        }
    }


    /// <summary>
    /// 执行优惠券合成
    /// POST /api/coupon_synthesis
    /// Requirements: 7.5
    /// </summary>
    [HttpPost("coupon_synthesis")]
    [Authorize]
    public async Task<ApiResponse> SynthesisCoupons([FromBody] SynthesisCouponsRequest? request)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse.Unauthorized();
        }

        try
        {
            if (request == null || string.IsNullOrEmpty(request.CouponIds))
            {
                return ApiResponse.Fail("缺少必要参数");
            }

            await _couponService.SynthesisCouponsAsync(userId.Value, request.CouponIds);
            return ApiResponse.Success("合成成功");
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning("Synthesis coupons failed: UserId={UserId}, Error={Error}", userId, ex.Message);
            return ApiResponse.Fail(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to synthesis coupons: UserId={UserId}", userId);
            return ApiResponse.Fail("合成优惠券失败");
        }
    }

    /// <summary>
    /// 批量领取优惠券
    /// </summary>
    /// <remarks>
    /// POST /api/receive
    /// 
    /// 批量领取指定的优惠券
    /// Requirements: 7.1
    /// </remarks>
    /// <param name="request">批量领取请求参数</param>
    /// <returns>领取结果</returns>
    [HttpPost("receive")]
    [Authorize]
    [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse> BatchReceiveCoupons([FromBody] BatchReceiveCouponRequest? request)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse.Unauthorized();
        }

        try
        {
            if (request == null || string.IsNullOrEmpty(request.CouponId))
            {
                return ApiResponse.Fail("缺少必要参数");
            }

            await _couponService.BatchReceiveCouponsAsync(userId.Value, request.CouponId);
            return ApiResponse.Success("领取成功");
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning("Batch receive coupons failed: UserId={UserId}, Error={Error}", userId, ex.Message);
            return ApiResponse.Fail(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to batch receive coupons: UserId={UserId}", userId);
            return ApiResponse.Fail("购买失败,请刷新重试");
        }
    }

    /// <summary>
    /// 获取待领取优惠券数量
    /// </summary>
    /// <remarks>
    /// GET /api/coupon_pending_count
    /// 
    /// 获取用户待领取的优惠券数量，用于首页入口显示/隐藏
    /// Requirements: 1.1.0 - 三、待领取优惠券固定入口
    /// </remarks>
    /// <returns>待领取优惠券数量</returns>
    [HttpGet("coupon_pending_count")]
    [Authorize]
    [ProducesResponseType(typeof(ApiResponse<PendingCouponCountResponse>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<PendingCouponCountResponse>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<PendingCouponCountResponse>> GetPendingCouponCount()
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse<PendingCouponCountResponse>.Unauthorized();
        }

        try
        {
            var count = await _couponService.GetPendingCouponCountAsync(userId.Value);
            return ApiResponse<PendingCouponCountResponse>.Success(new PendingCouponCountResponse { Count = count });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get pending coupon count: UserId={UserId}", userId);
            return ApiResponse<PendingCouponCountResponse>.Fail("获取待领取优惠券数量失败");
        }
    }

    /// <summary>
    /// 获取可领取的优惠券列表
    /// </summary>
    /// <remarks>
    /// GET /api/coupon
    /// 
    /// 获取首页弹出的可领取优惠券列表
    /// Requirements: 7.2
    /// </remarks>
    /// <returns>可领取优惠券列表</returns>
    [HttpGet("coupon")]
    [Authorize]
    [ProducesResponseType(typeof(ApiResponse<AvailableCouponListResponse>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<AvailableCouponListResponse>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<AvailableCouponListResponse>> GetAvailableCoupons()
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse<AvailableCouponListResponse>.Unauthorized();
        }

        try
        {
            var result = await _couponService.GetAvailableCouponsAsync(userId.Value);
            return ApiResponse<AvailableCouponListResponse>.Success(result);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get available coupons: UserId={UserId}", userId);
            return ApiResponse<AvailableCouponListResponse>.Fail("获取优惠券列表失败");
        }
    }

    /// <summary>
    /// 获取可使用的优惠券列表
    /// </summary>
    /// <remarks>
    /// GET /api/used
    /// 
    /// 获取用户可使用的优惠券列表，支持从个人中心或计算金额页面进入
    /// Requirements: 7.3
    /// </remarks>
    /// <param name="total_price">订单总价（从计算金额进入时必填）</param>
    /// <param name="type">类型: 1-从个人中心进 2-从计算金额进</param>
    /// <param name="type1">子类型: 1-可用 2-不可用</param>
    /// <param name="status">状态</param>
    /// <param name="page">页码</param>
    /// <param name="state">优惠券子类型</param>
    /// <returns>可使用优惠券列表</returns>
    [HttpGet("used")]
    [Authorize]
    [ProducesResponseType(typeof(ApiResponse<UsableCouponListResponse>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<UsableCouponListResponse>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<UsableCouponListResponse>> GetUsableCoupons(
        [FromQuery] decimal? total_price,
        [FromQuery] int type = 1,
        [FromQuery] int type1 = 1,
        [FromQuery] int status = 0,
        [FromQuery] int page = 1,
        [FromQuery] int? state = null)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse<UsableCouponListResponse>.Unauthorized();
        }

        try
        {
            var request = new UsableCouponListRequest
            {
                TotalPrice = total_price,
                Type = type,
                Type1 = type1,
                Status = status,
                Page = page,
                State = state
            };

            var result = await _couponService.GetUsableCouponsAsync(userId.Value, request);
            return ApiResponse<UsableCouponListResponse>.Success(result);
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning("Get usable coupons failed: UserId={UserId}, Error={Error}", userId, ex.Message);
            return ApiResponse<UsableCouponListResponse>.Fail(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get usable coupons: UserId={UserId}", userId);
            return ApiResponse<UsableCouponListResponse>.Fail("获取优惠券列表失败");
        }
    }

    /// <summary>
    /// 获取领券中心优惠券列表
    /// </summary>
    /// <remarks>
    /// POST /api/t_coupon_list
    /// 
    /// 获取领券中心的优惠券列表（潮券明细）
    /// Requirements: 7.4
    /// </remarks>
    /// <param name="request">请求参数</param>
    /// <returns>领券中心优惠券列表</returns>
    [HttpPost("t_coupon_list")]
    [Authorize]
    [ProducesResponseType(typeof(ApiResponse<UserCouponListResponse>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<UserCouponListResponse>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<UserCouponListResponse>> GetCouponCenterList([FromBody] CouponCenterListRequest? request)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse<UserCouponListResponse>.Unauthorized();
        }

        try
        {
            request ??= new CouponCenterListRequest();
            var result = await _couponService.GetCouponCenterListAsync(userId.Value, request);
            return ApiResponse<UserCouponListResponse>.Success(result);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to get coupon center list: UserId={UserId}", userId);
            return ApiResponse<UserCouponListResponse>.Fail("获取优惠券列表失败");
        }
    }

    /// <summary>
    /// 领取领券中心优惠券
    /// </summary>
    /// <remarks>
    /// POST /api/t_coupon_ling
    /// 
    /// 领取领券中心的优惠券（潮券领取）
    /// Requirements: 7.5
    /// </remarks>
    /// <param name="request">领取请求参数</param>
    /// <returns>领取结果</returns>
    [HttpPost("t_coupon_ling")]
    [Authorize]
    [ProducesResponseType(typeof(ApiResponse<ClaimCouponResponse>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<ClaimCouponResponse>), StatusCodes.Status401Unauthorized)]
    public async Task<ApiResponse<ClaimCouponResponse>> ReceiveCouponCenter([FromBody] CouponCenterReceiveRequest? request)
    {
        var userId = GetCurrentUserId();
        if (userId == null)
        {
            return ApiResponse<ClaimCouponResponse>.Unauthorized();
        }

        try
        {
            if (request == null || request.CouponId <= 0)
            {
                return ApiResponse<ClaimCouponResponse>.Fail("缺少必要参数");
            }

            var result = await _couponService.ReceiveCouponCenterAsync(userId.Value, request.CouponId);
            return ApiResponse<ClaimCouponResponse>.Success(result, "领取成功");
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning("Receive coupon center failed: UserId={UserId}, Error={Error}", userId, ex.Message);
            // 特殊错误码处理
            if (ex.Message == "请勿开启自己的劵" || 
                ex.Message == "你已经领取过了" || 
                ex.Message == "来晚了, 已经被人领完了")
            {
                return ApiResponse<ClaimCouponResponse>.Fail(ex.Message, 2222);
            }
            return ApiResponse<ClaimCouponResponse>.Fail(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to receive coupon center: UserId={UserId}", userId);
            return ApiResponse<ClaimCouponResponse>.Fail("领取优惠券失败");
        }
    }

    #region Private Helper Methods

    /// <summary>
    /// 获取当前登录用户ID
    /// </summary>
    private int? GetCurrentUserId()
    {
        var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier);
        if (userIdClaim == null || !int.TryParse(userIdClaim.Value, out var userId))
        {
            return null;
        }
        return userId;
    }

    #endregion
}
