<?php

namespace Formatrica\Submission\Integrations\Dispatchers;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Formatrica\Submission\Integrations\Http_Client;
use Formatrica\Submission\Integrations\Integration_Dispatcher_Interface;
use Formatrica\Submission\Rendering\Message_Formatter;
use Formatrica\Submission\Rendering\Template_Renderer;

/**
 * Dispatcher for Slack integration
 */
final class Slack_Dispatcher implements Integration_Dispatcher_Interface
{
    private Http_Client $client;
    private Message_Formatter $formatter;
    private Template_Renderer $renderer;

    public function __construct(?Http_Client $client = null, ?Message_Formatter $formatter = null, ?Template_Renderer $renderer = null)
    {
        $this->client = $client ?? new Http_Client();
        $this->formatter = $formatter ?? new Message_Formatter();
        $this->renderer = $renderer ?? new Template_Renderer();
    }

    public function dispatch(array $settings, array $form, array $payload, array $context, array $field_meta): void
    {
        $webhook_url = isset($settings['webhook_url']) ? trim((string) $settings['webhook_url']) : '';

        if ($webhook_url === '') {
            return;
        }

        $template = isset($settings['message_template']) ? (string) $settings['message_template'] : '';
        $headline = $this->formatter->build_headline($form);

        if ($template !== '') {
            $message = $this->renderer->render($template, $form, $payload, $field_meta);
            if ($message === '') {
                $message = $headline;
            }
        } else {
            $lines = $this->formatter->build_lines($payload, $field_meta);
            $formatted = $this->formatter->format_for_slack($lines);
            $message = $headline;
            if ($formatted !== '') {
                $message .= "\n" . $formatted;
            }
        }

        $body = [
            'text' => $message,
        ];

        /**
         * Filter the Slack payload before it is sent.
         *
         * @param array<string, mixed> $body
         * @param array<string, mixed> $form
         * @param array<string, mixed> $payload
         * @param array<string, mixed> $context
         * @param array<int, array<string, mixed>> $field_meta
         */
        $body = apply_filters('formatrica_slack_payload', $body, $form, $payload, $context, $field_meta);

        $this->client->send_json($webhook_url, $body, 'slack', $form, $payload, $context);
    }
}
