<?php

namespace GriffinForms\Includes\Integrations\CustomSmtp;

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception as PHPMailerException;

class Main extends \GriffinForms\Includes\Integrations\Format
{
    protected function setMeta()
    {
        $this->meta = 'customsmtp';
        $this->id = 'custom_smtp';
    }

    protected function buildInfo(): array
    {
        return [
            'id'       => 'custom_smtp',
            'name'     => __('Custom SMTP', 'griffinforms-form-builder'),
            'category' => __('Email', 'griffinforms-form-builder'),
        ];
    }

    public function getStatus(): array
    {
        $configured = $this->isConfigured();
        return [
            'configured' => $configured,
            'active'     => $configured,
            'message'    => $configured ? __('Configured', 'griffinforms-form-builder') : __('Not configured', 'griffinforms-form-builder'),
        ];
    }

    public function getConfigFields(): array
    {
        return [
            ['name' => 'smtp_host', 'label' => __('SMTP Host', 'griffinforms-form-builder'), 'type' => 'text', 'required' => true],
            ['name' => 'smtp_port', 'label' => __('SMTP Port', 'griffinforms-form-builder'), 'type' => 'number', 'required' => true],
            [
                'name'    => 'smtp_encryption',
                'label'   => __('Encryption', 'griffinforms-form-builder'),
                'type'    => 'select',
                'required'=> false,
                'options' => [
                    'none' => __('None', 'griffinforms-form-builder'),
                    'ssl'  => __('SSL', 'griffinforms-form-builder'),
                    'tls'  => __('TLS', 'griffinforms-form-builder'),
                ],
            ],
            ['name' => 'smtp_username', 'label' => __('Username', 'griffinforms-form-builder'), 'type' => 'text', 'required' => false],
            ['name' => 'smtp_password', 'label' => __('Password', 'griffinforms-form-builder'), 'type' => 'password', 'required' => false],
        ];
    }

    protected function saveConfiguration(array $config): bool
    {
        try {
            $host = isset($config['smtp_host']) ? sanitize_text_field($config['smtp_host']) : '';
            $port = isset($config['smtp_port']) ? absint($config['smtp_port']) : 0;
            $encryption = isset($config['smtp_encryption']) ? sanitize_text_field($config['smtp_encryption']) : 'none';
            $username = isset($config['smtp_username']) ? sanitize_text_field($config['smtp_username']) : '';
            $password = isset($config['smtp_password']) ? sanitize_text_field($config['smtp_password']) : '';

            if (empty($host) || empty($port)) {
                return false;
            }

            $allowed_encryption = ['none', 'ssl', 'tls'];
            if (!in_array($encryption, $allowed_encryption, true)) {
                $encryption = 'none';
            }

            $this->settings->updateOption('smtp_host', $host, 'mail');
            $this->settings->updateOption('smtp_port', $port, 'mail');
            $this->settings->updateOption('smtp_encryption', $encryption, 'mail');
            $this->settings->updateOption('smtp_username', $username, 'mail');
            $this->settings->updateOption('smtp_password', $password, 'mail');

            \GriffinForms\Includes\Integrations\Categories\Mailer::getInstance()->ensureActiveProvider($this->id);

            return true;
        } catch (\Exception $e) {
            $form_id = $this->resolveFormContextId();
            $message = 'Failed to save SMTP configuration: ' . $e->getMessage();
            $this->log->add('error', 'form', $form_id, get_current_user_id(), $message, 'Mail Integration (custom_smtp)');
            return false;
        }
    }

    protected function validateConnection(): array
    {
        $host = $this->settings->getOption('smtp_host');
        $port = (int) $this->settings->getOption('smtp_port');
        $encryption = $this->settings->getOption('smtp_encryption', 'none');
        $username = $this->settings->getOption('smtp_username');
        $password = $this->settings->getOption('smtp_password');
        $form_id = $this->resolveFormContextId();

        if (empty($host) || empty($port)) {
            return [
                'success' => false,
                'message' => __('SMTP host and port are required to run the connection test.', 'griffinforms-form-builder'),
            ];
        }

        $this->maybeLoadPHPMailer();

        $mailer = new PHPMailer(true);

        try {
            $mailer->isSMTP();
            $mailer->SMTPAuth = !empty($username);
            $mailer->Host = $host;
            $mailer->Port = $port;
            $mailer->Timeout = 10;
            $mailer->SMTPDebug = 0;

            if (!empty($username)) {
                $mailer->Username = $username;
                $mailer->Password = $password;
            }

            if ($encryption === 'ssl') {
                $mailer->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
            } elseif ($encryption === 'tls') {
                $mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
            } else {
                $mailer->SMTPSecure = false;
            }

            if ($mailer->smtpConnect()) {
                $mailer->smtpClose();
                $message = __('SMTP connection succeeded. Credentials look good.', 'griffinforms-form-builder');
                $this->log->add('success', 'form', $form_id, get_current_user_id(), 'SMTP validation succeeded.', 'Mail Integration (custom_smtp)');
                return [
                    'success' => true,
                    'message' => $message,
                ];
            }

            $error = $mailer->ErrorInfo ?: __('Unknown SMTP connection error.', 'griffinforms-form-builder');
            $mailer->smtpClose();
            $this->log->add('error', 'form', $form_id, get_current_user_id(), 'SMTP validation failed: ' . $error, 'Mail Integration (custom_smtp)');
            return [
                'success' => false,
                /* translators: %s: SMTP connection error message */
                'message' => sprintf(__('Unable to connect to SMTP server: %s', 'griffinforms-form-builder'), $error),
            ];
        } catch (PHPMailerException $e) {
            $mailer->smtpClose();
            $this->log->add('error', 'form', $form_id, get_current_user_id(), 'SMTP validation threw exception: ' . $e->getMessage(), 'Mail Integration (custom_smtp)');
            return [
                'success' => false,
                /* translators: %s: SMTP connection error message */
                'message' => sprintf(__('SMTP connection error: %s', 'griffinforms-form-builder'), $e->getMessage()),
            ];
        }
    }

    public function isLibraryInstalled(): bool
    {
        $this->maybeLoadPHPMailer();
        return class_exists('\PHPMailer\PHPMailer\PHPMailer');
    }

    public function getLibraryInstructions(): string
    {
        return __('Uses WordPress bundled PHPMailer library—no additional installation required.', 'griffinforms-form-builder');
    }

    public function isConfigured(): bool
    {
        $host = $this->settings->getOption('smtp_host');
        $port = $this->settings->getOption('smtp_port');
        return !empty($host) && !empty($port);
    }

    public function getConfigurationFormHtml(): string
    {
        $host = $this->settings->getOption('smtp_host', '');
        $port = $this->settings->getOption('smtp_port', '');
        $encryption = $this->settings->getOption('smtp_encryption', 'ssl');
        $username = $this->settings->getOption('smtp_username', '');
        $password = $this->settings->getOption('smtp_password', '');

        $fields_html = '';
        $factory = '\\GriffinForms\\Includes\\Integrations\\FormControls\\Factory';

        $fields_html .= $factory::create(
            'text',
            'smtp_host',
            $host,
            'custom_smtp',
            [
                'label' => __('SMTP Host', 'griffinforms-form-builder'),
                'required' => true,
                'description' => __('Server hostname or IP (e.g., smtp.example.com)', 'griffinforms-form-builder'),
            ]
        )->render();

        $fields_html .= $factory::create(
            'number',
            'smtp_port',
            $port,
            'custom_smtp',
            [
                'label' => __('SMTP Port', 'griffinforms-form-builder'),
                'required' => true,
                'description' => __('Typical ports: 465 (SSL) or 587 (TLS)', 'griffinforms-form-builder'),
            ]
        )->render();

        $fields_html .= $factory::create(
            'select',
            'smtp_encryption',
            $encryption,
            'custom_smtp',
            [
                'label' => __('Encryption', 'griffinforms-form-builder'),
                'options' => [
                    'none' => __('None', 'griffinforms-form-builder'),
                    'ssl'  => __('SSL', 'griffinforms-form-builder'),
                    'tls'  => __('TLS', 'griffinforms-form-builder'),
                ],
                'description' => __('Match the encryption type expected by your SMTP server.', 'griffinforms-form-builder'),
            ]
        )->render();

        $fields_html .= $factory::create(
            'text',
            'smtp_username',
            $username,
            'custom_smtp',
            [
                'label' => __('Username', 'griffinforms-form-builder'),
                'description' => __('Usually your email account or login for the SMTP server.', 'griffinforms-form-builder'),
            ]
        )->render();

        $fields_html .= $factory::create(
            'password',
            'smtp_password',
            $password,
            'custom_smtp',
            [
                'label' => __('Password', 'griffinforms-form-builder'),
            ]
        )->render();

        return $this->renderConfigurationFormTemplate('gf-custom-smtp-config', 'custom_smtp', $fields_html);
    }

    public function getConfigurationJs(): string
    {
        return "
        (function() {
            const form = document.getElementById('gf-custom-smtp-config');
            if (!form) return;

            const cancelBtn = form.querySelector('.gf-integration-btn-cancel');
            if (cancelBtn) {
                cancelBtn.addEventListener('click', function(e) {
                    e.preventDefault();
                    window.loadIntegrationInfo('custom_smtp');
                });
            }

            form.addEventListener('submit', function(e) {
                e.preventDefault();

                const formId = window.griffinformsResolveActiveFormId ? window.griffinformsResolveActiveFormId() : null;
                const formData = new FormData(form);

                jQuery.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    dataType: 'json',
                    data: {
                        action: 'saveIntegrationConfiguration',
                        integration_id: 'custom_smtp',
                        nonce: window.griffinformsIntegrationsNonce || '',
                        form_id: formId || '',
                        smtp_host: formData.get('smtp_host') || '',
                        smtp_port: formData.get('smtp_port') || '',
                        smtp_encryption: formData.get('smtp_encryption') || 'none',
                        smtp_username: formData.get('smtp_username') || '',
                        smtp_password: formData.get('smtp_password') || ''
                    },
                    success: function(response) {
                        if (response.success) {
                            window.showIntegrationsMessage('success', response.data.message || 'Configuration saved');
                            setTimeout(() => window.loadIntegrationInfo('custom_smtp'), 500);
                        } else {
                            const msg = (response.data && response.data.msg) ? response.data.msg : 'Failed to save configuration';
                            window.showIntegrationsMessage('danger', msg);
                        }
                    },
                    error: function() {
                        window.showIntegrationsMessage('danger', 'Failed to save configuration');
                    }
                });
            });
        })();
        ";
    }

    private function maybeLoadPHPMailer(): void
    {
        if (!class_exists('\PHPMailer\PHPMailer\PHPMailer')) {
            require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
            require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
            require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
        }
    }
}
