package es.tatvil.taiageweb.controlador;

import com.stripe.exception.SignatureVerificationException;
import com.stripe.model.Event;
import com.stripe.model.checkout.Session;
import com.stripe.net.Webhook;
import es.tatvil.taiageweb.servicio.UsuarioService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

/**
 * Controlador REST que recibe y procesa webhooks de Stripe.
 *
 * <p>Escucha en {@code POST /webhook/stripe} (ruta excluida de CSRF en
 * {@link es.tatvil.taiageweb.config.SecurityConfig}). Verifica la firma
 * del payload con el secreto de webhook antes de procesar ningún evento.</p>
 *
 * <p>Evento gestionado:</p>
 * <ul>
 *   <li>{@code checkout.session.completed} – concede acceso al curso al usuario
 *       identificado por {@code clientReferenceId}.</li>
 * </ul>
 */
@RestController
public class WebhookController {

    /** Secreto de webhook de Stripe (inyectado desde {@code STRIPE_WEBHOOK_SECRET}). */
    @Value("${stripe.webhook-secret}")
    private String webhookSecret;

    private final UsuarioService usuarioService;

    /**
     * Constructor con inyección de dependencias.
     *
     * @param usuarioService servicio de gestión de usuarios
     */
    public WebhookController(UsuarioService usuarioService) {
        this.usuarioService = usuarioService;
    }

    /**
     * Endpoint receptor de eventos de Stripe.
     *
     * <p>Verifica la firma {@code Stripe-Signature} del payload. Si es válida
     * y el evento es {@code checkout.session.completed}, concede
     * {@code ROLE_PAGADO} al usuario referenciado.</p>
     *
     * @param payload   cuerpo crudo de la petición HTTP (necesario para verificar la firma)
     * @param sigHeader valor del header {@code Stripe-Signature}
     * @return {@code 200 OK} si el evento se procesa correctamente,
     *         {@code 400 Bad Request} si la firma es inválida
     */
    @PostMapping("/webhook/stripe")
    public ResponseEntity<String> stripeWebhook(
            @RequestBody String payload,
            @RequestHeader("Stripe-Signature") String sigHeader) {

        Event event;
        try {
            event = Webhook.constructEvent(payload, sigHeader, webhookSecret);
        } catch (SignatureVerificationException e) {
            return ResponseEntity.badRequest().body("Firma inválida");
        }

        if ("checkout.session.completed".equals(event.getType())) {
            event.getDataObjectDeserializer().getObject().ifPresent(obj -> {
                Session session = (Session) obj;
                String refId = session.getClientReferenceId();
                if (refId != null) {
                    try {
                        Long userId = Long.parseLong(refId);
                        usuarioService.darAccesoPagado(userId);
                    } catch (NumberFormatException ignored) {
                    }
                }
            });
        }

        return ResponseEntity.ok("ok");
    }
}
