package com.saas.tenant.service;

import com.saas.tenant.entity.CallCostRecord;
import com.saas.tenant.repository.CallCostRecordRepository;
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 Call Cost Service
 * 
 * Manages call cost records in tenant-specific database
 * - Uses NEW tenant/entity/CallCostRecord (NO tenantId)
 * - Physical isolation via database-per-tenant
 * - Replaces old CallCostTrackingService (admin DB)
 * 
 * Migration Status:
 * - NEW: Uses tenant/repository/CallCostRecordRepository
 * - OLD: CallCostTrackingService uses admin/repository (deprecated)
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class TenantCallCostService {
    
    private final CallCostRecordRepository callCostRecordRepository;
    
    @Transactional(transactionManager = "tenantTransactionManager")
    public CallCostRecord saveCallCost(CallCostRecord costRecord) {
        log.info("💰 Saving call cost record - CallSid: {}, Provider: {}, Cost: {} {}", 
                costRecord.getCallSid(), costRecord.getProvider(), costRecord.getCost(), costRecord.getCurrency());
        
        Optional<CallCostRecord> existing = callCostRecordRepository.findByCallSid(costRecord.getCallSid());
        if (existing.isPresent()) {
            log.info("📝 Updating existing cost record for CallSid: {}", costRecord.getCallSid());
            CallCostRecord existingRecord = existing.get();
            existingRecord.setCost(costRecord.getCost());
            existingRecord.setCurrency(costRecord.getCurrency());
            existingRecord.setCallDurationSeconds(costRecord.getCallDurationSeconds());
            existingRecord.setCallEndTime(costRecord.getCallEndTime());
            existingRecord.setCostDetails(costRecord.getCostDetails());
            return callCostRecordRepository.save(existingRecord);
        }
        
        return callCostRecordRepository.save(costRecord);
    }
    
    @Transactional(transactionManager = "tenantTransactionManager", readOnly = true)
    public Optional<CallCostRecord> getCallCostByCallSid(String callSid) {
        return callCostRecordRepository.findByCallSid(callSid);
    }
    
    @Transactional(transactionManager = "tenantTransactionManager", readOnly = true)
    public Map<String, Object> getCostReport(LocalDateTime startDate, LocalDateTime endDate) {
        Map<String, Object> report = new HashMap<>();
        
        BigDecimal totalCost = callCostRecordRepository.getTotalCostBetween(startDate, endDate);
        Long callCount = callCostRecordRepository.getCallCountBetween(startDate, endDate);
        List<Object[]> costByProvider = callCostRecordRepository.getCostByProviderBetween(startDate, endDate);
        
        report.put("totalCost", totalCost != null ? totalCost : BigDecimal.ZERO);
        report.put("totalCalls", callCount != null ? callCount : 0L);
        report.put("startDate", startDate);
        report.put("endDate", endDate);
        
        Map<String, BigDecimal> providerCosts = new HashMap<>();
        for (Object[] row : costByProvider) {
            String provider = (String) row[0];
            BigDecimal cost = (BigDecimal) row[1];
            providerCosts.put(provider, cost);
        }
        report.put("costByProvider", providerCosts);
        
        log.info("📊 Cost report generated - Total: {} USD, Calls: {}, Period: {} to {}", 
                totalCost, callCount, startDate, endDate);
        
        return report;
    }
    
    @Transactional(transactionManager = "tenantTransactionManager", readOnly = true)
    public List<CallCostRecord> getAllCostRecords(LocalDateTime startDate, LocalDateTime endDate) {
        return callCostRecordRepository.findByCallStartTimeBetween(startDate, endDate);
    }
    
    @Transactional(transactionManager = "tenantTransactionManager", readOnly = true)
    public List<CallCostRecord> getCostRecordsByProvider(String provider) {
        return callCostRecordRepository.findByProvider(provider);
    }
    
    @Transactional(transactionManager = "tenantTransactionManager", readOnly = true)
    public List<CallCostRecord> getAllCosts() {
        log.debug("🔍 Fetching all costs for current tenant (physical isolation)");
        return callCostRecordRepository.findAll();
    }
}
