<?php

class Mailer
{
    private static function log(string $message): void
    {
        $logFile = APP_ROOT . '/mailer.log';
        $timestamp = date('Y-m-d H:i:s');
        file_put_contents($logFile, "[$timestamp] $message" . PHP_EOL, FILE_APPEND);
        error_log($message);
    }

    public static function send(string $to, string $subject, string $htmlBody): bool
    {
        require_once APP_ROOT . '/models/Setting.php';
        $settingModel = new Setting();

        $provider = $settingModel->get('email_provider') ?? 'sendgrid';
        $fromEmail = $settingModel->get('from_email');

        if (empty($fromEmail)) {
            self::log('Email configuration error: From email is not set');
            return false;
        }

        if ($provider === 'mailersend') {
            return self::sendViaMailerSend($to, $subject, $htmlBody, $fromEmail, $settingModel);
        } elseif ($provider === 'php') {
            return self::sendViaPhpMail($to, $subject, $htmlBody, $fromEmail);
        } else {
            return self::sendViaSendGrid($to, $subject, $htmlBody, $fromEmail, $settingModel);
        }
    }

    private static function sendViaSendGrid(string $to, string $subject, string $htmlBody, string $fromEmail, Setting $settingModel): bool
    {
        $apiKey = $settingModel->get('sendgrid_api_key');

        if (empty($apiKey)) {
            self::log('SendGrid configuration error: API key is not set');
            return false;
        }

        $email = new \SendGrid\Mail\Mail();
        $email->setFrom($fromEmail, Lang::get('app_name'));
        $email->setSubject($subject);
        $email->addTo($to);
        $email->addContent("text/html", $htmlBody);

        $sendgrid = new \SendGrid($apiKey);

        try {
            $response = $sendgrid->send($email);
            $success = $response->statusCode() >= 200 && $response->statusCode() < 300;
            if (!$success) {
                self::log('SendGrid API error: ' . $response->statusCode() . ' - ' . $response->body());
            }
            return $success;
        } catch (\Exception $e) {
            self::log('SendGrid error: ' . $e->getMessage());
            return false;
        }
    }

    private static function sendViaMailerSend(string $to, string $subject, string $htmlBody, string $fromEmail, Setting $settingModel): bool
    {
        $apiToken = $settingModel->get('mailersend_api_token');

        if (empty($apiToken)) {
            self::log('MailerSend configuration error: API token is not set');
            return false;
        }

        try {
            self::log('MailerSend: Attempting to send email to ' . $to . ' from ' . $fromEmail);
            $mailersend = new \MailerSend\MailerSend(['api_key' => $apiToken]);
            
            $emailParams = new \MailerSend\Helpers\Builder\EmailParams();
            $emailParams->setFrom($fromEmail)
                       ->setFromName(Lang::get('app_name'))
                       ->setRecipients([new \MailerSend\Helpers\Builder\Recipient($to, 'User')])
                       ->setSubject($subject)
                       ->setHtml($htmlBody);
            
            $response = $mailersend->email->send($emailParams);
            self::log('MailerSend: Email sent successfully');
            return true;
        } catch (\Throwable $e) {
            $errorMsg = 'MailerSend error [' . get_class($e) . ']: ' . $e->getMessage();
            try {
                if (method_exists($e, 'getResponse') && $e->getResponse()) {
                    $body = (string) $e->getResponse()->getBody();
                    $errorMsg .= ' | Response: ' . $body;
                }
            } catch (\Throwable $inner) {
                $errorMsg .= ' | Could not read response body: ' . $inner->getMessage();
            }
            self::log($errorMsg);
            return false;
        }
    }

    private static function sendViaPhpMail(string $to, string $subject, string $htmlBody, string $fromEmail): bool
    {
        $headers = "MIME-Version: 1.0\r\n";
        $headers .= "Content-type: text/html; charset=UTF-8\r\n";
        $headers .= "From: " . Lang::get('app_name') . " <" . $fromEmail . ">\r\n";

        try {
            $result = mail($to, $subject, $htmlBody, $headers);
            if ($result) {
                self::log('PHP mail: Email sent successfully to ' . $to);
            } else {
                self::log('PHP mail: Failed to send email to ' . $to);
            }
            return $result;
        } catch (\Exception $e) {
            self::log('PHP mail error: ' . $e->getMessage());
            return false;
        }
    }

    public static function sendAccountApprovedEmail(string $to, string $displayName): bool
    {
        $subject = Lang::get('app_name') . ' - ' . Lang::get('account_approved_email_subject');
        $loginUrl = APP_URL . '/login';

        $htmlBody = "
        <div style='font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;'>
            <div style='text-align: center; margin-bottom: 30px;'>
                <h1 style='color: #2563eb;'>" . Lang::get('app_name') . "</h1>
            </div>
            <div style='background: #f8fafc; padding: 30px; border-radius: 10px; margin-bottom: 20px;'>
                <h2 style='color: #1f2937; margin-bottom: 20px;'>" . Lang::get('account_approved_email_subject') . "</h2>
                <p style='color: #6b7280; line-height: 1.6; margin-bottom: 25px;'>
                    " . sprintf(Lang::get('account_approved_email_body'), htmlspecialchars($displayName)) . "
                </p>
                <div style='text-align: center;'>
                    <a href='{$loginUrl}' style='display: inline-block; background: #2563eb; color: white; padding: 12px 30px; text-decoration: none; border-radius: 5px; font-weight: bold;'>
                        " . Lang::get('account_approved_email_cta') . "
                    </a>
                </div>
            </div>
            <div style='text-align: center; color: #9ca3af; font-size: 12px;'>
                <p>" . Lang::get('app_name') . "</p>
            </div>
        </div>";

        return self::send($to, $subject, $htmlBody);
    }

    public static function sendEmailVerificationEmail(string $to, string $displayName, string $verifyLink): bool
    {
        $subject = Lang::get('app_name') . ' - ' . Lang::get('email_verification_subject');

        $htmlBody = "
        <div style='font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;'>
            <div style='text-align: center; margin-bottom: 30px;'>
                <h1 style='color: #2563eb;'>" . Lang::get('app_name') . "</h1>
            </div>
            <div style='background: #f8fafc; padding: 30px; border-radius: 10px; margin-bottom: 20px;'>
                <h2 style='color: #1f2937; margin-bottom: 20px;'>" . Lang::get('email_verification_subject') . "</h2>
                <p style='color: #6b7280; line-height: 1.6; margin-bottom: 25px;'>
                    " . sprintf(Lang::get('email_verification_body'), htmlspecialchars($displayName)) . "
                </p>
                <div style='text-align: center;'>
                    <a href='{$verifyLink}' style='display: inline-block; background: #2563eb; color: white; padding: 12px 30px; text-decoration: none; border-radius: 5px; font-weight: bold;'>
                        " . Lang::get('email_verification_cta') . "
                    </a>
                </div>
                <p style='color: #9ca3af; font-size: 14px; margin-top: 25px;'>
                    " . Lang::get('email_verification_expires_note') . "
                </p>
            </div>
            <div style='text-align: center; color: #9ca3af; font-size: 12px;'>
                <p>" . Lang::get('app_name') . "</p>
            </div>
        </div>";

        return self::send($to, $subject, $htmlBody);
    }

    public static function sendPasswordResetEmail(string $to, string $resetLink): bool
    {
        $subject = Lang::get('app_name') . ' - ' . Lang::get('forgot_password');
        
        $htmlBody = "
        <div style='font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;'>
            <div style='text-align: center; margin-bottom: 30px;'>
                <h1 style='color: #2563eb;'>" . Lang::get('app_name') . "</h1>
            </div>
            <div style='background: #f8fafc; padding: 30px; border-radius: 10px; margin-bottom: 20px;'>
                <h2 style='color: #1f2937; margin-bottom: 20px;'>" . Lang::get('forgot_password') . "</h2>
                <p style='color: #6b7280; line-height: 1.6; margin-bottom: 25px;'>
                    " . Lang::get('email_reset_sent') . "
                </p>
                <div style='text-align: center;'>
                    <a href='{$resetLink}' style='display: inline-block; background: #2563eb; color: white; padding: 12px 30px; text-decoration: none; border-radius: 5px; font-weight: bold;'>
                        " . Lang::get('reset_password_btn') . "
                    </a>
                </div>
                <p style='color: #9ca3af; font-size: 14px; margin-top: 25px;'>
                    " . Lang::get('reset_link_invalid') . "
                </p>
            </div>
            <div style='text-align: center; color: #9ca3af; font-size: 12px;'>
                <p>If you didn't request this password reset, you can safely ignore this email.</p>
            </div>
        </div>";
        
        return self::send($to, $subject, $htmlBody);
    }
}
