<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use ZipArchive;

class ContentUploadController extends Controller
{
    protected int $maxSize = 10 * 1024 * 1024; // 10 Mo

    /**
     * Upload et installe un thème depuis un fichier ZIP.
     */
    public function uploadTheme(Request $request)
    {
        $request->validate([
            'zip' => 'required|file|mimes:zip|max:10240',
        ], [
            'zip.required' => 'Veuillez sélectionner un fichier ZIP.',
            'zip.mimes' => 'Le fichier doit être au format ZIP.',
            'zip.max' => 'Le fichier ne doit pas dépasser 10 Mo.',
        ]);

        $zip = $request->file('zip');
        $result = $this->extractAndInstall($zip->getRealPath(), 'theme');

        if ($result['success']) {
            return back()->with('success', $result['message']);
        }

        return back()->withErrors(['zip' => $result['message']]);
    }

    /**
     * Upload et installe un plugin depuis un fichier ZIP.
     */
    public function uploadPlugin(Request $request)
    {
        $request->validate([
            'zip' => 'required|file|mimes:zip|max:10240',
        ], [
            'zip.required' => 'Veuillez sélectionner un fichier ZIP.',
            'zip.mimes' => 'Le fichier doit être au format ZIP.',
            'zip.max' => 'Le fichier ne doit pas dépasser 10 Mo.',
        ]);

        $zip = $request->file('zip');
        $result = $this->extractAndInstall($zip->getRealPath(), 'plugin');

        if ($result['success']) {
            return back()->with('success', $result['message']);
        }

        return back()->withErrors(['zip' => $result['message']]);
    }

    protected function extractAndInstall(string $zipPath, string $type): array
    {
        $configFile = $type === 'theme' ? 'theme.json' : 'plugin.json';
        $basePath = $type === 'theme'
            ? config('cms.custom_themes_path')
            : config('cms.custom_plugins_path');

        if (! $basePath || ! is_dir($basePath)) {
            File::ensureDirectoryExists($basePath);
        }

        $zip = new ZipArchive;
        if ($zip->open($zipPath) !== true) {
            return ['success' => false, 'message' => 'Impossible d\'ouvrir le fichier ZIP.'];
        }

        $tempDir = sys_get_temp_dir().'/cms_upload_'.uniqid();
        File::ensureDirectoryExists($tempDir);

        $zip->extractTo($tempDir);
        $zip->close();

        try {
            $rootContents = scandir($tempDir);
            $rootContents = array_diff($rootContents, ['.', '..']);

            // Cas 1 : un seul dossier à la racine (ex: mon-theme/ ou mon-plugin/)
            if (count($rootContents) === 1) {
                $single = reset($rootContents);
                $singlePath = $tempDir.'/'.$single;
                if (is_dir($singlePath)) {
                    $extractRoot = $singlePath;
                } else {
                    $extractRoot = $tempDir;
                }
            } else {
                $extractRoot = $tempDir;
            }

            $configPath = $extractRoot.'/'.$configFile;
            if (! file_exists($configPath)) {
                File::deleteDirectory($tempDir);

                return [
                    'success' => false,
                    'message' => "Le fichier {$configFile} est introuvable dans le ZIP. Structure attendue : un dossier contenant {$configFile} à la racine.",
                ];
            }

            $config = json_decode(file_get_contents($configPath), true);
            if (! $config || empty($config['slug'] ?? null)) {
                File::deleteDirectory($tempDir);

                return [
                    'success' => false,
                    'message' => "Le fichier {$configFile} doit contenir un champ \"slug\" valide.",
                ];
            }

            $slug = preg_replace('/[^a-z0-9\-]/', '', $config['slug']);
            if ($slug === '') {
                File::deleteDirectory($tempDir);

                return ['success' => false, 'message' => 'Le slug doit contenir uniquement des lettres minuscules, chiffres et tirets.'];
            }

            // Blocage : plugin marketplace copié (même avec slug modifié)
            if ($type === 'plugin') {
                $uploadFingerprint = $this->computePluginFingerprint($extractRoot);
                $marketplaceSlugs = array_column(config('marketplace_catalog.plugins', []), 'slug');
                $corePluginsPath = base_path('plugins');
                foreach ($marketplaceSlugs as $mpSlug) {
                    $mpPath = $corePluginsPath.'/'.$mpSlug;
                    if (is_dir($mpPath) && file_exists($mpPath.'/plugin.json')) {
                        $mpFingerprint = $this->computePluginFingerprint($mpPath);
                        if ($uploadFingerprint === $mpFingerprint) {
                            File::deleteDirectory($tempDir);

                            return [
                                'success' => false,
                                'message' => 'Ce plugin est disponible via le marketplace. Achetez-le pour l\'activer.',
                            ];
                        }
                    }
                }
            }

            $targetDir = $basePath.'/'.$slug;

            if ($type === 'theme') {
                if (! file_exists($extractRoot.'/home.blade.php')) {
                    File::deleteDirectory($tempDir);

                    return ['success' => false, 'message' => 'Le thème doit contenir au minimum home.blade.php.'];
                }
            }

            $config['source'] = 'custom';
            if (! isset($config['name'])) {
                $config['name'] = ucfirst(str_replace('-', ' ', $slug));
            }
            file_put_contents($configPath, json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));

            if (is_dir($targetDir)) {
                File::deleteDirectory($targetDir);
            }
            File::copyDirectory($extractRoot, $targetDir);

            // Plugins : copier les sections personnalisées vers content/partials/sections/
            if ($type === 'plugin') {
                $sectionsDir = $targetDir.'/sections';
                if (is_dir($sectionsDir)) {
                    $partialsPath = dirname($basePath).'/partials/sections';
                    File::ensureDirectoryExists($partialsPath);
                    foreach (File::files($sectionsDir) as $file) {
                        if (str_ends_with($file->getFilename(), '.blade.php')) {
                            File::copy($file->getPathname(), $partialsPath.'/'.$file->getFilename());
                        }
                    }
                }
            }

            File::deleteDirectory($tempDir);

            $name = $config['name'] ?? $slug;

            return [
                'success' => true,
                'message' => $type === 'theme'
                    ? "Thème « {$name} » installé. Vous pouvez l'activer dans Apparence."
                    : "Plugin « {$name} » installé et activé.",
            ];
        } catch (\Throwable $e) {
            if (is_dir($tempDir)) {
                File::deleteDirectory($tempDir);
            }

            return ['success' => false, 'message' => 'Erreur lors de l\'installation : '.$e->getMessage()];
        }
    }

    /**
     * Empreinte du plugin (hash du contenu normalisé, slug/name exclus).
     */
    protected function computePluginFingerprint(string $pluginDir): string
    {
        $configPath = $pluginDir.'/plugin.json';
        if (! file_exists($configPath)) {
            return '';
        }
        $config = json_decode(file_get_contents($configPath), true);
        if (! $config) {
            return '';
        }
        unset($config['slug'], $config['name']);

        return hash('sha256', json_encode($config, JSON_UNESCAPED_UNICODE));
    }
}
