<?php
/**
 * @package     MefisAssetBridge
 * @subpackage  Joomla_System_Plugin
 *
 * @copyright   Copyright (C) 2025 Goran Usljebrka. All rights reserved.
 * @license     Proprietary — No resale or incorporation into other projects without explicit written permission. see LICENSE.txt
 */

namespace Mefi\Plugin\System\MefisAssetBridge\Ajax;

defined('_JEXEC') or die;

use Joomla\CMS\Input\Input;
use MefisAssetBridgeCore\Api\ApiFactory;

/**
 * Preview AJAX handler
 *
 * @since  1.0.0
 */
class Preview extends BaseHandler
{
    /**
     * Execute the handler - Get assets from the API
     *
     * @param   ApiFactory  $apiFactory  The API factory
     * @param   Input       $input       Input object
     *
     * @return  array       Response data with assets
     *
     * @throws  \Exception  On error
     */
    public function execute(ApiFactory $apiFactory, Input $input): array
    {
        $rawData = file_get_contents('php://input');
        if(empty($rawData)) {
            return $this->createErrorResponse('No data provided', 400);
        }
        $decodedJson = json_decode($rawData, true);
        if (json_last_error() !== JSON_ERROR_NONE || !isset($decodedJson['assetData'])) {
            return $this->createErrorResponse('Invalid JSON data', 400);
        }

        $jsonInfo = [];
        array_walk_recursive($decodedJson['assetData'], function (&$item, $key) use (&$jsonInfo): void {
            if ($key === 'type' && is_string($item)) {
                if (!isset($jsonInfo[$item])) {
                    $jsonInfo[$item] = 1;
                } else {
                    $jsonInfo[$item]++;
                }
            }
        });
        $error = '';
        if (isset($decodedJson['website']) && $decodedJson['website'] !== 'local') {
            $websiteInput = trim((string) $decodedJson['website']);
            if (preg_match('#^https?://#i', $websiteInput)) {
                $websiteBase = rtrim($websiteInput, '/');
            } else {
                $websiteBase = 'https://' . rtrim($websiteInput, '/');
            }

            array_walk_recursive($decodedJson['assetData'], function (&$item, $key) use ($websiteBase): void {
                if ($key !== 'image' || !is_string($item) || $item === '') {
                    return;
                }

                $item = trim($item);

                if (preg_match('#^(data:|blob:|mailto:|javascript:)#i', $item)) {
                    return;
                }

                if (strpos($item, '//') === 0) {
                    $scheme = parse_url($websiteBase, PHP_URL_SCHEME) ?: 'https';
                    $item = $scheme . ':' . $item;
                }

                if (filter_var($item, FILTER_VALIDATE_URL)) {
                    $parsed = parse_url($item);
                    if ($parsed !== false) {
                        $path = isset($parsed['path']) ? $parsed['path'] : '';
                        $query = isset($parsed['query']) ? '?' . $parsed['query'] : '';
                        $fragment = isset($parsed['fragment']) ? '#' . $parsed['fragment'] : '';
                        $item = $websiteBase . '/' . ltrim($path, '/') . $query . $fragment;
                    }
                } else {

                    $item = preg_replace('#^\./#', '', $item);
                    $item = $websiteBase . '/' . ltrim($item, '/');
                }
            });
        }

        $disableModulePositions = function (&$node) use (&$disableModulePositions): void {
            if (!is_array($node)) {
                return;
            }

            if (isset($node['type']) && is_string($node['type']) && $node['type'] === 'module_position') {
                if (!isset($node['props']) || !is_array($node['props'])) {
                    $node['props'] = [];
                }
                $node['props']['status'] = 'disabled';
            }

            // Recurse into child arrays
            foreach ($node as &$child) {
                if (is_array($child)) {
                    $disableModulePositions($child);
                }
            }
        };

        $disableModulePositions($decodedJson['assetData']);

        $json = json_encode($decodedJson['assetData']);

        $yoothemeBootstrap = JPATH_SITE . '/templates/yootheme/bootstrap.php';

        if (!file_exists($yoothemeBootstrap)) {
            throw new \RuntimeException('YOOtheme bootstrap not found: ' . $yoothemeBootstrap);
        }

        /** @var \YOOtheme\Application $yooapp */
        $yooapp = require $yoothemeBootstrap;
        $yooapp->load('~theme/packages/builder/bootstrap.php');
        $yooapp->load('~theme/packages/theme/bootstrap.php');

        try {
        /** @var \YOOtheme\Builder $builder */
        $builder = $yooapp(\YOOtheme\Builder::class);

        $html = $builder->render($json, ['prefix' => 'el', 'context' => 'render']);

        } catch (\Throwable $th) {
            $error = $th->getMessage();

        }

        if(empty($html)) {
            // Build a readable stats summary of detected asset types.
            $html = 'No preview available.';
            $html .= '<br /><strong>Asset types detected:</strong><br />';

            if (!empty($jsonInfo)) {
                // Sort descending by count for readability
                arsort($jsonInfo);
                $parts = [];
                foreach ($jsonInfo as $type => $count) {
                    // Escape type for safe HTML output
                    $escapedType = htmlspecialchars((string) $type, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
                    $parts[] = $escapedType . ': ' . (int) $count;
                }
                $html .= implode('<br />', $parts);
            } else {
                $html .= 'No asset type information available.';
            }

            if($error)
                $html .= '<br /><small>Error: ' . htmlspecialchars($error, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '</small>';
        }

        return $this->createSuccessResponse('', $html);
    }
}