package com.saas.tenant.controller;

import com.saas.shared.core.TenantContext;
import com.saas.tenant.entity.RetellAgent;
import com.saas.tenant.service.TenantRetellAgentService;
import com.saas.voip.dto.CallRequest;
import com.saas.voip.dto.CallResponse;
import com.saas.voip.service.RetellApiClient;
import com.saas.voip.service.VoIPOrchestrationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * Tenant Retell AI Controller
 * 
 * Phase 4.4 - Self-service CRUD for Retell AI agents
 * 
 * Provides TENANT_USER with:
 * - Create/update/delete their own Retell agents
 * - Initiate outbound calls via Retell
 * - View call history and costs
 * 
 * Security: Only TENANT_USER can access their own data
 * Multi-tenancy: TenantContext routing to tenant DB
 */
@RestController
@RequestMapping("/api/tenant/retell")
@PreAuthorize("hasRole('TENANT_USER')")
@Tag(name = "Tenant Retell AI", description = "Self-service Retell AI management")
@RequiredArgsConstructor
@Slf4j
public class TenantRetellController {
    
    private final TenantRetellAgentService retellAgentService;
    private final RetellApiClient retellApiClient;
    private final VoIPOrchestrationService orchestrationService;
    
    /**
     * Create Retell agent (self-service)
     */
    @PostMapping("/agents")
    @Operation(summary = "Create Retell agent", description = "Tenant creates their own Retell voice agent")
    public ResponseEntity<?> createAgent(
            @RequestBody Map<String, Object> agentConfig,
            Authentication auth) {
        
        String tenantId = TenantContext.getTenantId();
        log.info("🚀 Tenant {} creating Retell agent", tenantId);
        
        try {
            // Call Retell API to create agent
            Map<String, Object> retellResponse = retellApiClient.createAgent(agentConfig);
            String retellAgentId = (String) retellResponse.get("agent_id");
            
            // Save to tenant DB
            RetellAgent agent = RetellAgent.builder()
                    .retellAgentId(retellAgentId)
                    .name((String) agentConfig.get("name"))
                    .voiceId((String) agentConfig.get("voice_id"))
                    .language((String) agentConfig.get("language"))
                    .llmModel((String) agentConfig.get("llm_model"))
                    .systemPrompt((String) agentConfig.get("system_prompt"))
                    .firstMessage((String) agentConfig.get("first_message"))
                    .status("ACTIVE")
                    .build();
            
            agent = retellAgentService.createAgent(agent);
            
            log.info("✅ Retell agent created - ID: {}", retellAgentId);
            return ResponseEntity.ok(agent);
            
        } catch (Exception e) {
            log.error("❌ Failed to create Retell agent", e);
            return ResponseEntity.internalServerError()
                .body(Map.of("error", e.getMessage()));
        }
    }
    
    /**
     * List tenant's Retell agents
     */
    @GetMapping("/agents")
    @Operation(summary = "List Retell agents", description = "Get all tenant's Retell agents")
    public ResponseEntity<?> listAgents(Authentication auth) {
        String tenantId = TenantContext.getTenantId();
        log.info("📋 Tenant {} listing Retell agents", tenantId);
        
        try {
            List<RetellAgent> agents = retellAgentService.getAllActiveAgents();
            return ResponseEntity.ok(agents);
            
        } catch (Exception e) {
            log.error("❌ Failed to list Retell agents", e);
            return ResponseEntity.internalServerError()
                .body(Map.of("error", e.getMessage()));
        }
    }
    
    /**
     * Get specific Retell agent
     */
    @GetMapping("/agents/{agentId}")
    @Operation(summary = "Get Retell agent details")
    public ResponseEntity<?> getAgent(@PathVariable String agentId) {
        log.info("🔍 Fetching Retell agent: {}", agentId);
        
        try {
            RetellAgent agent = retellAgentService.getByRetellAgentId(agentId);
            return ResponseEntity.ok(agent);
            
        } catch (Exception e) {
            log.error("❌ Failed to fetch Retell agent", e);
            return ResponseEntity.notFound().build();
        }
    }
    
    /**
     * Update Retell agent
     */
    @PatchMapping("/agents/{agentId}")
    @Operation(summary = "Update Retell agent")
    public ResponseEntity<?> updateAgent(
            @PathVariable String agentId,
            @RequestBody Map<String, Object> updates) {
        
        log.info("✏️ Updating Retell agent: {}", agentId);
        
        try {
            // Update via Retell API
            Map<String, Object> updatedAgent = retellApiClient.updateAgent(agentId, updates);
            
            // TODO: Update local DB record
            
            return ResponseEntity.ok(updatedAgent);
            
        } catch (Exception e) {
            log.error("❌ Failed to update Retell agent", e);
            return ResponseEntity.internalServerError()
                .body(Map.of("error", e.getMessage()));
        }
    }
    
    /**
     * Delete Retell agent
     */
    @DeleteMapping("/agents/{agentId}")
    @Operation(summary = "Delete Retell agent")
    public ResponseEntity<?> deleteAgent(@PathVariable String agentId) {
        log.warn("🗑️ Deleting Retell agent: {}", agentId);
        
        try {
            // Delete via Retell API
            retellApiClient.deleteAgent(agentId);
            
            // TODO: Mark as deleted in tenant DB
            
            return ResponseEntity.ok(Map.of("message", "Agent deleted successfully"));
            
        } catch (Exception e) {
            log.error("❌ Failed to delete Retell agent", e);
            return ResponseEntity.internalServerError()
                .body(Map.of("error", e.getMessage()));
        }
    }
    
    /**
     * Initiate outbound call via Retell AI
     * Uses VoIPOrchestrationService for unified routing
     * 
     * API V2 requires from_number (E.164 format)
     * 
     * Request body:
     * - from_number: Required - Caller ID (E.164 format, e.g., "+14157774444")
     * - to_number or phone_number: Required - Target number (E.164 format)
     * - agent_id: Optional - Override agent for this call
     * - dynamic_variables: Optional - LLM context variables
     */
    @PostMapping("/calls")
    @Operation(summary = "Initiate Retell call", description = "Start outbound call via Retell AI. Requires from_number and to_number in E.164 format.")
    public ResponseEntity<?> initiateCall(@RequestBody Map<String, Object> callRequest) {
        String tenantId = TenantContext.getTenantId();
        String agentId = (String) callRequest.get("agent_id");
        String fromNumber = (String) callRequest.get("from_number");
        String toNumber = (String) callRequest.getOrDefault("to_number", callRequest.get("phone_number"));
        
        log.info("📞 Tenant {} initiating Retell call - From: {}, To: {}", tenantId, fromNumber, toNumber);
        
        // Validate required from_number
        if (fromNumber == null || fromNumber.isEmpty()) {
            return ResponseEntity.badRequest()
                .body(Map.of("error", "from_number is required (E.164 format, e.g., +14157774444)"));
        }
        
        // Validate required to_number
        if (toNumber == null || toNumber.isEmpty()) {
            return ResponseEntity.badRequest()
                .body(Map.of("error", "to_number is required (E.164 format, e.g., +12137774445)"));
        }
        
        try {
            // Extract dynamic variables if present
            @SuppressWarnings("unchecked")
            Map<String, Object> dynamicVariables = (Map<String, Object>) callRequest.get("dynamic_variables");
            
            // Use VoIPOrchestrationService for unified call routing
            CallRequest request = CallRequest.builder()
                    .tenantId(tenantId)
                    .assistantId(agentId)
                    .fromNumber(fromNumber)
                    .phoneNumber(toNumber)
                    .dynamicVariables(dynamicVariables)
                    .build();
            
            CallResponse response = orchestrationService.initiateRetellCall(request);
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("❌ Failed to initiate Retell call", e);
            return ResponseEntity.internalServerError()
                .body(Map.of("error", e.getMessage()));
        }
    }
    
    /**
     * Get call details
     */
    @GetMapping("/calls/{callId}")
    @Operation(summary = "Get Retell call details")
    public ResponseEntity<?> getCallDetails(@PathVariable String callId) {
        log.info("📊 Fetching Retell call: {}", callId);
        
        try {
            Map<String, Object> callDetails = retellApiClient.getCallDetails(callId);
            return ResponseEntity.ok(callDetails);
            
        } catch (Exception e) {
            log.error("❌ Failed to fetch Retell call details", e);
            return ResponseEntity.internalServerError()
                .body(Map.of("error", e.getMessage()));
        }
    }
}
