package com.saas.admin.controller;

import com.saas.shared.email.BrevoEmailService;
import com.saas.shared.email.EmailNotificationService;
import com.saas.shared.email.EmailTemplateService;
import com.saas.shared.exception.BusinessException;
import com.saas.shared.exception.ErrorCode;
import com.saas.shared.dto.common.ApiResponse;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * Email Management Controller
 * Provides API endpoints for testing and managing email sending via Brevo
 * Requires SYSTEM_ADMIN role
 */
@RestController
@RequestMapping("/api/admin/email")
@RequiredArgsConstructor
@Slf4j
@PreAuthorize("hasAuthority('SYSTEM_ADMIN')")
public class AdminEmailController {

    private final BrevoEmailService brevoEmailService;
    private final EmailTemplateService emailTemplateService;
    private final EmailNotificationService emailNotificationService;

    /**
     * Test email endpoint - Send a test email to verify Brevo integration
     * POST /api/admin/email/test
     */
    @PostMapping("/test")
    public ResponseEntity<ApiResponse<Map<String, String>>> sendTestEmail(
            @RequestBody SendTestEmailRequest request) {

        if (request.getEmail() == null || request.getEmail().trim().isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "Email address is required");
        }

        log.info("🧪 Sending test email to: {}", request.getEmail());

        try {
            emailNotificationService.sendTestEmail(
                    request.getEmail(),
                    request.getRecipientName() != null ? request.getRecipientName() : request.getEmail());

            Map<String, String> response = new HashMap<>();
            response.put("status", "success");
            response.put("message", "Test email queued for sending");
            response.put("recipient", request.getEmail());

            return ResponseEntity.ok(ApiResponse.success(response, "Test email sent successfully"));
        } catch (Exception e) {
            log.error("❌ Error sending test email: {}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.INTERNAL_ERROR, "Failed to send test email: " + e.getMessage());
        }
    }

    /**
     * Send doctor welcome email
     * POST /api/admin/email/doctor-welcome
     */
    @PostMapping("/doctor-welcome")
    public ResponseEntity<ApiResponse<Map<String, String>>> sendDoctorWelcomeEmail(
            @RequestBody SendDoctorWelcomeRequest request) {

        validateDoctorWelcomeRequest(request);
        log.info("📧 Sending welcome email to doctor: {} {}", request.getFirstName(), request.getLastName());

        try {
            String htmlContent = emailTemplateService.buildDoctorWelcomeEmail(
                    request.getFirstName(),
                    request.getLastName(),
                    request.getEmail(),
                    request.getPassword(),
                    request.getTenantName(),
                    request.getLoginUrl() != null ? request.getLoginUrl() : "http://localhost:3000/login");

            boolean sent = brevoEmailService.sendEmailWithHtml(
                    request.getEmail(),
                    "Dr. " + request.getFirstName() + " " + request.getLastName(),
                    "🎉 Bienvenue - Vos identifiants de connexion",
                    htmlContent);

            if (!sent) {
                throw new BusinessException(ErrorCode.INTERNAL_ERROR, "Failed to send email via Brevo");
            }

            Map<String, String> response = new HashMap<>();
            response.put("status", "success");
            response.put("message", "Welcome email sent to doctor");
            response.put("doctor_email", request.getEmail());

            return ResponseEntity.ok(ApiResponse.success(response, "Doctor welcome email sent successfully"));
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("❌ Error sending doctor welcome email: {}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.INTERNAL_ERROR, "Failed to send doctor welcome email");
        }
    }

    /**
     * Send monthly invoice email
     * POST /api/admin/email/monthly-invoice
     */
    @PostMapping("/monthly-invoice")
    public ResponseEntity<ApiResponse<Map<String, String>>> sendMonthlyInvoice(
            @RequestBody SendInvoiceRequest request) {

        validateInvoiceRequest(request);
        log.info("📊 Sending monthly invoice to: {}", request.getAdminEmail());

        try {
            String htmlContent = emailTemplateService.buildMonthlyInvoiceEmail(
                    request.getTenantName(),
                    request.getAdminName(),
                    request.getBillingPeriod(),
                    request.getBaseAmount(),
                    request.getIncludedMinutes(),
                    request.getUsedMinutes(),
                    request.getOverageMinutes(),
                    request.getOverageAmount(),
                    request.getTotalAmount(),
                    request.getInvoiceUrl() != null ? request.getInvoiceUrl() : "https://admin.example.com/invoices");

            boolean sent = brevoEmailService.sendEmailWithHtml(
                    request.getAdminEmail(),
                    request.getAdminName(),
                    String.format("📊 Facture mensuelle - %s (%s)", request.getTenantName(),
                            request.getBillingPeriod()),
                    htmlContent);

            if (!sent) {
                throw new BusinessException(ErrorCode.INTERNAL_ERROR, "Failed to send invoice email via Brevo");
            }

            Map<String, String> response = new HashMap<>();
            response.put("status", "success");
            response.put("message", "Invoice email sent");
            response.put("admin_email", request.getAdminEmail());
            response.put("tenant", request.getTenantName());

            return ResponseEntity.ok(ApiResponse.success(response, "Invoice email sent successfully"));
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("❌ Error sending invoice email: {}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.INTERNAL_ERROR, "Failed to send invoice email");
        }
    }

    /**
     * Send payment notification to system admins
     * POST /api/admin/email/payment-notification
     */
    @PostMapping("/payment-notification")
    public ResponseEntity<ApiResponse<Map<String, String>>> sendPaymentNotification(
            @RequestBody SendPaymentNotificationRequest request) {

        validatePaymentNotificationRequest(request);
        log.info("💰 Sending payment notification for tenant: {}", request.getTenantName());

        try {
            emailNotificationService.notifySystemAdminsOfPayment(
                    request.getTenantName(),
                    request.getTenantId(),
                    request.getPlanName(),
                    request.getAmount(),
                    request.getPaymentStatus() != null ? request.getPaymentStatus() : "succeeded");

            Map<String, String> response = new HashMap<>();
            response.put("status", "success");
            response.put("message", "Payment notifications sent to all system admins");
            response.put("tenant", request.getTenantName());
            response.put("amount", request.getAmount().toString());

            return ResponseEntity.ok(ApiResponse.success(response, "Payment notifications sent successfully"));
        } catch (Exception e) {
            log.error("❌ Error sending payment notification: {}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.INTERNAL_ERROR, "Failed to send payment notifications");
        }
    }

    /**
     * Check email service status
     * GET /api/admin/email/status
     */
    @GetMapping("/status")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getEmailStatus() {
        try {
            Map<String, Object> status = new HashMap<>();
            status.put("service", "Brevo Email Service");
            status.put("status", "active");
            status.put("configured", true);
            status.put("timestamp", java.time.LocalDateTime.now());

            return ResponseEntity.ok(ApiResponse.success(status, "Email service is operational"));
        } catch (Exception e) {
            log.error("❌ Error checking email status: {}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.INTERNAL_ERROR, "Failed to check email service status");
        }
    }

    // Validation methods
    private void validateDoctorWelcomeRequest(SendDoctorWelcomeRequest request) {
        if (request.getFirstName() == null || request.getFirstName().trim().isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "First name is required");
        }
        if (request.getLastName() == null || request.getLastName().trim().isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "Last name is required");
        }
        if (request.getEmail() == null || request.getEmail().trim().isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "Email is required");
        }
        if (request.getPassword() == null || request.getPassword().trim().isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "Password is required");
        }
        if (request.getTenantName() == null || request.getTenantName().trim().isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "Tenant name is required");
        }
    }

    private void validateInvoiceRequest(SendInvoiceRequest request) {
        if (request.getTenantName() == null || request.getTenantName().trim().isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "Tenant name is required");
        }
        if (request.getAdminEmail() == null || request.getAdminEmail().trim().isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "Admin email is required");
        }
        if (request.getBillingPeriod() == null || request.getBillingPeriod().trim().isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "Billing period is required");
        }
        if (request.getTotalAmount() == null || request.getTotalAmount().compareTo(BigDecimal.ZERO) < 0) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "Total amount must be greater than zero");
        }
    }

    private void validatePaymentNotificationRequest(SendPaymentNotificationRequest request) {
        if (request.getTenantName() == null || request.getTenantName().trim().isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "Tenant name is required");
        }
        if (request.getTenantId() == null || request.getTenantId().trim().isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "Tenant ID is required");
        }
        if (request.getPlanName() == null || request.getPlanName().trim().isEmpty()) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "Plan name is required");
        }
        if (request.getAmount() == null || request.getAmount().compareTo(BigDecimal.ZERO) < 0) {
            throw new BusinessException(ErrorCode.INVALID_INPUT, "Amount must be greater than zero");
        }
    }

    // Request DTOs
    @lombok.Data
    @lombok.AllArgsConstructor
    @lombok.NoArgsConstructor
    public static class SendTestEmailRequest {
        private String email;
        private String recipientName;
    }

    @lombok.Data
    @lombok.AllArgsConstructor
    @lombok.NoArgsConstructor
    public static class SendDoctorWelcomeRequest {
        private String firstName;
        private String lastName;
        private String email;
        private String password;
        private String tenantName;
        private String loginUrl;
    }

    @lombok.Data
    @lombok.AllArgsConstructor
    @lombok.NoArgsConstructor
    public static class SendInvoiceRequest {
        private String tenantName;
        private String adminName;
        private String adminEmail;
        private String billingPeriod;
        private BigDecimal baseAmount;
        private int includedMinutes;
        private int usedMinutes;
        private int overageMinutes;
        private BigDecimal overageAmount;
        private BigDecimal totalAmount;
        private String invoiceUrl;
    }

    @lombok.Data
    @lombok.AllArgsConstructor
    @lombok.NoArgsConstructor
    public static class SendPaymentNotificationRequest {
        private String tenantName;
        private String tenantId;
        private String planName;
        private BigDecimal amount;
        private String paymentStatus;
    }
}
