<?php

namespace Formatrica\Submission\Rendering;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
/**
 * Formats submission data for display
 */
final class Message_Formatter
{
    private Template_Renderer $renderer;

    public function __construct(?Template_Renderer $renderer = null)
    {
        $this->renderer = $renderer ?? new Template_Renderer();
    }

    /**
     * Build a default headline for a submission
     *
     * @param array<string, mixed> $form
     * @return string
     */
    public function build_headline(array $form): string
    {
        $title = isset($form['title']) && is_string($form['title']) && $form['title'] !== ''
            ? $form['title']
            : __('your form', 'formatrica');

        /* translators: %s: form title */
        return sprintf(__('New submission on %s', 'formatrica'), $title);
    }

    /**
     * Build submission lines from payload
     *
     * @param array<string, mixed> $payload
     * @param array<int, array<string, mixed>> $field_meta
     * @return array<int, array{label:string,value:string}>
     */
    public function build_lines(array $payload, array $field_meta): array
    {
        $lines = [];

        foreach ($field_meta as $meta) {
            if (!is_array($meta)) {
                continue;
            }

            $name = isset($meta['name']) ? (string) $meta['name'] : '';
            $label = isset($meta['label']) && $meta['label'] !== '' ? (string) $meta['label'] : $name;

            if ($label === '') {
                continue;
            }

            $value = array_key_exists($name, $payload) ? $payload[$name] : ($meta['value'] ?? '');

            // Edition display override for text-first consumers (Pro registers
            // the richtext HTML->plain flattening).
            $value = apply_filters('formatrica_field_display_text', $value, $meta);

            $lines[] = [
                'label' => $label,
                'value' => $this->renderer->normalise_value($value),
            ];
        }

        return $lines;
    }

    /**
     * Format lines for Slack
     *
     * @param array<int, array{label:string,value:string}> $lines
     * @return string
     */
    public function format_for_slack(array $lines): string
    {
        $formatted = [];

        foreach ($lines as $line) {
            $value = $line['value'] !== '' ? $line['value'] : __('(empty)', 'formatrica');
            $formatted[] = sprintf(
                '*%s*: %s',
                $this->escape_slack($line['label']),
                $this->escape_slack($value)
            );
        }

        return implode("\n", $formatted);
    }

    /**
     * Format lines for Markdown output
     *
     * @param array<int, array{label:string,value:string}> $lines
     * @return string
     */
    public function format_for_markdown(array $lines): string
    {
        if (empty($lines)) {
            return '';
        }

        $segments = [];
        foreach ($lines as $line) {
            $value = $line['value'] !== '' ? $line['value'] : __('(empty)', 'formatrica');
            $segments[] = sprintf('**%s**: %s', $line['label'], $value);
        }

        return implode("\n\n", $segments);
    }

    /**
     * Format lines for plain text
     *
     * @param array<int, array{label:string,value:string}> $lines
     * @param string $headline
     * @return string
     */
    public function format_for_plaintext(array $lines, string $headline = ''): string
    {
        $parts = [];

        if ($headline !== '') {
            $parts[] = $headline;
        }

        foreach ($lines as $line) {
            $value = $line['value'] !== '' ? $line['value'] : __('(empty)', 'formatrica');
            $parts[] = sprintf('%s: %s', $line['label'], $value);
        }

        return implode("\n", $parts);
    }

    /**
     * Escape special characters for Slack
     *
     * @param string $value
     * @return string
     */
    private function escape_slack(string $value): string
    {
        return strtr($value, [
            '&' => '&amp;',
            '<' => '&lt;',
            '>' => '&gt;',
        ]);
    }
}
