<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\V1;

use App\Domain\Blog\ArticleAccess;
use App\Http\Controllers\Controller;
use App\Models\Article;
use App\Settings\BlogSettings;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class ArticleController extends Controller
{
    public function index(Request $request, BlogSettings $blog): JsonResponse
    {
        $perPage = max(1, min(50, $request->integer('per_page') ?: $blog->posts_per_page));

        $articles = Article::query()
            ->with(['category:id,name', 'user:id,name,username', 'tags:id,name'])
            ->visible()
            ->published()
            ->orderByDesc('stick')
            ->orderByDesc('published_at')
            ->paginate($perPage);

        return response()->json([
            'data' => $articles->getCollection()->map(fn (Article $article) => $this->summary($article))->values(),
            'meta' => [
                'current_page' => $articles->currentPage(),
                'last_page' => $articles->lastPage(),
                'per_page' => $articles->perPage(),
                'total' => $articles->total(),
            ],
        ]);
    }

    public function show(int $id, ArticleAccess $access): JsonResponse
    {
        $article = Article::query()
            ->with(['category:id,name', 'user:id,name,username', 'tags:id,name'])
            ->visible()
            ->published()
            ->findOrFail($id);

        // Anonymous API: never pass a user (purchased/admin full text is Web-only this phase).
        $decision = $access->resolve($article, null, []);

        $payload = [
            ...$this->summary($article),
            'content_format' => $article->content_format,
            'keywords' => $article->keywords,
            'access' => [
                'status' => $decision->status,
                'message' => $decision->message,
                'checkout_url' => $decision->checkoutUrl,
            ],
        ];

        if ($decision->isAllow()) {
            $payload['content'] = $article->content;
            $payload['content_html'] = $article->renderedHtml();
        } else {
            $payload['content'] = null;
            $payload['content_html'] = $access->publicHtml($article, $decision);
            $payload['teaser_html'] = $payload['content_html'];
        }

        return response()->json(['data' => $payload]);
    }

    /**
     * @return array<string, mixed>
     */
    protected function summary(Article $article): array
    {
        return [
            'id' => $article->id,
            'title' => $article->title,
            'slug' => $article->slug,
            'description' => $article->description,
            'published_at' => optional($article->published_at)?->toIso8601String(),
            'views' => $article->views,
            'stick' => (bool) $article->stick,
            'url' => url('/show-'.$article->id.'.shtml'),
            'category' => $article->category ? [
                'id' => $article->category->id,
                'name' => $article->category->name,
            ] : null,
            'author' => $article->user ? [
                'id' => $article->user->id,
                'name' => $article->user->name,
                'username' => $article->user->username,
            ] : null,
            'tags' => $article->tags->map(fn ($tag) => [
                'id' => $tag->id,
                'name' => $tag->name,
            ])->values(),
        ];
    }
}
