using Api.Services.Contracts;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Models.Settings;
using Swashbuckle.AspNetCore.Annotations;
using Models.Requests;
using Shared.Models.Responses;

namespace Api.Controllers
{
    /// <summary>
    /// Endpoints that expose captcha configuration and verification.
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    public sealed class CaptchaController : ControllerBase
    {
        private readonly CaptchaSettings _captchaSettings;
        private readonly ICaptchaVerifier _captcha;
        private readonly ILogger<CaptchaController> _log;

        public CaptchaController(IOptions<CaptchaSettings> options, ICaptchaVerifier captcha, ILogger<CaptchaController> log)
        {
            _captchaSettings = options.Value;
            _captcha = captcha;
            _log = log;
        }

        /// <summary>
        /// Returns the public reCAPTCHA site key used by the client to render the widget.
        /// </summary>
        [HttpGet]
        [SwaggerOperation(Summary = "Get captcha site key")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public IActionResult GetSiteKey()
        {
            return Ok(_captchaSettings.PublicKey);
        }

        /// <summary>
        /// Verify a captcha token and return the verification verdict.
        /// </summary>
        [HttpPost("verify")]
        [SwaggerOperation(Summary = "Verify captcha token")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status400BadRequest)]
        [SwaggerResponse(StatusCodes.Status400BadRequest, "Captcha verification failed or token missing", typeof(ErrorResponse))]
        public async Task<IActionResult> Verify([FromBody] CaptchaVerifyRequest req, CancellationToken ct)
        {
            if (req is null || string.IsNullOrWhiteSpace(req.Token))
            {
                return BadRequest(new ErrorResponse { Error = "Missing token", Code = "captcha_token_missing" });
            }

            var userIp = HttpContext.Connection.RemoteIpAddress?.ToString();
            var verdict = await _captcha.VerifyAsync(req.Token, userIp, req.ExpectedAction, ct);
            if (!verdict.Success)
            {
                _log.LogWarning("Captcha failed. ip={Ip} score={Score} err={Err}", userIp, verdict.Score, verdict.Error);
                return BadRequest(new ErrorResponse
                {
                    Error = "Captcha verification failed.",
                    Code = "captcha_verification_failed",
                    Score = verdict.Score
                });
            }

            return Ok(verdict);
        }
    }
}
