<?php
/**
 * Email Helper Functions
 * Reusable functions for sending emails throughout the application
 */

if (!class_exists('PHPMailer\\PHPMailer\\PHPMailer')) {
    $vendorBase = __DIR__ . '/vendor/phpmailer/phpmailer/src';
    if (is_file($vendorBase . '/PHPMailer.php')) {
        require_once $vendorBase . '/PHPMailer.php';
        require_once $vendorBase . '/SMTP.php';
        require_once $vendorBase . '/Exception.php';
    } else {
        require_once __DIR__ . '/PHPMailer/PHPMailer.php';
        require_once __DIR__ . '/PHPMailer/SMTP.php';
        require_once __DIR__ . '/PHPMailer/Exception.php';
    }

if (!class_exists('TonEnv')) {
    $envPath = __DIR__ . '/includes/Env.php';
    if (is_file($envPath)) { require_once $envPath; }
}
}
if (!class_exists('TonEnv')) {
    $envPath = __DIR__ . '/includes/Env.php';
    if (is_file($envPath)) { require_once $envPath; }
}
$defaultsPath = __DIR__ . '/includes/email_defaults.php';
if (is_file($defaultsPath)) { require_once $defaultsPath; }

function getEmailConfig($conn) {
    try {
        $stmt = $conn->query("SELECT config_key, config_value FROM email_config");
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        $config = [
            'smtp' => null,
            'settings' => null,
            'templates' => []
        ];
        
        foreach ($rows as $row) {
            $key = $row['config_key'];
            $value = json_decode($row['config_value'], true);
            
            if ($key === 'smtp_config') {
                $config['smtp'] = $value;
            } elseif ($key === 'email_settings') {
                $config['settings'] = $value;
            } elseif (strpos($key, 'template_') === 0) {
                $templateName = str_replace('template_', '', $key);
                $config['templates'][$templateName] = $value;
            }
        }
        
        return $config;
    } catch (PDOException $e) {
        error_log("Get email config error: " . $e->getMessage());
        return null;
    }
}

function sendEmail($conn, $to, $templateName, $variables = []) {
    try {
        $config = getEmailConfig($conn);
        
        $envHost = class_exists('TonEnv') ? TonEnv::get('MAILER_HOST', '') : '';
        $envUser = class_exists('TonEnv') ? TonEnv::get('MAILER_USERNAME', '') : '';
        $envPass = class_exists('TonEnv') ? TonEnv::get('MAILER_PASSWORD', '') : '';
        $envPort = (int)(class_exists('TonEnv') ? TonEnv::get('MAILER_PORT', '587') : 587);
        $envFrom = class_exists('TonEnv') ? TonEnv::get('MAILER_FROM', $envUser) : '';
        $envEnc = strtolower((string)(class_exists('TonEnv') ? TonEnv::get('MAILER_ENCRYPTION', '') : ''));
        $useEnv = ($envHost && $envUser && $envPass);

        // Brand defaults from environment (for template placeholders)
        $brandName = class_exists('TonEnv') ? TonEnv::get('BRAND_NAME', 'First De France Bank') : 'First De France Bank';
        $envFromName = class_exists('TonEnv') ? TonEnv::get('MAILER_FROM_NAME', $brandName) : $brandName;
        $brandEmail = class_exists('TonEnv') ? TonEnv::get('BRAND_EMAIL', ($envFrom ?: $envUser)) : ($envFrom ?: $envUser);
        $brandLogo = class_exists('TonEnv') ? TonEnv::get('BRAND_LOGO_URL', '') : '';
        $brandAddress = class_exists('TonEnv') ? TonEnv::get('BRAND_ADDRESS', '') : '';
        // Override with admin-configured settings if present
        $settings = $config['settings'] ?? [];
        if (!empty($settings['brand_name'])) { $brandName = (string)$settings['brand_name']; }
        if (!empty($settings['brand_email'])) { $brandEmail = (string)$settings['brand_email']; }
        if (!empty($settings['brand_logo_url'])) { $brandLogo = (string)$settings['brand_logo_url']; }
        if (!empty($settings['brand_address'])) { $brandAddress = (string)$settings['brand_address']; }
        // Fallback brand logo to dynamic SVG if not set (dev path)
        if (empty($brandLogo)) {
            $host = $_SERVER['HTTP_HOST'] ?? '';
            if ($host) {
                $scheme = 'https://';
                $brandLogo = $scheme . $host . '/auth-backend/brand_logo.php?t=' . rawurlencode($brandName);
            }
        }
        // Normalize relative logo URL to absolute (ensure HTTPS in emails)
        $host = $_SERVER['HTTP_HOST'] ?? '';
        if (!empty($brandLogo) && $host && strpos($brandLogo, 'http://') !== 0 && strpos($brandLogo, 'https://') !== 0) {
            if (strpos($brandLogo, '/') === 0) {
                $brandLogo = 'https://' . $host . $brandLogo;
            }
        }

        // Derive frauddesk email from brand domain
        $brandDomain = '';
        if (!empty($brandEmail) && strpos($brandEmail, '@') !== false) {
            $brandDomain = substr(strrchr($brandEmail, '@'), 1);
        }
        $fraudEmail = $brandDomain ? ('frauddesk@' . $brandDomain) : ($brandEmail ?: 'frauddesk@firstdefrance.com');

        // If SMTP is disabled and no ENV SMTP, we will try Mailer fallback below
        $smtpDisabled = ((!$config || !$config['smtp'] || !$config['smtp']['enabled']) && !$useEnv);
        
        $smtp = $config['smtp'] ?? null;
        $template = $config['templates'][$templateName] ?? null;
        if (!$template && function_exists('getDefaultTemplates')) {
            $defaults = getDefaultTemplates();
            if (isset($defaults[$templateName])) {
                $template = $defaults[$templateName];
            }
        }
        if (!$template) {
            return ['success' => false, 'error' => 'Template not found'];
        }
        
        // Merge brand defaults, then replace variables in subject and body
        $variables = array_merge([
            'brand_name' => $brandName,
            'brand_email' => $brandEmail,
            'brand_logo_url' => $brandLogo,
            'brand_address' => $brandAddress,
            'fraud_email' => $fraudEmail,
        ], (array)$variables);
        if (!isset($variables['bic_swift']) || trim((string)$variables['bic_swift']) === '') {
            $bicSwift = '';
            $bicKeys = ['bic_swift','bank_bic','swift_bic','bic'];
            foreach ($bicKeys as $bk) {
                if (!empty($settings[$bk])) { $bicSwift = trim((string)$settings[$bk]); break; }
            }
            if ($bicSwift === '') {
                try {
                    $tbl = $conn->query("SHOW TABLES LIKE 'settings'");
                    if ($tbl && $tbl->rowCount() > 0) {
                        $q = $conn->query("SELECT setting_value FROM settings WHERE setting_key IN ('bic_swift','bank_bic','swift_bic','bic') LIMIT 1");
                        $r = $q ? $q->fetch(PDO::FETCH_ASSOC) : null;
                        if ($r && !empty($r['setting_value'])) { $bicSwift = trim((string)$r['setting_value']); }
                    }
                } catch (Exception $ie) { }
            }
            if ($bicSwift === '' && class_exists('TonEnv')) {
                $bicSwift = (string)(TonEnv::get('BIC_SWIFT', TonEnv::get('BANK_BIC_SWIFT', '')));
            }
            if ($bicSwift !== '') { $variables['bic_swift'] = $bicSwift; }
        }

        // Replace variables in subject and body
        $subject = $template['subject'];
        $body = $template['body'];
        // Defensive brand override for legacy content
        $legacyMarks = ['multi-purpose international','multipurpose international','viz de france','ton sui','ton sui mining'];
        foreach ($legacyMarks as $mark) {
            $subject = str_ireplace($mark, $brandName, $subject);
            $body = str_ireplace($mark, $brandName, $body);
        }
        if (stripos($body, 'Thank you for choosing') !== false && stripos($body, '{{brand_name}}') === false) {
            $body = preg_replace('/Thank you for choosing(\s*)(?=<)/i', 'Thank you for choosing {{brand_name}}$1', $body);
        }
        
        foreach ($variables as $key => $value) {
            $pattern = '/{{\s*' . preg_quote($key, '/') . '\s*}}/i';
            $subject = preg_replace($pattern, $value, $subject);
            $body = preg_replace($pattern, $value, $body);
        }
        if (stripos($body, $brandName) === false && stripos($body, '{{brand_name}}') === false) {
            $body = preg_replace('/<body[^>]*>/i', '$0' . '<div style="text-align:center;font-weight:700;font-size:18px;color:#1a1a2e;margin:12px 0;">' . htmlspecialchars($brandName, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '</div>', $body, 1);
        }
        if (strpos($body, '\\n') !== false || strpos($body, '\\r\\n') !== false) {
            $body = str_replace(["\\r\\n", "\\n"], "\n", $body);
        }
        if (strpos($body, '\\t') !== false) {
            $body = str_replace("\\t", "    ", $body);
        }
        // Ensure spacing in Available Balance row for clients without flex support
        // Insert a non-breaking space between label and value spans if missing
        $body = preg_replace('/(Available Balance<\/span>)(\s*<span[^>]*>)/i', '$1&nbsp;$2', $body);
        
        if (!$smtpDisabled) {
            try {
                $mail = new PHPMailer\PHPMailer\PHPMailer(true);
                $mail->CharSet = 'UTF-8';
                $mail->isSMTP();
                if ($useEnv) {
                    $mail->Host = $envHost;
                    $mail->SMTPAuth = true;
                    $mail->Username = $envUser;
                    $mail->Password = $envPass;
                    $mail->SMTPSecure = ($envEnc === 'ssl' || $envPort === 465) 
                        ? PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_SMTPS 
                        : PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS;
                    $mail->Port = $envPort ?: 587;
                    $mail->setFrom($envFrom ?: $envUser, $envFromName ?: $brandName);
                } else {
                    $mail->Host = $smtp['host'];
                    $mail->SMTPAuth = true;
                    $mail->Username = $smtp['username'];
                    $mail->Password = $smtp['password'];
                    $mail->SMTPSecure = ($smtp['encryption'] ?? '') === 'ssl' 
                        ? PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_SMTPS 
                        : PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS;
                    $mail->Port = $smtp['port'];
                    $mail->setFrom($smtp['fromEmail'], (($smtp['fromName'] ?? '') ?: $brandName));
                }
                $mail->addAddress($to);
                $mail->isHTML(true);
                $mail->Subject = $subject;
                $mail->Body = $body;
                $mail->AltBody = strip_tags($body);
                $mail->send();
                return ['success' => true];
            } catch (\Throwable $pe) {
                // fall through to Mailer fallback
            }
        }
        $mailerPath = __DIR__ . '/includes/Mailer.php';
        if (is_file($mailerPath)) {
            require_once $mailerPath;
            if (class_exists('Mailer')) {
                $fallback = new Mailer();
                if ($fallback->sendEmail($to, $subject, $body, strip_tags($body))) {
                    return ['success' => true];
                }
            }
        }
        return ['success' => false, 'error' => 'Email system is disabled'];
    } catch (Exception $e) {
        error_log("Email send error: " . $e->getMessage());
        return ['success' => false, 'error' => $e->getMessage()];
    }
}

function sendVerificationEmail($conn, $userId, $userEmail, $userName) {
    try {
        $config = getEmailConfig($conn);
        $settings = $config['settings'] ?? [];
        
        if (!$settings['verificationRequired']) {
            return ['success' => true, 'message' => 'Verification not required'];
        }
        
        // Generate verification token
        $token = bin2hex(random_bytes(32));
        $expiry = $settings['verificationExpiry'] ?? 24;
        $expiryDate = date('Y-m-d H:i:s', strtotime("+{$expiry} hours"));
        
        // Store token in database
        $stmt = $conn->prepare("
            INSERT INTO email_verifications (user_id, token, expires_at)
            VALUES (:user_id, :token, :expires_at)
            ON DUPLICATE KEY UPDATE token = :token, expires_at = :expires_at, verified = 0
        ");
        
        $stmt->execute([
            'user_id' => $userId,
            'token' => $token,
            'expires_at' => $expiryDate
        ]);
        
        // Create verification link
        $verificationLink = "http://localhost:5173/verify-email?token=" . $token;
        
        // Send email
        return sendEmail($conn, $userEmail, 'verification', [
            'user_name' => $userName,
            'verification_link' => $verificationLink,
            'expiry_hours' => $expiry
        ]);
    } catch (Exception $e) {
        error_log("Send verification email error: " . $e->getMessage());
        return ['success' => false, 'error' => $e->getMessage()];
    }
}

function sendWelcomeEmail($conn, $userEmail, $userName) {
    try {
        $config = getEmailConfig($conn);
        $settings = $config['settings'] ?? [];
        
        if (!$settings['sendWelcomeEmail']) {
            return ['success' => true, 'message' => 'Welcome email disabled'];
        }
        
        return sendEmail($conn, $userEmail, 'welcome', [
            'user_name' => $userName,
            'login_link' => 'http://localhost:5173/login',
            'support_email' => 'support@firstdefrance.com'
        ]);
    } catch (Exception $e) {
        error_log("Send welcome email error: " . $e->getMessage());
        return ['success' => false, 'error' => $e->getMessage()];
    }
}

function sendDepositNotification($conn, $userEmail, $userName, $amount, $method, $status = 'request') {
    try {
        $config = getEmailConfig($conn);
        $settings = $config['settings'] ?? [];
        
        if (!$settings['sendDepositNotifications']) {
            return ['success' => true, 'message' => 'Deposit notifications disabled'];
        }
        
        $templateName = $status === 'approved' ? 'depositApproved' : 'depositRequest';
        
        $variables = [
            'user_name' => $userName,
            'amount' => $amount,
            'method' => $method,
            'date' => date('Y-m-d H:i:s')
        ];
        
        if ($status === 'approved') {
            // Get user balance
            $stmt = $conn->prepare("SELECT balance FROM users WHERE email = :email");
            $stmt->execute(['email' => $userEmail]);
            $user = $stmt->fetch(PDO::FETCH_ASSOC);
            $variables['balance'] = $user['balance'] ?? '0';
        }
        
        return sendEmail($conn, $userEmail, $templateName, $variables);
    } catch (Exception $e) {
        error_log("Send deposit notification error: " . $e->getMessage());
        return ['success' => false, 'error' => $e->getMessage()];
    }
}

function sendWithdrawalNotification($conn, $userEmail, $userName, $amount, $method, $status = 'request') {
    try {
        $config = getEmailConfig($conn);
        $settings = $config['settings'] ?? [];
        
        if (!$settings['sendWithdrawalNotifications']) {
            return ['success' => true, 'message' => 'Withdrawal notifications disabled'];
        }
        
        $templateName = $status === 'approved' ? 'withdrawalApproved' : 'withdrawalRequest';
        
        return sendEmail($conn, $userEmail, $templateName, [
            'user_name' => $userName,
            'amount' => $amount,
            'method' => $method,
            'date' => date('Y-m-d H:i:s')
        ]);
    } catch (Exception $e) {
        error_log("Send withdrawal notification error: " . $e->getMessage());
        return ['success' => false, 'error' => $e->getMessage()];
    }
}

function sendKycNotification($conn, $userEmail, $userName, $status, $reason = '') {
    try {
        $config = getEmailConfig($conn);
        $settings = $config['settings'] ?? [];
        
        if (!$settings['sendKycNotifications']) {
            return ['success' => true, 'message' => 'KYC notifications disabled'];
        }
        
        $templateName = $status === 'approved' ? 'kycApproved' : 'kycRejected';
        
        $variables = [
            'user_name' => $userName,
            'verification_level' => 'Full Access'
        ];
        
        if ($status === 'rejected') {
            $variables['reason'] = $reason;
        }
        
        return sendEmail($conn, $userEmail, $templateName, $variables);
    } catch (Exception $e) {
        error_log("Send KYC notification error: " . $e->getMessage());
        return ['success' => false, 'error' => $e->getMessage()];
    }
}

function sendTicketReplyNotification($conn, $userEmail, $userName, $ticketId, $reply) {
    try {
        $config = getEmailConfig($conn);
        $settings = $config['settings'] ?? [];
        
        if (!$settings['sendTicketNotifications']) {
            return ['success' => true, 'message' => 'Ticket notifications disabled'];
        }
        
        return sendEmail($conn, $userEmail, 'ticketReply', [
            'user_name' => $userName,
            'ticket_id' => $ticketId,
            'reply' => $reply,
            'ticket_link' => 'http://localhost:5173/dashboard/tickets'
        ]);
    } catch (Exception $e) {
        error_log("Send ticket reply notification error: " . $e->getMessage());
        return ['success' => false, 'error' => $e->getMessage()];
    }
}

// Create email_verifications table if it doesn't exist
function createEmailVerificationsTable($conn) {
    $sql = "CREATE TABLE IF NOT EXISTS email_verifications (
        id INT AUTO_INCREMENT PRIMARY KEY,
        user_id INT NOT NULL,
        token VARCHAR(255) UNIQUE NOT NULL,
        verified TINYINT(1) DEFAULT 0,
        expires_at DATETIME NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
        UNIQUE KEY unique_user (user_id)
    )";
    
    try {
        $conn->exec($sql);
    } catch (PDOException $e) {
        error_log("Email verifications table creation error: " . $e->getMessage());
    }
}

function isEmailVerificationRequired($conn) {
    try {
        $stmt = $conn->query("SELECT config_value FROM email_config WHERE config_key = 'email_settings'");
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($row) {
            $settings = json_decode($row['config_value'], true);
            return $settings['verificationRequired'] ?? false;
        }
        
        return false;
    } catch (PDOException $e) {
        return false;
    }
}

function isEmailVerified($conn, $userId) {
    try {
        $stmt = $conn->prepare("SELECT verified FROM email_verifications WHERE user_id = :user_id");
        $stmt->execute(['user_id' => $userId]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        
        return $row ? (bool)$row['verified'] : false;
    } catch (PDOException $e) {
        return false;
    }
}
?>
