package com.saas.shared.email;

import com.saas.admin.entity.Tenant;
import com.saas.admin.entity.User;
import com.saas.admin.repository.TenantRepository;
import com.saas.admin.repository.UserRepository;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.List;

/**
 * Email Notification Service
 * Handles sending emails for:
 * - Monthly invoices to tenant admins
 * - Payment notifications to system admins
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class EmailNotificationService {

    private final BrevoEmailService brevoEmailService;
    private final EmailTemplateService emailTemplateService;
    private final TenantRepository tenantRepository;
    private final UserRepository userRepository;

    /**
     * Send monthly invoices to all tenant admins
     * Runs every first day of the month at 2:00 AM
     */
    @Scheduled(cron = "0 0 2 1 * ?")
    @Transactional(transactionManager = "adminTransactionManager")
    public void sendMonthlyInvoicesToAllTenants() {
        log.info("📧 Starting monthly invoice sending process...");

        try {
            // Get all active tenants
            List<Tenant> activeTenants = tenantRepository.findAll();

            if (activeTenants.isEmpty()) {
                log.warn("No active tenants found for invoice sending");
                return;
            }

            YearMonth previousMonth = YearMonth.now().minusMonths(1);

            for (Tenant tenant : activeTenants) {
                try {
                    sendMonthlyInvoiceToTenant(tenant, previousMonth);
                } catch (Exception e) {
                    log.error("❌ Failed to send invoice to tenant {}: {}", tenant.getTenantName(), e.getMessage(), e);
                }
            }

            log.info("✅ Monthly invoice sending completed for {} tenants", activeTenants.size());
        } catch (Exception e) {
            log.error("❌ Error in sendMonthlyInvoicesToAllTenants: {}", e.getMessage(), e);
        }
    }

    /**
     * Send monthly invoice to a specific tenant admin
     */
    @Transactional(transactionManager = "adminTransactionManager")
    public void sendMonthlyInvoiceToTenant(Tenant tenant, YearMonth month) {
        try {
            // Get tenant admin(s) - currently using a simple query
            // TODO: Implement proper role-based query when Role entity is available
            List<User> tenantAdmins = userRepository.findAll().stream()
                    .filter(u -> tenant.getId().toString().equals(u.getTenantId()) && "ADMIN".equals(u.getRole()))
                    .toList();

            if (tenantAdmins.isEmpty()) {
                log.warn("No admin users found for tenant: {}", tenant.getTenantName());
                return;
            }

            // Calculate usage stats (example values - integrate with real usage tracking)
            // TODO: Get from actual call/SMS/AI usage logs
            int callMinutes = 250;
            int smsCount = 45;
            int aiInteractions = 78;
            int includedMinutes = 500;
            int usedMinutes = 250;
            int overageMinutes = 0;

            BigDecimal baseAmount = new BigDecimal("99.00");
            BigDecimal overageAmount = BigDecimal.ZERO;
            BigDecimal totalAmount = baseAmount.add(overageAmount);

            String htmlContent = emailTemplateService.buildMonthlyInvoiceEmail(
                    tenant.getTenantName(),
                    tenantAdmins.get(0).getFirstName() + " " + tenantAdmins.get(0).getLastName(),
                    month.toString(),
                    baseAmount,
                    includedMinutes,
                    usedMinutes,
                    overageMinutes,
                    overageAmount,
                    totalAmount,
                    "https://admin.example.com/invoices/" + month);

            for (User admin : tenantAdmins) {
                sendMonthlyInvoiceEmailAsync(
                        admin.getEmail(),
                        admin.getFirstName() + " " + admin.getLastName(),
                        tenant.getTenantName(),
                        month,
                        htmlContent);
            }

            log.info("✅ Monthly invoice sent to {} admins for tenant: {}", tenantAdmins.size(), tenant.getTenantName());
        } catch (Exception e) {
            log.error("❌ Error sending monthly invoice to tenant {}: {}", tenant.getTenantName(), e.getMessage(), e);
        }
    }

    /**
     * Send monthly invoice email asynchronously
     */
    @Async
    private void sendMonthlyInvoiceEmailAsync(String email, String adminName, String tenantName,
            YearMonth month, String htmlContent) {
        try {
            boolean sent = brevoEmailService.sendEmailWithHtml(
                    email,
                    adminName,
                    String.format("📊 Facture mensuelle - %s (%s)", tenantName, month),
                    htmlContent);

            if (sent) {
                log.info("✅ Invoice email sent to admin: {}", email);
            } else {
                log.error("❌ Failed to send invoice email to admin: {}", email);
            }
        } catch (Exception e) {
            log.error("❌ Error sending invoice email to {}: {}", email, e.getMessage(), e);
        }
    }

    /**
     * Notify system admins of a new subscription payment
     */
    @Async
    public void notifySystemAdminsOfPayment(String tenantName, String tenantId, String planName,
            BigDecimal amount, String paymentStatus) {
        try {
            // Get all system admins from the admin database
            List<User> systemAdmins = userRepository.findAll().stream()
                    .filter(u -> u.getUserType() != null && u.getUserType().toString().equals("SYSTEM_ADMIN")
                            && "ACTIVE".equals(u.getStatus()))
                    .toList();

            if (systemAdmins.isEmpty()) {
                log.warn("No system admins found for payment notification");
                return;
            }

            String htmlContent = emailTemplateService.buildSubscriptionPaymentNotification(
                    tenantName,
                    tenantId,
                    planName,
                    amount,
                    paymentStatus,
                    LocalDateTime.now(),
                    "pi_" + System.currentTimeMillis() // Placeholder payment intent ID
            );

            for (User admin : systemAdmins) {
                try {
                    boolean sent = brevoEmailService.sendEmailWithHtml(
                            admin.getEmail(),
                            admin.getFirstName() + " " + admin.getLastName(),
                            "💰 Notification de paiement d'abonnement",
                            htmlContent);

                    if (sent) {
                        log.info("✅ Payment notification sent to system admin: {}", admin.getEmail());
                    } else {
                        log.error("❌ Failed to send payment notification to: {}", admin.getEmail());
                    }
                } catch (Exception e) {
                    log.error("❌ Error sending payment notification to {}: {}", admin.getEmail(), e.getMessage(), e);
                }
            }

            log.info("✅ Payment notifications sent to {} system admins", systemAdmins.size());
        } catch (Exception e) {
            log.error("❌ Error notifying system admins of payment: {}", e.getMessage(), e);
        }
    }

    /**
     * Calculate total monthly cost for a tenant
     * TODO: Integrate with actual usage tracking service
     */
    private BigDecimal calculateTenantMonthlyCost(Tenant tenant, YearMonth month) {
        // This is a placeholder - should integrate with actual cost tracking
        // See docs/AI_COST_TRACKING_DOCUMENTATION.md for implementation
        return BigDecimal.ZERO;
    }

    /**
     * Send test email for verification
     */
    @Async
    public void sendTestEmail(String recipientEmail, String recipientName) {
        try {
            String htmlContent = emailTemplateService.buildTestEmail(recipientName);

            boolean sent = brevoEmailService.sendEmailWithHtml(
                    recipientEmail,
                    recipientName,
                    "🧪 Email de test - SaaS VoIP Platform",
                    htmlContent);

            if (sent) {
                log.info("✅ Test email sent successfully to: {}", recipientEmail);
            } else {
                log.error("❌ Failed to send test email to: {}", recipientEmail);
            }
        } catch (Exception e) {
            log.error("❌ Error sending test email to {}: {}", recipientEmail, e.getMessage(), e);
        }
    }
}
