<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api;

use App\Blog\Services\PostContentRenderer;
use App\Models\Category;
use App\Models\Comment;
use App\Models\Post;
use App\Models\Setting;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Spatie\Tags\Tag;

/**
 * 对外 API：为小程序/第三方平台提供数据与评论能力。
 */
class ApiController extends Controller
{
    /**
     * 站点信息。
     *
     * @response array{name: string, description: string, icp: string, url: string}
     */
    public function site(): JsonResponse
    {
        return response()->json([
            'name' => Setting::get('site_name', config('blog.name')),
            'description' => Setting::get('site_description', config('blog.description')),
            'icp' => Setting::get('site_icp', config('blog.icp')),
            'url' => url('/'),
            'rss' => route('feed.rss'),
            'api_version' => '1.0',
        ]);
    }

    /**
     * 文章列表（分页）。
     *
     * @queryParam page int 页码 Example: 1
     * @queryParam per_page int 每页数量（默认 10，最大 50）Example: 10
     * @queryParam category string 分类 slug Example: tech
     * @queryParam tag string 标签名 Example: laravel
     * @queryParam q string 关键词搜索 Example: laravel
     *
     * @response array{data: array, meta: array}
     */
    public function posts(Request $request): JsonResponse
    {
        $query = Post::published()->with('category:id,name,slug')->with('tags:id,name');

        if ($category = $request->query('category')) {
            $query->whereHas('category', fn ($q) => $q->where('slug', $category)->orWhere('name', $category));
        }

        if ($tag = $request->query('tag')) {
            $query->whereHas('tags', fn ($q) => $q->where('name', $tag)->orWhere('slug', $tag));
        }

        if ($q = trim((string) $request->query('q', ''))) {
            $query->search($q);
        }

        $perPage = min((int) $request->query('per_page', 10), 50);

        $posts = $query->orderByDesc('published_at')->paginate($perPage);

        return response()->json([
            'data' => $posts->through(fn (Post $post) => $this->postSummary($post))->items(),
            'meta' => [
                'current_page' => $posts->currentPage(),
                'last_page' => $posts->lastPage(),
                'per_page' => $posts->perPage(),
                'total' => $posts->total(),
            ],
        ]);
    }

    /**
     * 文章详情。
     *
     * @urlParam slug string required 文章 slug 或 ID Example: post-1
     *
     * @response array{id: int, title: string, content_html: string, ...}
     */
    public function post(string $slug): JsonResponse
    {
        $post = Post::query()
            ->where('slug', $slug)
            ->orWhere('id', (int) $slug)
            ->first();

        abort_unless($post && $post->status === 'published', 404);

        // 会员/付费内容过滤与前台一致
        $contentHtml = app(PostContentRenderer::class)->render($post);

        return response()->json([
            'id' => $post->id,
            'title' => $post->title,
            'slug' => $post->slug,
            'excerpt' => $post->excerpt_or_fallback,
            'content_html' => $contentHtml,
            'content_format' => $post->content_format,
            'keywords' => $post->keywords,
            'category' => $post->category ? ['id' => $post->category->id, 'name' => $post->category->name, 'slug' => $post->category->slug] : null,
            'tags' => $post->tags->map(fn ($t) => ['id' => $t->id, 'name' => $t->name, 'slug' => $t->slug])->values(),
            'views' => $post->views,
            'comment_count' => $post->comment_count,
            'published_at' => $post->published_at?->toIso8601String(),
            'url' => route('posts.show', $post->slug ?: $post->id),
        ]);
    }

    /**
     * 分类列表。
     *
     * @response array{data: array}
     */
    public function categories(): JsonResponse
    {
        return response()->json([
            'data' => Category::query()->orderBy('display_order')->orderBy('name')->get(['id', 'name', 'slug', 'post_count']),
        ]);
    }

    /**
     * 标签列表。
     *
     * @response array{data: array}
     */
    public function tags(): JsonResponse
    {
        $counts = DB::table('taggables')
            ->selectRaw('tag_id, COUNT(*) as total')
            ->where('taggable_type', Post::class)
            ->groupBy('tag_id')
            ->pluck('total', 'tag_id');

        return response()->json([
            'data' => Tag::query()->where('type', 'post')->get()
                ->map(fn (Tag $tag) => [
                    'id' => $tag->id,
                    'name' => $tag->name,
                    'slug' => $tag->slug,
                    'post_count' => (int) ($counts[$tag->id] ?? 0),
                ])
                ->values(),
        ]);
    }

    /**
     * 提交评论（公开）。
     *
     * @bodyParam author_name string required 昵称 Example: 访客
     * @bodyParam author_email string 邮箱 Example: guest@example.com
     * @bodyParam author_url string 网站 Example: https://example.com
     * @bodyParam content string required 评论内容 Example: 写得很好
     * @bodyParam website string 蜜罐字段，留空 Example:
     */
    public function storeComment(Request $request): JsonResponse
    {
        $data = $request->validate([
            'post_id' => ['required', 'integer', 'exists:posts,id'],
            'author_name' => ['required', 'string', 'max:50'],
            'author_email' => ['nullable', 'email', 'max:255'],
            'author_url' => ['nullable', 'url', 'max:255'],
            'content' => ['required', 'string', 'min:'.(int) Setting::get('comment_min_len', 2), 'max:'.(int) Setting::get('comment_max_len', 6000)],
        ]);

        // 蜜罐
        if ($request->filled('website')) {
            return response()->json(['message' => '提交失败'], 422);
        }

        $post = Post::findOrFail((int) $data['post_id']);

        if ($post->status !== 'published' || $post->close_comment) {
            return response()->json(['message' => '该文章不允许评论'], 422);
        }

        $status = (int) Setting::get('comment_audit', 0) === 1 ? 'pending' : 'published';

        $comment = $post->comments()->create([
            'user_id' => $request->user()?->id,
            'author_name' => $data['author_name'],
            'author_email' => $data['author_email'] ?? null,
            'author_url' => $data['author_url'] ?? null,
            'content' => $data['content'],
            'ip' => $request->ip(),
            'status' => $status,
        ]);

        if ($status === 'published') {
            $post->increment('comment_count');
        }

        app(\App\Blog\Support\PluginManager::class)->doAction('comment.created', $comment);

        return response()->json([
            'message' => $status === 'published' ? '评论已发布' : '评论已提交，等待审核',
            'data' => ['id' => $comment->id, 'status' => $status],
        ], 201);
    }

    /**
     * 当前登录用户（需 Bearer Token）。
     *
     * @authenticated
     *
     * @response array{id: int, name: string, email: string, roles: array}
     */
    public function me(Request $request): JsonResponse
    {
        $user = $request->user();

        return response()->json([
            'id' => $user->id,
            'name' => $user->name,
            'email' => $user->email,
            'roles' => $user->getRoleNames(),
            'url' => $user->url,
        ]);
    }

    private function postSummary(Post $post): array
    {
        return [
            'id' => $post->id,
            'title' => $post->title,
            'slug' => $post->slug,
            'excerpt' => $post->excerpt_or_fallback,
            'category' => $post->category?->name,
            'tags' => $post->tags->pluck('name')->values(),
            'views' => $post->views,
            'comment_count' => $post->comment_count,
            'published_at' => $post->published_at?->toIso8601String(),
            'url' => route('posts.show', $post->slug ?: $post->id),
        ];
    }
}
