<?php

namespace TableBuilderPro\Shortcode;

use TableBuilder\Shortcode\ShortcodeUtils;
use TableBuilderPro\Core\Enqueue;
use TableBuilderPro\Traits\Singleton;

defined('ABSPATH') || exit;

class Shortcode
{
    use Singleton;

    private const BLOCK_TYPES = [
        'tablebuilder/data-table',
        'tablebuilder/post-table',
    ];

    protected function __construct()
    {
        add_filter('tablekit/block_names',  [$this, 'register_block_names']);
        add_filter('tablekit/render_block', [$this, 'handle_render'], 10, 5);
    }

    public function register_block_names(array $names): array
    {
        return array_merge($names, self::BLOCK_TYPES);
    }

    public function handle_render($output, array $block, array $atts, array $ids, string $content): ?string
    {
        $block_name = $block['blockName'] ?? '';
        if (!$this->is_supported_block($block_name)) {
            return null;
        }

        $block = $this->apply_overrides($block, $atts);
        $this->enqueue_assets($block_name);

        $css      = ShortcodeUtils::collect_block_css($block);
        $block_id = $block['attrs']['blockID'] ?? '';
        $style    = ($css && $block_id)
            ? '<style id="tb-' . esc_attr($block_id) . '">' . $css . '</style>'
            : '';

        $rendered = (new \WP_Block($block))->render();

        return $style . $rendered . $this->get_elementor_init_script($block_name);
    }

    private function is_supported_block(string $block_name): bool
    {
        return in_array($block_name, self::BLOCK_TYPES, true);
    }

    private function get_elementor_init_script(string $block_name): string
    {
        if (!$this->is_supported_block($block_name)) {
            return '';
        }

        return ShortcodeUtils::get_elementor_init_script();
    }

    private function apply_overrides(array $block, array $atts): array
    {
        $json = ShortcodeUtils::decode_json($atts['attrs_json'] ?? '');
        if ($json) {
            $block['attrs'] = array_replace_recursive($block['attrs'] ?? [], $json);
        }

        if (!empty($atts['class'])) {
            $block['attrs']['blockClass'] = trim(
                ($block['attrs']['blockClass'] ?? '') . ' ' . sanitize_html_class($atts['class'])
            );
        }

        return $block;
    }

    private function enqueue_assets(string $block_name): void
    {
        static $enqueued = [];
        static $frontend_enqueued = false;

        if (isset($enqueued[$block_name])) {
            return;
        }

        $enqueued[$block_name] = true;
        ShortcodeUtils::enqueue_block_assets($block_name);

        if (! $frontend_enqueued) {
            $frontend_enqueued = true;
            Enqueue::instance()->enqueue_frontend_assets();
        }
    }
}
