using FluentValidation;
using Microsoft.AspNetCore.Mvc;
using Meezi.API.Models.Crm;
using Meezi.API.Services;
using Meezi.Core.Interfaces;
using Meezi.Shared;

namespace Meezi.API.Controllers;

[Route("api/cafes/{cafeId}/sms")]
public class SmsController : CafeApiControllerBase
{
    private readonly ISmsMarketingService _smsMarketingService;
    private readonly ISmsService _smsService;
    private readonly IValidator<SendSmsCampaignRequest> _campaignValidator;

    public SmsController(
        ISmsMarketingService smsMarketingService,
        ISmsService smsService,
        IValidator<SendSmsCampaignRequest> campaignValidator)
    {
        _smsMarketingService = smsMarketingService;
        _smsService = smsService;
        _campaignValidator = campaignValidator;
    }

    [HttpGet("balance")]
    public async Task<IActionResult> GetBalance(string cafeId, ITenantContext tenant, CancellationToken cancellationToken)
    {
        if (EnsureCafeAccess(cafeId, tenant) is { } denied) return denied;

        var info = await _smsService.GetAccountInfoAsync(cancellationToken);
        var dto = info is not null
            ? new SmsBalanceDto(info.RemainCredit, info.AccountType, true)
            : new SmsBalanceDto(0, "master", false);

        return Ok(new ApiResponse<SmsBalanceDto>(true, dto));
    }

    [HttpGet("usage")]
    public async Task<IActionResult> GetUsage(string cafeId, ITenantContext tenant, CancellationToken cancellationToken)
    {
        if (EnsureCafeAccess(cafeId, tenant) is { } denied) return denied;
        if (tenant.PlanTier is null)
            return BadRequest(new ApiResponse<object>(false, null, new ApiError("INVALID", "Plan tier missing.")));

        var data = await _smsMarketingService.GetUsageAsync(cafeId, tenant.PlanTier.Value, cancellationToken);
        return Ok(new ApiResponse<SmsUsageDto>(true, data));
    }

    [HttpPost("campaign")]
    public async Task<IActionResult> SendCampaign(
        string cafeId,
        [FromBody] SendSmsCampaignRequest request,
        ITenantContext tenant,
        CancellationToken cancellationToken)
    {
        if (EnsureCafeAccess(cafeId, tenant) is { } denied) return denied;
        if (tenant.PlanTier is null)
            return BadRequest(new ApiResponse<object>(false, null, new ApiError("INVALID", "Plan tier missing.")));

        var validation = await _campaignValidator.ValidateAsync(request, cancellationToken);
        if (!validation.IsValid) return BadRequest(ValidationError(validation));

        var (success, data, code, message) = await _smsMarketingService.SendCampaignAsync(
            cafeId, tenant.PlanTier.Value, request, cancellationToken);

        if (!success)
        {
            return code switch
            {
                "PLAN_LIMIT_REACHED" => StatusCode(StatusCodes.Status403Forbidden,
                    new ApiResponse<object>(false, null, new ApiError(code, message!))),
                "NOT_FOUND" => NotFound(new ApiResponse<object>(false, null, new ApiError(code, message!))),
                _ => BadRequest(new ApiResponse<object>(false, null, new ApiError(code!, message!)))
            };
        }

        return Ok(new ApiResponse<SmsCampaignResult>(true, data));
    }
}
