package com.saas.tenant.controller;

import com.saas.admin.dto.*;
import com.saas.shared.core.TenantContext;
import com.saas.voip.service.VapiCostTrackingService;
import com.saas.voip.service.VapiService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.List;

/**
 * Tenant Controller for Vapi.ai self-service
 * TENANT_USER - isolated to their own tenant data
 */
@RestController
@RequestMapping("/api/tenant/vapi")
@PreAuthorize("hasRole('TENANT_USER')")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "Tenant - Vapi.ai", description = "Self-service endpoints for managing Vapi.ai assistants and calls")
public class TenantVapiController {
    
    private final VapiService vapiService;
    private final VapiCostTrackingService costTrackingService;
    
    // ========================================
    // ASSISTANTS
    // ========================================
    
    @GetMapping("/assistants")
    @Operation(summary = "List my Vapi assistants", description = "Get all assistants for the authenticated tenant")
    @ApiResponse(responseCode = "200", description = "Assistants retrieved successfully")
    public ResponseEntity<List<VapiAssistantDTO>> getMyAssistants() {
        String tenantId = TenantContext.getTenantId();
        log.info("📋 Tenant {} requesting their Vapi assistants", tenantId);
        
        List<VapiAssistantDTO> assistants = vapiService.listAssistants(tenantId);
        return ResponseEntity.ok(assistants);
    }
    
    @GetMapping("/assistants/{assistantId}")
    @Operation(summary = "Get my assistant by ID", description = "Retrieve a specific assistant")
    @ApiResponse(responseCode = "200", description = "Assistant found")
    @ApiResponse(responseCode = "404", description = "Assistant not found")
    public ResponseEntity<VapiAssistantDTO> getMyAssistant(@PathVariable Long assistantId) {
        String tenantId = TenantContext.getTenantId();
        log.info("🔍 Tenant {} requesting assistant {}", tenantId, assistantId);
        
        try {
            VapiAssistantDTO assistant = vapiService.getAssistant(tenantId, assistantId);
            return ResponseEntity.ok(assistant);
        } catch (Exception e) {
            log.error("❌ Assistant not found or access denied: {}", assistantId);
            return ResponseEntity.notFound().build();
        }
    }
    
    @PostMapping("/assistants")
    @Operation(summary = "Create Vapi assistant", description = "Create a new voice assistant")
    @ApiResponse(responseCode = "201", description = "Assistant created successfully")
    @ApiResponse(responseCode = "400", description = "Invalid input")
    public ResponseEntity<VapiAssistantDTO> createAssistant(@Valid @RequestBody CreateVapiAssistantDTO dto) {
        String tenantId = TenantContext.getTenantId();
        log.info("➕ Tenant {} creating Vapi assistant: {}", tenantId, dto.getName());
        
        try {
            VapiAssistantDTO created = vapiService.createAssistant(tenantId, dto);
            return ResponseEntity.status(HttpStatus.CREATED).body(created);
        } catch (Exception e) {
            log.error("❌ Error creating assistant: {}", e.getMessage());
            return ResponseEntity.badRequest().build();
        }
    }
    
    @PatchMapping("/assistants/{assistantId}")
    @Operation(summary = "Update my assistant", description = "Update an existing assistant")
    @ApiResponse(responseCode = "200", description = "Assistant updated successfully")
    @ApiResponse(responseCode = "404", description = "Assistant not found")
    public ResponseEntity<VapiAssistantDTO> updateAssistant(
            @PathVariable Long assistantId,
            @Valid @RequestBody UpdateVapiAssistantDTO dto) {
        
        String tenantId = TenantContext.getTenantId();
        log.info("✏️ Tenant {} updating assistant {}", tenantId, assistantId);
        
        try {
            VapiAssistantDTO updated = vapiService.updateAssistant(tenantId, assistantId, dto);
            return ResponseEntity.ok(updated);
        } catch (Exception e) {
            log.error("❌ Error updating assistant: {}", e.getMessage());
            return ResponseEntity.notFound().build();
        }
    }
    
    @DeleteMapping("/assistants/{assistantId}")
    @Operation(summary = "Delete my assistant", description = "Delete an assistant")
    @ApiResponse(responseCode = "204", description = "Assistant deleted successfully")
    @ApiResponse(responseCode = "404", description = "Assistant not found")
    public ResponseEntity<Void> deleteAssistant(@PathVariable Long assistantId) {
        String tenantId = TenantContext.getTenantId();
        log.info("🗑️ Tenant {} deleting assistant {}", tenantId, assistantId);
        
        try {
            vapiService.deleteAssistant(tenantId, assistantId);
            return ResponseEntity.noContent().build();
        } catch (Exception e) {
            log.error("❌ Error deleting assistant: {}", e.getMessage());
            return ResponseEntity.notFound().build();
        }
    }
    
    // ========================================
    // CALLS
    // ========================================
    
    @PostMapping("/calls")
    @Operation(summary = "Start Vapi call", description = "Start an outbound call with a Vapi assistant")
    @ApiResponse(responseCode = "201", description = "Call started successfully")
    @ApiResponse(responseCode = "400", description = "Invalid input")
    public ResponseEntity<VapiCallDTO> startCall(@Valid @RequestBody StartVapiCallDTO dto) {
        String tenantId = TenantContext.getTenantId();
        log.info("📞 Tenant {} starting call to {} with assistant {}", 
            tenantId, dto.getCustomerNumber(), dto.getAssistantId());
        
        try {
            VapiCallDTO call = vapiService.startCall(tenantId, dto);
            return ResponseEntity.status(HttpStatus.CREATED).body(call);
        } catch (Exception e) {
            log.error("❌ Error starting call: {}", e.getMessage());
            return ResponseEntity.badRequest().build();
        }
    }
    
    @GetMapping("/calls")
    @Operation(summary = "List my calls", description = "Get all calls for the authenticated tenant")
    @ApiResponse(responseCode = "200", description = "Calls retrieved successfully")
    public ResponseEntity<List<VapiCallDTO>> getMyCalls() {
        String tenantId = TenantContext.getTenantId();
        log.info("📋 Tenant {} requesting their Vapi calls", tenantId);
        
        List<VapiCallDTO> calls = vapiService.listCalls(tenantId);
        return ResponseEntity.ok(calls);
    }
    
    @GetMapping("/calls/{vapiCallId}")
    @Operation(summary = "Get my call by ID", description = "Retrieve a specific call")
    @ApiResponse(responseCode = "200", description = "Call found")
    @ApiResponse(responseCode = "404", description = "Call not found")
    public ResponseEntity<VapiCallDTO> getMyCall(@PathVariable String vapiCallId) {
        String tenantId = TenantContext.getTenantId();
        log.info("🔍 Tenant {} requesting call {}", tenantId, vapiCallId);
        
        try {
            VapiCallDTO call = vapiService.getCall(tenantId, vapiCallId);
            return ResponseEntity.ok(call);
        } catch (Exception e) {
            log.error("❌ Call not found or access denied: {}", vapiCallId);
            return ResponseEntity.notFound().build();
        }
    }
    
    // ========================================
    // COST ANALYTICS
    // ========================================
    
    @GetMapping("/costs")
    @Operation(summary = "Get my cost analytics", description = "Get Vapi cost analytics for the authenticated tenant")
    @ApiResponse(responseCode = "200", description = "Cost analytics retrieved successfully")
    public ResponseEntity<VapiCostAnalyticsDTO> getMyCostAnalytics(
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
        
        String tenantId = TenantContext.getTenantId();
        
        // Default to last 30 days if not provided
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
        }
        if (endDate == null) {
            endDate = LocalDate.now();
        }
        
        log.info("💰 Tenant {} requesting cost analytics ({} to {})", tenantId, startDate, endDate);
        
        VapiCostAnalyticsDTO analytics = costTrackingService.getCostAnalytics(tenantId, startDate, endDate);
        return ResponseEntity.ok(analytics);
    }
}
