<?php

namespace GriffinForms\Includes\Pipelines\Workers;

use GriffinForms\Includes\Mailer\MailHandler;
use GriffinForms\Includes\Notifications\NotificationChannelRegistry;
use GriffinForms\Includes\Pipelines\SubmissionContextBuilder;
use GriffinForms\Log;

class NotificationDispatchWorker
{
    public function process(array $job, array $payload): void
    {
        $submission_id   = absint($job['submission_id'] ?? 0);
        $form_id         = absint($job['form_id'] ?? 0);
        $channel_id      = sanitize_key($payload['channel'] ?? 'email');
        $recipient       = sanitize_email($payload['recipient'] ?? '');
        $message_id      = absint($payload['message_id'] ?? 0);
        $notification_id = sanitize_text_field($payload['notification_id'] ?? '');

        if (!$submission_id || !$form_id || !$recipient || !$message_id) {
            throw new \RuntimeException('notification_dispatch_email: missing required payload fields.');
        }

        if (!NotificationChannelRegistry::getInstance()->get($channel_id)) {
            Log::getInstance()->add(
                'warning',
                'submission',
                $submission_id,
                0,
                sprintf('notification_dispatch_email: channel "%s" not registered (integration inactive). notification_id=%s', $channel_id, $notification_id),
                'Notification'
            );
            throw new \RuntimeException('__NO_RETRY__: channel not registered');
        }

        $message = $this->getMessageById($message_id);
        if (!$message) {
            Log::getInstance()->add(
                'warning',
                'submission',
                $submission_id,
                0,
                sprintf('notification_dispatch_email: message %d not found; email not sent. notification_id=%s', $message_id, $notification_id),
                'Notification'
            );
            throw new \RuntimeException(sprintf('__NO_RETRY__: message %d not found', $message_id));
        }

        $context = SubmissionContextBuilder::getInstance()->build($submission_id);
        $merge_engine = new \GriffinForms\Includes\MergeTokens\Engine();
        $subject = $merge_engine->render($message['name'] ?? '', $context);
        $content = $merge_engine->render($message['content'] ?? '', $context);

        if (trim($content) === '') {
            Log::getInstance()->add(
                'warning',
                'submission',
                $submission_id,
                0,
                sprintf('notification_dispatch_email: message %d has empty content; email not sent. notification_id=%s', $message_id, $notification_id),
                'Notification'
            );
            return;
        }

        $mailer = new MailHandler();
        $mailer->setLogContext('submission', $submission_id);
        $mailer->setSubmissionId($submission_id);
        $mailer->setEmailSubject($subject);
        $mailer->setEmailContent($content);
        $mailer->setEmailRecipient($recipient);
        $mailer->sendMail();

        Log::getInstance()->add(
            'info',
            'submission',
            $submission_id,
            0,
            sprintf('Notification email sent to %s (message_id=%d, notification_id=%s).', $recipient, $message_id, $notification_id),
            'Notification'
        );
    }

    private function getMessageById(int $message_id): ?array
    {
        global $wpdb;
        $table = \GriffinForms\Config::getInstance()->getTable('message');
        if (!$table) {
            return null;
        }

        $row = $wpdb->get_row(
            $wpdb->prepare("SELECT * FROM {$table} WHERE id = %d", $message_id),
            ARRAY_A
        );

        return $row ?: null;
    }
}
