package com.saas.tenant.service;

import com.saas.tenant.entity.VapiCall;
import com.saas.tenant.entity.VapiCallCostRecord;
import com.saas.tenant.repository.VapiCallCostRecordRepository;
import com.saas.tenant.repository.VapiCallRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * Tenant Vapi Call Service
 * 
 * Manages Vapi.ai call history and costs in tenant-specific database
 * - Uses NEW tenant/entity/VapiCall (NO tenantId)
 * - Physical isolation via database-per-tenant
 * - Populated via webhooks (end-of-call-report) from Vapi.ai
 * 
 * Architecture:
 * - Call tracking: VapiCall (transcript, metadata)
 * - Cost tracking: VapiCallCostRecord (costs, breakdown)
 * - Linked to VapiAssistant via assistantId
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class TenantVapiCallService {
    
    private final VapiCallRepository vapiCallRepository;
    private final VapiCallCostRecordRepository vapiCallCostRecordRepository;
    
    @Transactional(transactionManager = "tenantTransactionManager")
    public VapiCall saveCall(VapiCall call) {
        log.info("📞 Saving Vapi call - CallID: {}, Assistant: {}, Status: {}", 
                call.getVapiCallId(), call.getAssistantId(), call.getStatus());
        
        return vapiCallRepository.save(call);
    }
    
    @Transactional(transactionManager = "tenantTransactionManager")
    public VapiCallCostRecord saveCallCost(VapiCallCostRecord costRecord) {
        log.info("💰 Saving Vapi call cost - CallID: {}, Cost: {} {}", 
                costRecord.getVapiCallId(), costRecord.getTotalCost(), costRecord.getCurrency());
        
        return vapiCallCostRecordRepository.save(costRecord);
    }
    
    @Transactional(transactionManager = "tenantTransactionManager", readOnly = true)
    public Optional<VapiCall> getCallByVapiId(String vapiCallId) {
        return vapiCallRepository.findByVapiCallId(vapiCallId);
    }
    
    @Transactional(transactionManager = "tenantTransactionManager", readOnly = true)
    public List<VapiCall> getCallsByAssistant(String assistantId) {
        return vapiCallRepository.findByAssistantId(assistantId);
    }
    
    @Transactional(transactionManager = "tenantTransactionManager", readOnly = true)
    public List<VapiCall> getCallsByStatus(String status) {
        return vapiCallRepository.findByStatus(status);
    }
    
    @Transactional(transactionManager = "tenantTransactionManager", readOnly = true)
    public List<VapiCall> getCallsByDateRange(LocalDateTime startDate, LocalDateTime endDate) {
        return vapiCallRepository.findByStartTimeBetween(startDate, endDate);
    }
    
    @Transactional(transactionManager = "tenantTransactionManager", readOnly = true)
    public Map<String, Object> getCallAnalytics(LocalDateTime startDate, LocalDateTime endDate) {
        Map<String, Object> analytics = new HashMap<>();
        
        Long callCount = vapiCallRepository.getCallCountBetween(startDate, endDate);
        BigDecimal totalCost = vapiCallRepository.getTotalCostBetween(startDate, endDate);
        List<Object[]> callsByStatus = vapiCallRepository.getCallCountByStatusBetween(startDate, endDate);
        
        BigDecimal totalVapiCost = vapiCallCostRecordRepository.getTotalCostBetween(startDate, endDate);
        Long vapiCallCount = vapiCallCostRecordRepository.getCallCountBetween(startDate, endDate);
        BigDecimal avgCostPerMinute = vapiCallCostRecordRepository.getAverageCostPerMinuteBetween(startDate, endDate);
        
        analytics.put("totalCalls", callCount != null ? callCount : 0L);
        analytics.put("totalCost", totalCost != null ? totalCost : BigDecimal.ZERO);
        analytics.put("totalVapiCost", totalVapiCost != null ? totalVapiCost : BigDecimal.ZERO);
        analytics.put("vapiCallCount", vapiCallCount != null ? vapiCallCount : 0L);
        analytics.put("averageCostPerMinute", avgCostPerMinute != null ? avgCostPerMinute : BigDecimal.ZERO);
        analytics.put("startDate", startDate);
        analytics.put("endDate", endDate);
        
        Map<String, Long> statusCounts = new HashMap<>();
        for (Object[] row : callsByStatus) {
            String status = (String) row[0];
            Long count = (Long) row[1];
            statusCounts.put(status, count);
        }
        analytics.put("callsByStatus", statusCounts);
        
        log.info("📊 Vapi call analytics generated - Total Calls: {}, Total Cost: {} USD, Period: {} to {}", 
                callCount, totalVapiCost, startDate, endDate);
        
        return analytics;
    }
    
    @Transactional(transactionManager = "tenantTransactionManager", readOnly = true)
    public Optional<VapiCallCostRecord> getCallCostByVapiCallId(String vapiCallId) {
        return vapiCallCostRecordRepository.findByVapiCallId(vapiCallId);
    }
}
