<?php

namespace App\Seraph\Services;

use App\Modules\Admin\EmailSettings;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;
use Exception;

class GlobalMailerService
{
    /**
     * Send email using global SMTP configuration if available, fallback to default
     *
     * @param string $template
     * @param array $data
     * @param callable $callback
     * @param string|null $from_email Override from email
     * @param string|null $from_name Override from name
     * @param bool $use_cc_bcc Whether to include CC/BCC from SMTP settings (default: false for system notifications)
     * @param array $additional_cc Additional CC addresses to include along with global CC/BCC settings
     * @return bool
     */
    public static function send($template, $data = [], $callback = null, $from_email = null, $from_name = null, $use_cc_bcc = false, $additional_cc = [])
    {
        try {
            // Get global SMTP settings
            $settings = self::getGlobalSmtpSettings($from_email);

            if ($settings) {
                Log::info('GlobalMailerService: Using SMTP settings from: ' . $settings->email . ' (Host: ' . $settings->smtp_host . ')');
                if ($from_email) {
                    Log::info('GlobalMailerService: Overriding from_email to: ' . $from_email);
                }
                if ($from_name) {
                    Log::info('GlobalMailerService: Overriding from_name to: ' . $from_name);
                }
                return self::sendWithCustomSMTP($template, $data, $callback, $settings, $from_name, $from_email, $use_cc_bcc, $additional_cc);
            } else {
                Log::warning('GlobalMailerService: No SMTP settings found, using default Laravel mail configuration');
                // Fallback to default Laravel mail configuration
                Mail::send($template, $data, $callback);
                return true;
            }
        } catch (Exception $e) {
            Log::error('GlobalMailerService failed: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Send raw email using global SMTP configuration
     *
     * @param string $text
     * @param callable $callback
     * @param string|null $from_email Override from email
     * @param bool $use_cc_bcc Whether to include CC/BCC from SMTP settings (default: false for system notifications)
     * @return bool
     */
    public static function raw($text, $callback = null, $from_email = null, $use_cc_bcc = false)
    {
        try {
            $settings = self::getGlobalSmtpSettings($from_email);
            
            if ($settings) {
                return self::sendRawWithCustomSMTP($text, $callback, $settings, $use_cc_bcc);
            } else {
                Mail::raw($text, $callback);
                return true;
            }
        } catch (Exception $e) {
            Log::error('GlobalMailerService raw failed: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Get global SMTP settings from database
     *
     * @param string|null $from_email
     * @return EmailSettings|null
     */
    private static function getGlobalSmtpSettings($from_email = null)
    {
        try {
            $query = EmailSettings::whereNotNull('smtp_host')
                                 ->whereNotNull('smtp_username')
                                 ->whereNotNull('smtp_password');
            
            // Always get the first available SMTP configuration
            // Don't try to match user email with EmailSettings.email 
            // (EmailSettings.email is for IMAP, not user accounts)
            return $query->first();
        } catch (Exception $e) {
            Log::error('Failed to get global SMTP settings: ' . $e->getMessage());
            return null;
        }
    }

    /**
     * Send email with custom SMTP settings
     *
     * @param string $template
     * @param array $data
     * @param callable $callback
     * @param EmailSettings $settings
     * @param string|null $from_name Override from name
     * @param string|null $from_email Override from email
     * @param bool $use_cc_bcc Whether to include CC/BCC from SMTP settings
     * @param array $additional_cc Additional CC addresses to include
     * @return bool
     */
    private static function sendWithCustomSMTP($template, $data, $callback, $settings, $from_name = null, $from_email = null, $use_cc_bcc = false, $additional_cc = [])
    {
        // Store original configuration
        $originalDriver = Config::get('mail.driver');
        $originalHost = Config::get('mail.host');
        $originalPort = Config::get('mail.port');
        $originalEncryption = Config::get('mail.encryption');
        $originalUsername = Config::get('mail.username');
        $originalPassword = Config::get('mail.password');
        $originalFromAddress = Config::get('mail.from.address');
        $originalFromName = Config::get('mail.from.name');

        try {
            // Set custom SMTP configuration
            Config::set('mail.driver', 'smtp');
            Config::set('mail.host', $settings->smtp_host);
            Config::set('mail.port', $settings->smtp_port ?: 587);
            Config::set('mail.encryption', $settings->smtp_encryption ?: 'tls');
            Config::set('mail.username', $settings->smtp_username);
            Config::set('mail.password', $settings->smtp_password);
            Config::set('mail.from.address', $from_email ?: $settings->smtp_from_address ?: $settings->email);
            Config::set('mail.from.name', $from_name ?: $settings->smtp_from_name ?: 'System');

            // Clear mail manager cache
            app()->forgetInstance('mail.manager');
            app()->forgetInstance('mailer');

            // Send the email with optional CC/BCC support
            Mail::send($template, $data, function ($message) use ($callback, $settings, $use_cc_bcc, $additional_cc) {
                if ($callback) {
                    $callback($message);
                }

                // Collect all CC emails
                $allCcEmails = [];

                // Add additional CC addresses first
                if (!empty($additional_cc)) {
                    $allCcEmails = array_merge($allCcEmails, $additional_cc);
                }

                // Add global CC/BCC if explicitly requested (not for system notifications)
                if ($use_cc_bcc) {
                    // Add CC recipients from settings
                    if ($settings->smtp_cc) {
                        $ccEmails = array_map('trim', explode(',', $settings->smtp_cc));
                        $ccEmails = array_filter($ccEmails);
                        $allCcEmails = array_merge($allCcEmails, $ccEmails);
                    }
                }

                // Apply all CC emails at once (removes duplicates)
                if (!empty($allCcEmails)) {
                    $allCcEmails = array_unique($allCcEmails);
                    $message->cc($allCcEmails);
                }

                // Add BCC recipients if requested
                if ($use_cc_bcc) {
                    if ($settings->smtp_bcc) {
                        $bccEmails = array_map('trim', explode(',', $settings->smtp_bcc));
                        $bccEmails = array_filter($bccEmails);
                        if (!empty($bccEmails)) {
                            $message->bcc($bccEmails);
                        }
                    }
                }
            });

            return true;
        } finally {
            // Always restore original configuration
            Config::set('mail.driver', $originalDriver);
            Config::set('mail.host', $originalHost);
            Config::set('mail.port', $originalPort);
            Config::set('mail.encryption', $originalEncryption);
            Config::set('mail.username', $originalUsername);
            Config::set('mail.password', $originalPassword);
            Config::set('mail.from.address', $originalFromAddress);
            Config::set('mail.from.name', $originalFromName);
        }
    }

    /**
     * Send raw email with custom SMTP settings
     *
     * @param string $text
     * @param callable $callback
     * @param EmailSettings $settings
     * @param bool $use_cc_bcc Whether to include CC/BCC from SMTP settings
     * @return bool
     */
    private static function sendRawWithCustomSMTP($text, $callback, $settings, $use_cc_bcc = false)
    {
        // Store original configuration
        $originalDriver = Config::get('mail.driver');
        $originalHost = Config::get('mail.host');
        $originalPort = Config::get('mail.port');
        $originalEncryption = Config::get('mail.encryption');
        $originalUsername = Config::get('mail.username');
        $originalPassword = Config::get('mail.password');
        $originalFromAddress = Config::get('mail.from.address');
        $originalFromName = Config::get('mail.from.name');

        try {
            // Set custom SMTP configuration
            Config::set('mail.driver', 'smtp');
            Config::set('mail.host', $settings->smtp_host);
            Config::set('mail.port', $settings->smtp_port ?: 587);
            Config::set('mail.encryption', $settings->smtp_encryption ?: 'tls');
            Config::set('mail.username', $settings->smtp_username);
            Config::set('mail.password', $settings->smtp_password);
            Config::set('mail.from.address', $settings->smtp_from_address ?: $settings->email);
            Config::set('mail.from.name', $settings->smtp_from_name ?: 'System');

            // Clear mail manager cache
            app()->forgetInstance('mail.manager');
            app()->forgetInstance('mailer');

            // Send the email with optional CC/BCC support
            Mail::raw($text, function ($message) use ($callback, $settings, $use_cc_bcc) {
                if ($callback) {
                    $callback($message);
                }
                
                // Only add CC/BCC if explicitly requested (not for system notifications)
                if ($use_cc_bcc) {
                    // Add CC recipients
                    if ($settings->smtp_cc) {
                        $ccEmails = array_map('trim', explode(',', $settings->smtp_cc));
                        $ccEmails = array_filter($ccEmails);
                        if (!empty($ccEmails)) {
                            $message->cc($ccEmails);
                        }
                    }
                    
                    // Add BCC recipients
                    if ($settings->smtp_bcc) {
                        $bccEmails = array_map('trim', explode(',', $settings->smtp_bcc));
                        $bccEmails = array_filter($bccEmails);
                        if (!empty($bccEmails)) {
                            $message->bcc($bccEmails);
                        }
                    }
                }
            });

            return true;
        } finally {
            // Always restore original configuration
            Config::set('mail.driver', $originalDriver);
            Config::set('mail.host', $originalHost);
            Config::set('mail.port', $originalPort);
            Config::set('mail.encryption', $originalEncryption);
            Config::set('mail.username', $originalUsername);
            Config::set('mail.password', $originalPassword);
            Config::set('mail.from.address', $originalFromAddress);
            Config::set('mail.from.name', $originalFromName);
        }
    }
}