<?php

namespace App\Http\Controllers;

use App\Models\Playlist;
use App\Models\User;
use App\Models\Video;
use App\Models\VideoSlide;
use App\Services\NasSyncService;
use Illuminate\Http\Response;

/**
 * Serves image assets (thumbnails, slides, avatars, banners) with a transparent
 * NAS fallback: if the file is missing locally it is fetched from the NAS and
 * cached in the standard public storage directory before being served.
 *
 * All routes are public (no auth) so images render in emails and for guests.
 */
class MediaController extends Controller
{
    public function thumbnail(string $filename, NasSyncService $nas): Response
    {
        // New NAS-mirrored path format: "users/{username}/videos/{slug}/…"
        if (str_starts_with($filename, 'users/')) {
            $local = storage_path('app/' . $filename);

            if (! file_exists($local)) {
                @mkdir(dirname($local), 0755, true);

                // The thumbnail field stores the local relative path.
                // On NAS, thumbnails are always "thumb.webp"; try that first, then match extension.
                $video = Video::where('thumbnail', $filename)->first();
                if ($video) {
                    $dir = $nas->resolveVideoDir($video);
                    $ext = pathinfo($filename, PATHINFO_EXTENSION) ?: 'jpg';
                    foreach (["thumb.webp", "thumb.{$ext}"] as $nasFile) {
                        if ($nas->ensureLocalAsset($local, "{$dir}/{$nasFile}")) break;
                    }
                }

                // Might be a slide
                if (! file_exists($local)) {
                    $slide = VideoSlide::where('filename', $filename)->with('video')->first();
                    if ($slide && $slide->video) {
                        $dir = $nas->resolveVideoDir($slide->video);
                        $ext = pathinfo($filename, PATHINFO_EXTENSION) ?: 'jpg';
                        $nas->ensureLocalAsset($local, "{$dir}/slides/{$slide->position}.{$ext}");
                    }
                }

                // Might be a playlist thumbnail
                if (! file_exists($local)) {
                    $nas->ensureLocalAsset($local, $filename);
                }

                if (! file_exists($local)) abort(404);
            }

            return $this->fileResponse($local);
        }

        // Legacy flat filename format
        $local = storage_path('app/public/thumbnails/' . $filename);

        if (! file_exists($local)) {
            // Find the video that owns this thumbnail and pull from NAS
            $video = Video::where('thumbnail', $filename)->first();

            if ($video) {
                $dir     = $nas->resolveVideoDir($video);
                $nasPath = "{$dir}/thumb.webp";
                $nas->ensureLocalAsset($local, $nasPath);
            }

            // Not found via video — might be a slide
            if (! file_exists($local)) {
                $slide = VideoSlide::where('filename', $filename)->with('video')->first();
                if ($slide && $slide->video) {
                    $dir     = $nas->resolveVideoDir($slide->video);
                    $ext     = pathinfo($filename, PATHINFO_EXTENSION) ?: 'jpg';
                    $nasPath = "{$dir}/slides/{$slide->position}.{$ext}";
                    $nas->ensureLocalAsset($local, $nasPath);
                }
            }

            if (! file_exists($local)) {
                abort(404);
            }
        }

        return $this->fileResponse($local);
    }

    public function avatar(string $filename, NasSyncService $nas): Response
    {
        // New format: "users/{slug}/profile/avatar.{ext}"
        if (str_starts_with($filename, 'users/')) {
            $local = storage_path('app/' . $filename);

            if (! file_exists($local)) {
                @mkdir(dirname($local), 0755, true);
                $user = User::where('avatar', $filename)->first();
                if ($user) {
                    $dir = "users/{$nas->userSlug($user)}/profile";
                    $ext = pathinfo($filename, PATHINFO_EXTENSION) ?: 'webp';
                    foreach (["avatar.webp", "avatar.{$ext}"] as $nasFile) {
                        if ($nas->ensureLocalAsset($local, "{$dir}/{$nasFile}")) break;
                    }
                }
                if (! file_exists($local)) abort(404);
            }

            return $this->fileResponse($local);
        }

        // Legacy flat format
        $local = storage_path('app/public/avatars/' . $filename);

        if (! file_exists($local)) {
            $user = User::where('avatar', $filename)->first();
            if ($user) {
                $dir     = "users/{$nas->userSlug($user)}/profile";
                $nasPath = "{$dir}/avatar.webp";
                $nas->ensureLocalAsset($local, $nasPath);
            }
            if (! file_exists($local)) abort(404);
        }

        return $this->fileResponse($local);
    }

    public function banner(string $filename, NasSyncService $nas): Response
    {
        // New format: "users/{slug}/profile/cover.{ext}"
        if (str_starts_with($filename, 'users/')) {
            $local = storage_path('app/' . $filename);

            if (! file_exists($local)) {
                @mkdir(dirname($local), 0755, true);
                $user = User::where('banner', $filename)->first();
                if ($user) {
                    $dir = "users/{$nas->userSlug($user)}/profile";
                    $ext = pathinfo($filename, PATHINFO_EXTENSION) ?: 'webp';
                    foreach (["cover.webp", "cover.{$ext}"] as $nasFile) {
                        if ($nas->ensureLocalAsset($local, "{$dir}/{$nasFile}")) break;
                    }
                }
                if (! file_exists($local)) abort(404);
            }

            return $this->fileResponse($local);
        }

        // Legacy flat format
        $local = storage_path('app/public/banners/' . $filename);

        if (! file_exists($local)) {
            $user = User::where('banner', $filename)->first();
            if ($user) {
                $dir     = "users/{$nas->userSlug($user)}/profile";
                $nasPath = "{$dir}/cover.webp";
                $nas->ensureLocalAsset($local, $nasPath);
            }
            if (! file_exists($local)) abort(404);
        }

        return $this->fileResponse($local);
    }

    public function postImage(string $filename, NasSyncService $nas): Response
    {
        // New format: "users/{slug}/posts/{id}/{seq}.{ext}"
        if (str_starts_with($filename, 'users/')) {
            $local = storage_path('app/' . $filename);

            if (! file_exists($local)) {
                @mkdir(dirname($local), 0755, true);
                // NAS path is identical to the relative path stored in DB
                $nas->ensureLocalAsset($local, $filename);
                if (! file_exists($local)) abort(404);
            }

            return $this->fileResponse($local);
        }

        // Legacy flat format
        $local = storage_path('app/public/post_images/' . $filename);
        if (! file_exists($local)) abort(404);

        return $this->fileResponse($local);
    }

    public function sportsImage(string $filename, NasSyncService $nas): Response
    {
        // Format: "users/{slug}/sports/{matchId}/{key}.{ext}"
        if (str_starts_with($filename, 'users/')) {
            $local = storage_path('app/' . $filename);

            if (! file_exists($local)) {
                @mkdir(dirname($local), 0755, true);
                // NAS path is identical to the relative path stored in DB
                $nas->ensureLocalAsset($local, $filename);
                if (! file_exists($local)) abort(404);
            }

            return $this->fileResponse($local);
        }

        abort(404);
    }

    // ── Helper ────────────────────────────────────────────────────────────────

    private function fileResponse(string $path): Response
    {
        $ext  = strtolower(pathinfo($path, PATHINFO_EXTENSION));
        $mime = match ($ext) {
            'webp' => 'image/webp',
            'png'  => 'image/png',
            'gif'  => 'image/gif',
            default => 'image/jpeg',
        };

        return response(file_get_contents($path), 200, [
            'Content-Type'  => $mime,
            'Cache-Control' => 'public, max-age=86400',
            'Last-Modified' => gmdate('D, d M Y H:i:s', filemtime($path)) . ' GMT',
        ]);
    }
}
