<?php

declare(strict_types=1);

namespace App\Http\Controllers\RSS;

use App\Http\Controllers\Controller;
use App\Models\Artwork;
use App\Services\ContentTypes\ContentTypeSlugResolver;
use App\Services\RSS\RSSFeedBuilder;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Cache;

/**
 * ExploreFeedController
 *
 * Powers the /rss/explore/* feeds (spec §3.3).
 *
 * GET /rss/explore/{type}            → latest by content type
 * GET /rss/explore/{type}/{mode}     → sorted by mode (trending|latest|best)
 *
 * Valid types:  artworks | wallpapers | skins | photography | other
 * Valid modes:  trending | latest | best
 */
final class ExploreFeedController extends Controller
{
    private const SORT_TTL = [
        'trending' => 600,
        'best'     => 600,
        'latest'   => 300,
    ];

    public function __construct(
        private readonly RSSFeedBuilder $builder,
        private readonly ContentTypeSlugResolver $contentTypeResolver,
    ) {}

    /** /rss/explore/{type} — defaults to latest */
    public function byType(Request $request, string $type): Response|RedirectResponse
    {
        return $this->feed($request, $type, 'latest');
    }

    /** /rss/explore/{type}/{mode} */
    public function byTypeMode(Request $request, string $type, string $mode): Response|RedirectResponse
    {
        return $this->feed($request, $type, $mode);
    }

    // ─────────────────────────────────────────────────────────────────────────

    private function feed(Request $request, string $type, string $mode): Response|RedirectResponse
    {
        $resolution = $this->contentTypeResolver->resolve($type, allowVirtual: true);

        if (! $resolution->found()) {
            abort(404);
        }

        $mode    = in_array($mode, ['trending', 'latest', 'best'], true) ? $mode : 'latest';
        $resolvedType = $resolution->isVirtual ? 'artworks' : strtolower((string) $resolution->contentType?->slug);

        if ($resolution->requiresRedirect()) {
            return redirect()->to(url('/rss/explore/' . $resolvedType . ($mode !== 'latest' ? '/' . $mode : '')) . ($request->getQueryString() ? ('?' . $request->getQueryString()) : ''), 301);
        }

        $ttl     = self::SORT_TTL[$mode] ?? 300;
        $feedUrl = url('/rss/explore/' . $resolvedType . ($mode !== 'latest' ? '/' . $mode : ''));
        $label   = $resolution->isVirtual
            ? 'All Artworks'
            : ($resolution->contentType?->name ?? ucfirst(str_replace('-', ' ', $resolvedType)));

        $artworks = Cache::remember("rss:explore:{$resolvedType}:{$mode}", $ttl, function () use ($resolution, $mode) {
            $contentType = $resolution->contentType;

            $query = Artwork::public()->published()
                ->with(['user:id,username', 'categories:id,name,slug,content_type_id']);

            if (! $resolution->isVirtual && $contentType) {
                $query->whereHas('categories', fn ($q) =>
                    $q->where('content_type_id', $contentType->id)
                );
            }

            return match ($mode) {
                'trending' => $query
                    ->leftJoin('artwork_stats', 'artwork_stats.artwork_id', '=', 'artworks.id')
                    ->orderByDesc('artwork_stats.trending_score_7d')
                    ->orderByDesc('artworks.published_at')
                    ->select('artworks.*')
                    ->limit(RSSFeedBuilder::FEED_LIMIT)
                    ->get(),

                'best'     => $query
                    ->leftJoin('artwork_stats', 'artwork_stats.artwork_id', '=', 'artworks.id')
                    ->orderByDesc('artwork_stats.favorites')
                    ->orderByDesc('artwork_stats.downloads')
                    ->select('artworks.*')
                    ->limit(RSSFeedBuilder::FEED_LIMIT)
                    ->get(),

                default    => $query
                    ->latest('artworks.published_at')
                    ->limit(RSSFeedBuilder::FEED_LIMIT)
                    ->get(),
            };
        });

        $modeLabel = match ($mode) {
            'trending' => 'Trending',
            'best'     => 'Best',
            default    => 'Latest',
        };

        return $this->builder->buildFromArtworks(
            "{$modeLabel} {$label}",
            "{$modeLabel} {$label} artworks on Skinbase.",
            $feedUrl,
            $artworks,
        );
    }
}
