<?php

namespace App\Http\Controllers;

use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Artisan;

class StorageLinkController extends Controller
{
    /**
     * Crea el enlace simbólico public/storage → storage/app/public (equivalente a artisan storage:link).
     * Idempotente: si el enlace ya existe, responde éxito sin error.
     */
    public function __invoke(): JsonResponse
    {
        $publicStorage = public_path('storage');
        $target = storage_path('app/public');

        if ($this->linkAlreadyUsable($publicStorage, $target)) {
            return response()->json([
                'success' => true,
                'linked' => true,
                'message' => 'El enlace public/storage ya existe y apunta al storage público.',
                'path' => $publicStorage,
            ]);
        }

        try {
            Artisan::call('storage:link', $this->linkExists($publicStorage) ? ['--force' => true] : []);
            $output = trim(Artisan::output());

            return response()->json([
                'success' => true,
                'linked' => true,
                'message' => 'Enlace simbólico de storage creado correctamente.',
                'output' => $output !== '' ? $output : null,
                'path' => $publicStorage,
            ]);
        } catch (\Throwable $e) {
            if ($this->linkAlreadyUsable($publicStorage, $target)) {
                return response()->json([
                    'success' => true,
                    'linked' => true,
                    'message' => 'El enlace public/storage ya estaba disponible.',
                    'path' => $publicStorage,
                ]);
            }

            return response()->json([
                'success' => false,
                'linked' => false,
                'message' => 'No se pudo crear el enlace de storage: '.$e->getMessage(),
            ], 500);
        }
    }

    private function linkExists(string $path): bool
    {
        return file_exists($path) || is_link($path);
    }

    private function linkAlreadyUsable(string $link, string $target): bool
    {
        if (! $this->linkExists($link)) {
            return false;
        }

        $linkReal = realpath($link);
        $targetReal = realpath($target);

        return $linkReal !== false
            && $targetReal !== false
            && $linkReal === $targetReal;
    }
}
