<?php

namespace idoit\Module\SyneticsJdisc\Controller;

use Exception;
use idoit\Component\Logger;
use idoit\Response\IdoitResponse;
use isys_application;
use isys_component_template;
use isys_component_template_language_manager;
use isys_module_synetics_jdisc;
use Symfony\Component\HttpFoundation\Response;

class IndexController
{
    public isys_component_template $template;
    public isys_component_template_language_manager $language;

    public function __construct() {
        $this->template = isys_application::instance()->container->get('template');
        $this->language = isys_application::instance()->container->get('language');
    }

    public function page(string $slug = ''): Response
    {
        // Assign some necessary data.
        $this->template
            ->assign('jsDirectory', isys_module_synetics_jdisc::getWwwPath() . 'js/')
            ->assign('slug', $slug)
            ->assign('title', 'JDisc');

        return (new IdoitResponse(isys_module_synetics_jdisc::getPath() . 'templates/iframe.tpl'))->showBreadcrumb(false)->showNavbar(false);
    }

    public function iframe(): Response
    {
        $container = isys_application::instance()->container;

        $logger = $container->get('logger');

        $assets = $this->getViteAssets($logger);

        if (isset($assets['error'])) {
            $this->template->assign('errorMessage', $assets['error']);
            return new Response($this->template->fetch(isys_module_synetics_jdisc::getPath() . 'templates/error.tpl'));
        }

        // Assign some necessary data. @todo add authorization
        $this->template
            ->assign('scriptFile', $assets['scriptFile'])
            ->assign('styleFiles', $assets['styleFiles'])
            ->assign('jsDirectory', isys_module_synetics_jdisc::getWwwPath() . 'js/');
        return new Response($this->template->fetch(isys_module_synetics_jdisc::getPath() . 'templates/index.tpl'));
    }

    /**
     * @param Logger $logger
     * @return array
     * @throws Exception
     */
    private function getViteAssets(Logger $logger): array
    {
        $genericErrorMessage = $this->language->get('LC__MODULE__JDISC__ERROR__FRONTEND_NOT_AVAILABLE');

        $distPath = isys_module_synetics_jdisc::getWwwPath() . 'react/dist/';
        $manifestPath = isys_module_synetics_jdisc::getPath() . 'react/dist/.vite/manifest.json';

        if (!file_exists($manifestPath)) {
            $logger->error('JDisc Module: Vite manifest file not found at ' . $manifestPath . '. Please run the frontend build process.');
            return ['error' => $genericErrorMessage];
        }

        $manifestJson = file_get_contents($manifestPath);
        if ($manifestJson === false) {
            $logger->error('JDisc Module: Could not read Vite manifest file at ' . $manifestPath);
            return ['error' => $genericErrorMessage];
        }

        $manifest = json_decode($manifestJson, true);
        if ($manifest === null) {
            $logger->error('JDisc Module: Could not parse Vite manifest file. The JSON is invalid. Path: ' . $manifestPath);
            return ['error' => $genericErrorMessage];
        }

        $entryPoint = 'src/main.tsx';
        if (isset($manifest[$entryPoint])) {
            $entry      = $manifest[$entryPoint];
            $scriptFile = $distPath . $entry['file'];
            $styleFiles = [];
            $cssFiles   = [];

            // get css from imports (e.g. the vendor chunk)
            if (isset($entry['imports'])) {
                foreach ($entry['imports'] as $importKey) {
                    if (isset($manifest[$importKey]) && isset($manifest[$importKey]['css'])) {
                        $cssFiles = array_merge($cssFiles, $manifest[$importKey]['css']);
                    }
                }
            }

            // get css from entry point
            if (isset($entry['css'])) {
                $cssFiles = array_merge($cssFiles, $entry['css']);
            }

            foreach (array_unique($cssFiles) as $cssFileName) {
                $styleFiles[] = $distPath . $cssFileName;
            }

            return [
                'scriptFile' => $scriptFile,
                'styleFiles' => $styleFiles
            ];
        }

        $logger->error('JDisc Module: Entry point ' . $entryPoint . ' not found in Vite manifest. Please check your Vite configuration.');
        return ['error' => $genericErrorMessage];
    }
}
