<?php

use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage;

Route::get('/', function () {
    return view('welcome');
});

/*
|--------------------------------------------------------------------------
| Storage file serving – works on shared hosting without symlinks
|--------------------------------------------------------------------------
| On shared hosting (Truehost, cPanel, etc.) php artisan storage:link
| may fail because the host blocks symlinks. This route reads files
| directly from storage/app/public and streams them to the browser
| with proper MIME headers, caching, and CORS.
*/
Route::get('/storage/{path}', function (string $path) {
    $disk = Storage::disk('public');

    if (!$disk->exists($path)) {
        abort(404, 'File not found');
    }

    try {
        $mimeType = $disk->mimeType($path);
    } catch (\Throwable) {
        $mimeType = null;
    }
    $mimeType ??= match (strtolower(pathinfo($path, PATHINFO_EXTENSION))) {
        'jpg', 'jpeg' => 'image/jpeg',
        'png' => 'image/png',
        'gif' => 'image/gif',
        'webp' => 'image/webp',
        'svg' => 'image/svg+xml',
        'pdf' => 'application/pdf',
        'json' => 'application/json',
        'txt', 'log' => 'text/plain; charset=UTF-8',
        'csv' => 'text/csv; charset=UTF-8',
        default => 'application/octet-stream',
    };
    $size      = $disk->size($path);
    $lastMod   = $disk->lastModified($path);
    $etag      = md5($path . $lastMod . $size);

    // Honour If-None-Match for 304 responses
    $requestEtag = request()->header('If-None-Match');
    if ($requestEtag && trim($requestEtag, '"') === $etag) {
        return response()->noContent(304);
    }

    // Stream the file to keep memory low for large images
    $stream = $disk->readStream($path);

    return response()->stream(function () use ($stream) {
        fpassthru($stream);
        if (is_resource($stream)) {
            fclose($stream);
        }
    }, 200, [
        'Content-Type'        => $mimeType,
        'Content-Length'      => $size,
        'ETag'                => '"' . $etag . '"',
        'Cache-Control'       => 'public, max-age=31536000, immutable',
        'Access-Control-Allow-Origin' => '*',
    ]);
})->where('path', '.*');

Route::get('/files/{path}', function (string $path) {
    $disk = Storage::disk('public');

    if (!$disk->exists($path)) {
        abort(404, 'File not found');
    }

    try {
        $mimeType = $disk->mimeType($path);
    } catch (\Throwable) {
        $mimeType = null;
    }
    $mimeType ??= match (strtolower(pathinfo($path, PATHINFO_EXTENSION))) {
        'jpg', 'jpeg' => 'image/jpeg',
        'png' => 'image/png',
        'gif' => 'image/gif',
        'webp' => 'image/webp',
        'svg' => 'image/svg+xml',
        'pdf' => 'application/pdf',
        'json' => 'application/json',
        'txt', 'log' => 'text/plain; charset=UTF-8',
        'csv' => 'text/csv; charset=UTF-8',
        default => 'application/octet-stream',
    };
    $size      = $disk->size($path);
    $lastMod   = $disk->lastModified($path);
    $etag      = md5($path . $lastMod . $size);

    $requestEtag = request()->header('If-None-Match');
    if ($requestEtag && trim($requestEtag, '"') === $etag) {
        return response()->noContent(304);
    }

    $stream = $disk->readStream($path);

    return response()->stream(function () use ($stream) {
        fpassthru($stream);
        if (is_resource($stream)) {
            fclose($stream);
        }
    }, 200, [
        'Content-Type'        => $mimeType,
        'Content-Length'      => $size,
        'ETag'                => '"' . $etag . '"',
        'Cache-Control'       => 'public, max-age=31536000, immutable',
        'Access-Control-Allow-Origin' => '*',
    ]);
})->where('path', '.*');
