<?php
namespace App\Controllers;

use App\Core\Database;
use App\Core\SmtpMailer;

class AdminEmailTestController
{
    protected function db()
    {
        return Database::getInstance();
    }

    private function startSession(): void
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }
    }

    private function role(): string
    {
        return (string)($_SESSION['role'] ?? $_SESSION['user_role'] ?? '');
    }

    private function requireAdmin(): void
    {
        $this->startSession();

        if (empty($_SESSION['user_id'])) {
            header("Location: /easychair/login");
            exit;
        }

        if (!in_array($this->role(), ['super_admin','org_admin','admin'], true)) {
            http_response_code(403);
            exit("Access denied.");
        }
    }

    private function phpMailAvailable(): bool
    {
        return function_exists('mail');
    }

    private function sendMail(string $to, string $subject, string $body): array
    {
        $mailer = new SmtpMailer();
        $result = $mailer->send($to, $subject, $body, $to);

        return [
            'ok' => (bool)($result['ok'] ?? false),
            'error' => $result['error'] ?? null,
            'debug' => $result['debug'] ?? '',
        ];
    }

    public function index()
    {
        $this->requireAdmin();

        $db = $this->db();

        $outbox = $db->query("
            SELECT *
            FROM system_mail_outbox
            ORDER BY id DESC
            LIMIT 100
        ")->fetchAll(\PDO::FETCH_ASSOC);

        $templates = $db->query("
            SELECT *
            FROM system_email_templates
            ORDER BY template_key
        ")->fetchAll(\PDO::FETCH_ASSOC);

        $resetTokens = $db->query("
            SELECT *
            FROM password_reset_tokens
            ORDER BY id DESC
            LIMIT 50
        ")->fetchAll(\PDO::FETCH_ASSOC);

        $smtpSettings = SmtpMailer::settings();

        $diagnostics = [
            'smtp_enabled' => $smtpSettings['smtp_enabled'] ?? '(missing)',
            'smtp_host' => $smtpSettings['smtp_host'] ?? '(missing)',
            'smtp_port' => $smtpSettings['smtp_port'] ?? '(missing)',
            'smtp_security' => $smtpSettings['smtp_security'] ?? '(missing)',
            'smtp_username' => $smtpSettings['smtp_username'] ?? '(missing)',
            'smtp_from_email' => $smtpSettings['smtp_from_email'] ?? '(missing)',
            'php_version' => phpversion(),
            'mail_function' => $this->phpMailAvailable() ? 'available but not used now' : 'missing',
            'sendmail_path' => ini_get('sendmail_path') ?: '(empty)',
            'server_name' => $_SERVER['SERVER_NAME'] ?? '',
        ];

        ob_start();
        require BASE_PATH . '/app/views/admin/email_test/index.php';
        $content = ob_get_clean();

        require BASE_PATH . '/app/views/layouts/admin_layout.php';
    }

    public function sendTest()
    {
        $this->requireAdmin();

        $to = trim($_POST['email'] ?? '');
        $subject = trim($_POST['subject'] ?? 'EasyChair Test Email');
        $body = trim($_POST['body'] ?? '');

        if ($to === '' || !filter_var($to, FILTER_VALIDATE_EMAIL)) {
            $_SESSION['email_test_error'] = 'Valid recipient email is required.';
            header("Location: /easychair/admin/email-test");
            exit;
        }

        if ($body === '') {
            $body = "This is a test email from EasyChair at " . date('Y-m-d H:i:s') . ".\n\nIf you received this, server mail delivery is working.";
        }

        $db = $this->db();

        $stmt = $db->prepare("
            INSERT INTO system_mail_outbox
            (template_key, user_id, recipient_email, recipient_name, subject, body, status)
            VALUES ('manual_test', ?, ?, ?, ?, ?, 'queued')
        ");
        $stmt->execute([
            (int)($_SESSION['user_id'] ?? 0),
            $to,
            $to,
            $subject,
            $body
        ]);

        $outboxId = (int)$db->lastInsertId();

        $result = $this->sendMail($to, $subject, $body);

        if ($result['ok']) {
            $stmt = $db->prepare("
                UPDATE system_mail_outbox
                SET status='sent',
                    sent_at=NOW(),
                    error_message=NULL
                WHERE id=?
            ");
            $stmt->execute([$outboxId]);

            $_SESSION['email_test_success'] = "Test email sent successfully to {$to}.";
        } else {
            $stmt = $db->prepare("
                UPDATE system_mail_outbox
                SET status='failed',
                    error_message=?
                WHERE id=?
            ");
            $stmt->execute([trim(($result['error'] ?? '') . "\n\n" . ($result['debug'] ?? '')), $outboxId]);

            $_SESSION['email_test_error'] = "Test email failed: " . $result['error'];
        }

        header("Location: /easychair/admin/email-test");
        exit;
    }

    public function resend()
    {
        $this->requireAdmin();

        $id = (int)($_GET['id'] ?? 0);

        $db = $this->db();

        $stmt = $db->prepare("
            SELECT *
            FROM system_mail_outbox
            WHERE id=?
            LIMIT 1
        ");
        $stmt->execute([$id]);
        $mail = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$mail) {
            $_SESSION['email_test_error'] = 'Mail row not found.';
            header("Location: /easychair/admin/email-test");
            exit;
        }

        $result = $this->sendMail(
            (string)$mail['recipient_email'],
            (string)$mail['subject'],
            (string)$mail['body']
        );

        if ($result['ok']) {
            $stmt = $db->prepare("
                UPDATE system_mail_outbox
                SET status='sent',
                    sent_at=NOW(),
                    error_message=NULL
                WHERE id=?
            ");
            $stmt->execute([$id]);

            $_SESSION['email_test_success'] = 'Email resent successfully.';
        } else {
            $stmt = $db->prepare("
                UPDATE system_mail_outbox
                SET status='failed',
                    error_message=?
                WHERE id=?
            ");
            $stmt->execute([trim(($result['error'] ?? '') . "\n\n" . ($result['debug'] ?? '')), $id]);

            $_SESSION['email_test_error'] = 'Resend failed: ' . $result['error'];
        }

        header("Location: /easychair/admin/email-test");
        exit;
    }

    public function markSent()
    {
        $this->requireAdmin();

        $id = (int)($_GET['id'] ?? 0);

        $stmt = $this->db()->prepare("
            UPDATE system_mail_outbox
            SET status='sent',
                sent_at=COALESCE(sent_at, NOW())
            WHERE id=?
        ");
        $stmt->execute([$id]);

        header("Location: /easychair/admin/email-test");
        exit;
    }

    public function saveSmtp()
    {
        $this->requireAdmin();

        $fields = [
            'smtp_enabled',
            'smtp_host',
            'smtp_port',
            'smtp_security',
            'smtp_username',
            'smtp_password',
            'smtp_from_email',
            'smtp_from_name',
        ];

        foreach ($fields as $field) {
            $value = trim((string)($_POST[$field] ?? ''));

            if ($field === 'smtp_password' && $value === '') {
                continue;
            }

            $stmt = $this->db()->prepare("
                INSERT INTO system_mail_settings (setting_key, setting_value)
                VALUES (?, ?)
                ON DUPLICATE KEY UPDATE setting_value=VALUES(setting_value)
            ");
            $stmt->execute([$field, $value]);
        }

        $_SESSION['email_test_success'] = 'SMTP settings saved.';
        header("Location: /easychair/admin/email-test");
        exit;
    }


}