<?php

namespace GriffinForms\Includes\Pipelines\Handlers;

use GriffinForms\Includes\Pipelines\PostSubmissionHandlerInterface;
use GriffinForms\Includes\Pipelines\JobRepository;
use GriffinForms\Includes\Notifications\NotificationChannelRegistry;

class NotificationDispatchHandler implements PostSubmissionHandlerInterface
{
    /** @var JobRepository */
    protected $repository;

    public function __construct()
    {
        $this->repository = JobRepository::getInstance();
    }

    public function getId(): string
    {
        return 'notification_dispatch';
    }

    public function getPriority(): int
    {
        return 95; // Below MailQueueHandler (100) until legacy handler is retired.
    }

    public function supports(array $context): bool
    {
        $form = $context['form_object'] ?? null;
        if ($form === null) {
            return false;
        }

        $notifications_raw = is_object($form) && method_exists($form, 'getProp')
            ? $form->getProp('notifications')
            : (is_array($form) ? ($form['notifications'] ?? null) : null);

        if (empty($notifications_raw)) {
            return false;
        }

        $notifications = is_array($notifications_raw) ? $notifications_raw : json_decode($notifications_raw, true);
        if (!is_array($notifications)) {
            return false;
        }

        // Support only when there are actions for initial_submission.
        $actions = $notifications['form_submission']['initial_submission'] ?? [];
        return !empty($actions);
    }

    public function handle(array $context): void
    {
        $submission_id = (int) ($context['submission_id'] ?? 0);
        $form_id       = (int) ($context['form_id'] ?? 0);

        if ($submission_id <= 0 || $form_id <= 0) {
            return;
        }

        $form = $context['form_object'] ?? null;
        $notifications_raw = is_object($form) && method_exists($form, 'getProp')
            ? $form->getProp('notifications')
            : (is_array($form) ? ($form['notifications'] ?? null) : null);

        $notifications = is_array($notifications_raw) ? $notifications_raw : json_decode($notifications_raw, true);
        if (!is_array($notifications)) {
            return;
        }

        $actions      = $notifications['form_submission']['initial_submission'] ?? [];
        $field_values = $context['field_values'] ?? [];
        $channel_reg  = NotificationChannelRegistry::getInstance();

        // Sort by order ascending before enqueuing.
        usort($actions, fn($a, $b) => ($a['order'] ?? 0) <=> ($b['order'] ?? 0));

        foreach ($actions as $action) {
            if (empty($action['enabled'])) {
                continue;
            }

            $channel_id = $action['channel'] ?? '';
            $channel    = $channel_reg->get($channel_id);
            if (!$channel) {
                continue; // Integration deactivated since save — skip silently.
            }

            // Resolve field-based recipients to their runtime values.
            $resolved = [];
            foreach ($action['recipients'] ?? [] as $recipient) {
                if ($recipient['type'] === 'static') {
                    $resolved[] = $recipient;
                } elseif ($recipient['type'] === 'field') {
                    $field_id = (string) ($recipient['value'] ?? '');
                    $values   = $field_values[$field_id] ?? $field_values[(int) $field_id] ?? [];
                    foreach ((array) $values as $val) {
                        $val = trim((string) $val);
                        if ($val !== '') {
                            $resolved[] = ['type' => 'static', 'value' => $val];
                        }
                    }
                }
            }

            if (empty($resolved)) {
                continue;
            }

            $channel->send($action, $resolved, $context);
        }
    }
}
