<?php
declare(strict_types=1);

require_once __DIR__ . '/vendor/autoload.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;

class EmailService {
    private PDO $pdo;
    private ?PaymentLogger $logger;
    private array $smtpSettings;
    private string $companyName;
    
    public function __construct(PDO $pdo, ?PaymentLogger $logger = null) {
        if (!class_exists(PHPMailer::class)) {
            throw new RuntimeException('PHPMailer not loaded. Check composer installation.');
        }

        $this->pdo = $pdo;
        $this->logger = $logger;
        $this->smtpSettings = $this->loadSmtpSettings();
        $this->companyName = $this->getCompanyName();
    }

   // In EmailService class
public function sendPaymentNotification(
    $email,
    $amount,
    $currency,
    $receiptNumber,
    $runningBalance,
    $availableBalance,
    $memberData
) {
    $subject = "Payment Received - Receipt #$receiptNumber";
    
    $message = "
    <html>
    <body>
        <p>Dear {$memberData['first_name']},</p>
        <p>We have received your payment of <strong>$currency " . number_format($amount, 2) . "</strong>.</p>
        
        <p><strong>Transaction Details:</strong></p>
        <ul>
            <li>Receipt Number: $receiptNumber</li>
            <li>Amount: $currency " . number_format($amount, 2) . "</li>
            <li>New Running Balance: $currency " . number_format($runningBalance, 2) . "</li>
            <li>New Available Balance: $currency " . number_format($availableBalance, 2) . "</li>
        </ul>
        
        <p>Thank you for your payment.</p>
        <p>The {$this->companyName} Team</p>
    </body>
    </html>";

    return $this->sendEmail($email, $subject, $message);
}

    private function createPaymentMessage(
        float $amount,
        string $currency,
        string $receiptNumber,
        float $newBalance,
        ?array $memberData
    ): string {
        $firstName = $memberData['first_name'] ?? 'Valued Customer';
        $formattedAmount = number_format($amount, 2);
        $formattedBalance = number_format($newBalance, 2);

        return <<<MESSAGE
Dear {$firstName},

We have received your payment of {$currency} {$formattedAmount}.
Transaction Reference: {$receiptNumber}
Your new balance is {$currency} {$formattedBalance}

Thank you for your business!

The {$this->companyName} Team
MESSAGE;
    }

    public function sendEmail(
        string $recipient, 
        string $subject, 
        string $body,
        ?array $memberData = null
    ): array {
        try {
            if (!filter_var($recipient, FILTER_VALIDATE_EMAIL)) {
                throw new InvalidArgumentException("Invalid email address: $recipient");
            }

            $mail = $this->configureMailer();
            $this->setRecipients($mail, $recipient);
            $this->setEmailContent($mail, $subject, $body, $memberData);

            $mail->send();
            $this->logSuccess("Email to $recipient sent successfully", $subject);
            
            return $this->createSuccessResponse($recipient);
            
        } catch (Exception $e) {
            $this->logError("Failed to send email to $recipient", $e);
            return $this->createErrorResponse($e);
        }
    }

    private function configureMailer(): PHPMailer {
        $mail = new PHPMailer(true);
        
        // Server settings
        $mail->isSMTP();
        $mail->Host = $this->smtpSettings['smtp_host'];
        $mail->SMTPAuth = true;
        $mail->Username = $this->smtpSettings['smtp_username'];
        $mail->Password = $this->smtpSettings['smtp_password'];
        $mail->SMTPSecure = $this->smtpSettings['smtp_encryption'];
        $mail->Port = $this->smtpSettings['smtp_port'];
        $mail->Timeout = 15;
        $mail->CharSet = 'UTF-8';
        $mail->SMTPDebug = SMTP::DEBUG_OFF; // Change to DEBUG_SERVER for troubleshooting

        // Sender
        $fromName = $this->companyName ?: ($this->smtpSettings['from_name'] ?? 'System');
        $mail->setFrom($this->smtpSettings['smtp_username'], $fromName);

        return $mail;
    }

    private function setRecipients(PHPMailer $mail, string $recipient): void {
        $mail->addAddress($recipient);
        
        if (!empty($this->smtpSettings['cc_emails'])) {
            foreach (explode(',', $this->smtpSettings['cc_emails']) as $cc) {
                $mail->addCC(trim($cc));
            }
        }
    }

    private function setEmailContent(
        PHPMailer $mail,
        string $subject,
        string $body,
        ?array $memberData
    ): void {
        $mail->isHTML(true);
        $mail->Subject = $this->processPlaceholders($subject, $memberData);
        $mail->Body = $this->createEmailTemplate($this->processPlaceholders($body, $memberData));
        $mail->AltBody = strip_tags($body);
    }

    private function loadSmtpSettings(): array {
        $jsonFilePath = __DIR__ . '/smtp_settings_data.json';
        
        if (!file_exists($jsonFilePath)) {
            throw new RuntimeException("SMTP settings file not found at $jsonFilePath");
        }

        $json = file_get_contents($jsonFilePath);
        $settings = json_decode($json, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new RuntimeException("Invalid SMTP settings: " . json_last_error_msg());
        }

        $requiredKeys = ['smtp_host', 'smtp_username', 'smtp_password', 'smtp_port', 'smtp_encryption'];
        foreach ($requiredKeys as $key) {
            if (empty($settings[$key])) {
                throw new RuntimeException("Missing required SMTP setting: $key");
            }
        }

        return $settings;
    }

    private function getCompanyName(): string {
        try {
            $stmt = $this->pdo->query("SELECT company_name FROM company_settings LIMIT 1");
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            return $result['company_name'] ?? '';
        } catch (PDOException $e) {
            $this->logError("Failed to fetch company name", $e);
            return '';
        }
    }

    private function processPlaceholders(string $content, ?array $data): string {
        if (empty($data)) {
            return $content;
        }

        $replacements = [
            '{{first_name}}' => $data['first_name'] ?? '',
            '{{last_name}}' => $data['last_name'] ?? '',
            '{{email}}' => $data['email'] ?? '',
            '{{phone}}' => $data['phone'] ?? ''
        ];

        return str_replace(array_keys($replacements), array_values($replacements), $content);
    }

    private function createEmailTemplate(string $content): string {
        return <<<HTML
<!DOCTYPE html>
<html>
<head>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
        .container { max-width: 600px; margin: 0 auto; padding: 20px; }
        .header { background-color: #f8f9fa; padding: 15px; text-align: center; }
        .content { padding: 20px; }
        .footer { margin-top: 20px; font-size: 0.9em; color: #6c757d; text-align: center; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h2>{$this->companyName}</h2>
        </div>
        <div class="content">
            {$content}
        </div>
        <div class="footer">
            <p>This is an automated message. Please do not reply directly.</p>
        </div>
    </div>
</body>
</html>
HTML;
    }

    private function logSuccess(string $message, string $subject): void {
        if ($this->logger) {
            $this->logger->log($message, ['subject' => $subject]);
        }
    }

    private function logError(string $message, Exception $e): void {
        if ($this->logger) {
            $this->logger->log($message, [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
        }
    }

    private function createSuccessResponse(string $recipient): array {
        return [
            'status' => 'success',
            'message' => 'Email sent successfully',
            'recipient' => $recipient,
            'timestamp' => date('Y-m-d H:i:s')
        ];
    }

    private function createErrorResponse(Exception $e): array {
        return [
            'status' => 'error',
            'message' => $e->getMessage(),
            'retryable' => $this->isRetryableError($e->getMessage()),
            'timestamp' => date('Y-m-d H:i:s')
        ];
    }

    private function isRetryableError(string $error): bool {
        $retryableErrors = [
            'connection timed out',
            'could not connect',
            'authentication failed',
            'temporary failure',
            'socket'
        ];
        
        foreach ($retryableErrors as $retryable) {
            if (stripos($error, $retryable) !== false) {
                return true;
            }
        }
        
        return false;
    }
}