<?php
/**
 * EmailHelper — Reusable SMTP Email Sender
 *
 * Reads SMTP settings directly from DB and sends HTML emails via PHPMailer.
 * Used by: BranchStudentController, BranchFeeController, SuperAdminBranchController,
 * BranchApplicationController, etc.
 *
 * Usage:
 *   $helper = new \App\Helpers\EmailHelper();
 *   $sent = $helper->send('student@example.com', 'John', 'Subject', '<html>...</html>');
 *   if (!$sent) { $error = $helper->getLastError(); }
 *
 * Upload to: /gmind/app/Helpers/EmailHelper.php
 */

namespace App\Helpers;

class EmailHelper
{
    private ?\PDO $db = null;
    private string $lastError = '';
    private ?string $phpMailerPath = null;

    public function __construct(?\PDO $db = null)
    {
        $this->db = $db ?: $this->getDb();
    }

    /**
     * Send an HTML email.
     *
     * @param string $toEmail  Recipient email
     * @param string $toName   Recipient name
     * @param string $subject  Email subject
     * @param string $htmlBody HTML body content
     * @param array  $attachments  Optional attachments: [['path' => '/path/to/file.pdf', 'name' => 'receipt.pdf'], ...]
     * @return bool  True on success, false on failure (check getLastError)
     */
    public function send(string $toEmail, string $toName, string $subject, string $htmlBody, array $attachments = []): bool
    {
        $this->lastError = '';

        // Step 1: Read SMTP settings
        $smtp = $this->readSmtpSettings();

        if (empty($smtp['smtp_host']) || empty($smtp['smtp_from_email'])) {
            $this->lastError = 'SMTP not configured (host or from_email missing)';
            error_log('EmailHelper: ' . $this->lastError);
            return false;
        }

        // Step 2: Load PHPMailer
        $path = $this->findPHPMailerPath();
        if (!$path) {
            $this->lastError = 'PHPMailer library not found';
            error_log('EmailHelper: ' . $this->lastError);
            return false;
        }

        require_once $path . '/PHPMailer.php';
        require_once $path . '/SMTP.php';
        require_once $path . '/Exception.php';

        try {
            $mail = new \PHPMailer\PHPMailer\PHPMailer(true);
            $mail->isSMTP();
            $mail->Host       = $smtp['smtp_host'];
            $mail->Port       = (int)($smtp['smtp_port'] ?? 465);
            $mail->SMTPAuth   = !empty($smtp['smtp_username']);
            $mail->Username   = $smtp['smtp_username'] ?? '';
            $mail->Password   = $smtp['smtp_password'] ?? '';

            // Encryption
            $enc = $smtp['smtp_encryption'] ?? 'ssl';
            if ($enc === 'ssl') {
                $mail->SMTPSecure = \PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_SMTPS;
            } elseif ($enc === 'tls') {
                $mail->SMTPSecure = \PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS;
            } else {
                $mail->SMTPSecure = '';
                $mail->SMTPAutoTLS = false;
            }

            $mail->CharSet = 'UTF-8';
            $mail->Timeout = 25;

            // SSL bypass for cPanel self-signed certs
            $mail->SMTPOptions = [
                'ssl' => [
                    'verify_peer'       => false,
                    'verify_peer_name'  => false,
                    'allow_self_signed' => true,
                ],
            ];

            // From
            $mail->setFrom($smtp['smtp_from_email'], $smtp['smtp_from_name'] ?? 'Gmind Institute');

            // To
            $mail->addAddress($toEmail, $toName);

            // Attachments
            foreach ($attachments as $att) {
                if (!empty($att['path']) && file_exists($att['path'])) {
                    $mail->addAttachment($att['path'], $att['name'] ?? basename($att['path']));
                }
            }

            // Content
            $mail->isHTML(true);
            $mail->Subject = $subject;
            $mail->Body    = $htmlBody;
            $mail->AltBody = strip_tags(str_replace(['<br>', '<br/>', '</p>'], "\n", $htmlBody));

            $mail->send();
            error_log("EmailHelper: email sent to {$toEmail} (subject: {$subject})");
            return true;
        } catch (\PHPMailer\PHPMailer\Exception $e) {
            $this->lastError = $e->getMessage();
            error_log('EmailHelper PHPMailer error: ' . $e->getMessage());
            return false;
        } catch (\Throwable $e) {
            $this->lastError = $e->getMessage();
            error_log('EmailHelper exception: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Check if SMTP is configured (host + from_email set).
     */
    public function isConfigured(): bool
    {
        $smtp = $this->readSmtpSettings();
        return !empty($smtp['smtp_host']) && !empty($smtp['smtp_from_email']);
    }

    public function getLastError(): string
    {
        return $this->lastError;
    }

    /**
     * Read SMTP settings from settings table (both column pairs).
     */
    private function readSmtpSettings(): array
    {
        if (!$this->db) return [];

        $keys = ['smtp_host', 'smtp_port', 'smtp_username', 'smtp_password', 'smtp_encryption', 'smtp_from_email', 'smtp_from_name'];
        $result = [];

        // Method 1: setting_key / setting_value
        try {
            $placeholders = implode(',', array_fill(0, count($keys), '?'));
            $stmt = $this->db->prepare("SELECT `setting_key`, `setting_value` FROM `settings` WHERE `setting_key` IN ({$placeholders})");
            $stmt->execute($keys);
            foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) ?: [] as $row) {
                $k = $row['setting_key'] ?? '';
                if (in_array($k, $keys, true)) {
                    $result[$k] = $row['setting_value'] ?? '';
                }
            }
        } catch (\Throwable $e) {}

        // Method 2: key_name / value (fill missing or empty)
        try {
            $placeholders = implode(',', array_fill(0, count($keys), '?'));
            $stmt = $this->db->prepare("SELECT `key_name`, `value` FROM `settings` WHERE `key_name` IN ({$placeholders})");
            $stmt->execute($keys);
            foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) ?: [] as $row) {
                $k = $row['key_name'] ?? '';
                $v = $row['value'] ?? '';
                if (in_array($k, $keys, true) && (!isset($result[$k]) || $result[$k] === '')) {
                    $result[$k] = $v;
                }
            }
        } catch (\Throwable $e) {}

        return $result;
    }

    private function findPHPMailerPath(): ?string
    {
        if ($this->phpMailerPath !== null) return $this->phpMailerPath;

        $basePath = defined('BASE_PATH') ? BASE_PATH : '';
        $docRoot  = rtrim($_SERVER['DOCUMENT_ROOT'] ?? '', '/');
        $relRoot  = dirname(__DIR__, 2); // app/Helpers → app → project root

        $paths = [
            $docRoot . $basePath . '/phpmailer/src',
            $docRoot . '/phpmailer/src',
            $relRoot . '/phpmailer/src',
            $docRoot . $basePath . '/PHPMailer/src',
            $docRoot . '/PHPMailer/src',
            $relRoot . '/PHPMailer/src',
            '/home/advaysin/public_html/gmind/phpmailer/src',
            '/home/advaysin/public_html/phpmailer/src',
        ];

        foreach ($paths as $path) {
            $realPath = realpath($path);
            if ($realPath && is_dir($realPath) && file_exists($realPath . '/PHPMailer.php')) {
                $this->phpMailerPath = $realPath;
                return $realPath;
            }
        }
        return null;
    }

    private function getDb(): ?\PDO
    {
        try {
            if (function_exists('getDb')) return getDb();
        } catch (\Throwable $e) {}
        return null;
    }
}
