package com.saas.voip.controller;

import com.saas.shared.security.WebhookSecurityService;
import com.saas.voip.service.VapiWebhookService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * Vapi.ai Webhook Controller
 * 
 * Handles webhooks from Vapi.ai:
 * - end-of-call-report: Call finished (transcript, cost, analysis)
 * - status-update: Call status changed (queued, ringing, in-progress, ended)
 * - function-call: AI invoked a function (requires response)
 * 
 * Security: Phase 2.1 hardening
 * - Uses WebhookSecurityService with constant-time comparison
 * - Prevents timing attacks on secret validation
 */
@RestController
@RequestMapping("/api/vapi/webhook")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "Vapi.ai Webhooks", description = "Webhook endpoints for Vapi.ai events")
public class VapiWebhookController {
    
    private final VapiWebhookService webhookService;
    private final WebhookSecurityService webhookSecurityService;
    
    @Value("${vapi.webhook.secret:}")
    private String vapiWebhookSecret;
    
    /**
     * Main webhook endpoint for all Vapi.ai events
     * Vapi sends webhook with X-Vapi-Secret header for authentication
     */
    @PostMapping
    @Operation(summary = "Receive Vapi webhook", description = "Process Vapi.ai webhook events (end-of-call-report, status-update, function-call)")
    @ApiResponse(responseCode = "200", description = "Webhook processed successfully")
    @ApiResponse(responseCode = "401", description = "Invalid webhook secret")
    public ResponseEntity<?> handleWebhook(
            @RequestHeader(value = "X-Vapi-Secret", required = false) String providedSecret,
            @RequestBody Map<String, Object> payload) {
        
        log.info("📥 Vapi webhook received: {}", payload.get("type"));
        
        // Validate webhook secret
        if (!isValidSecret(providedSecret)) {
            log.error("❌ Invalid Vapi webhook secret provided");
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                .body(Map.of("error", "Invalid webhook secret"));
        }
        
        // Route webhook based on type
        String eventType = (String) payload.get("type");
        if (eventType == null) {
            log.error("❌ No event type in webhook payload");
            return ResponseEntity.badRequest()
                .body(Map.of("error", "Missing event type"));
        }
        
        try {
            switch (eventType) {
                case "end-of-call-report":
                    webhookService.processEndOfCallReport(payload);
                    return ResponseEntity.ok(Map.of("status", "processed"));
                    
                case "status-update":
                    webhookService.processStatusUpdate(payload);
                    return ResponseEntity.ok(Map.of("status", "processed"));
                    
                case "function-call":
                    Map<String, Object> response = webhookService.processFunctionCall(payload);
                    return ResponseEntity.ok(response);
                    
                default:
                    log.warn("⚠️ Unknown webhook type: {}", eventType);
                    return ResponseEntity.ok(Map.of("status", "ignored", "message", "Unknown event type"));
            }
            
        } catch (Exception e) {
            log.error("❌ Error processing Vapi webhook: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(Map.of("error", e.getMessage()));
        }
    }
    
    /**
     * Validate webhook secret (Phase 2.1 hardening)
     * Uses constant-time comparison to prevent timing attacks
     */
    private boolean isValidSecret(String providedSecret) {
        return webhookSecurityService.validateSimpleSecret(providedSecret, vapiWebhookSecret);
    }
}
