<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\BlogCategory;
use App\Models\BlogComment;
use App\Models\BlogPost;
use App\Models\PageContent;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class CmsController extends Controller
{
    // ── Page Contents (public) ───────────────────────────────────────────────

    public function getPage(string $page): JsonResponse
    {
        return response()->json(['data' => PageContent::getPage($page)]);
    }

    // ── Page Contents (admin) ────────────────────────────────────────────────

    public function updatePage(Request $request, string $page): JsonResponse
    {
        $data = $request->validate([
            'fields'         => 'required|array',
            'fields.*.key'   => 'required|string',
            'fields.*.value' => 'nullable|string',
            'fields.*.type'  => 'in:text,html,json',
        ]);

        foreach ($data['fields'] as $field) {
            PageContent::updateOrCreate(
                ['page' => $page, 'key' => $field['key']],
                ['value' => $field['value'] ?? '', 'type' => $field['type'] ?? 'text']
            );
        }

        return response()->json(['data' => PageContent::getPage($page)]);
    }

    // ── Blog Categories ──────────────────────────────────────────────────────

    public function categories(): JsonResponse
    {
        return response()->json(['data' => BlogCategory::withCount('posts')->orderBy('name')->get()]);
    }

    public function createCategory(Request $request): JsonResponse
    {
        $data = $request->validate(['name' => 'required|string|max:100']);
        $cat  = BlogCategory::create($data);
        return response()->json(['data' => $cat], 201);
    }

    public function updateCategory(Request $request, int $id): JsonResponse
    {
        $cat  = BlogCategory::findOrFail($id);
        $data = $request->validate(['name' => 'required|string|max:100']);
        $cat->update(['name' => $data['name'], 'slug' => Str::slug($data['name'])]);
        return response()->json(['data' => $cat]);
    }

    public function deleteCategory(int $id): JsonResponse
    {
        BlogCategory::findOrFail($id)->delete();
        return response()->json(['message' => 'Deleted.']);
    }

    // ── Blog Posts (public) ──────────────────────────────────────────────────

    public function posts(Request $request): JsonResponse
    {
        $query = BlogPost::with('category')
            ->where('status', 'published')
            ->orderBy('published_at', 'desc');

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

        $posts = $query->paginate(12);

        return response()->json([
            'data' => $posts->items(),
            'meta' => ['current_page' => $posts->currentPage(), 'last_page' => $posts->lastPage(), 'total' => $posts->total()],
        ]);
    }

    public function post(string $slug): JsonResponse
    {
        $post = BlogPost::with(['category', 'comments' => fn($q) => $q->where('status', 'approved')->orderBy('created_at')])
            ->where('slug', $slug)
            ->where('status', 'published')
            ->firstOrFail();

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

    // ── Blog Posts (admin) ───────────────────────────────────────────────────

    public function adminPosts(): JsonResponse
    {
        $posts = BlogPost::with('category')->withCount('comments')->orderBy('created_at', 'desc')->get();
        return response()->json(['data' => $posts]);
    }

    public function createPost(Request $request): JsonResponse
    {
        $data = $request->validate([
            'title'            => 'required|string|max:255',
            'slug'             => 'nullable|string|unique:blog_posts,slug',
            'excerpt'          => 'nullable|string',
            'content'          => 'nullable|string',
            'cover_image'      => 'nullable|string',
            'blog_category_id' => 'nullable|exists:blog_categories,id',
            'read_time'        => 'nullable|string',
            'status'           => 'in:draft,published',
        ]);

        $data['slug'] = $data['slug'] ?? Str::slug($data['title']);
        if (($data['status'] ?? 'draft') === 'published') {
            $data['published_at'] = now();
        }

        return response()->json(['data' => BlogPost::create($data)->load('category')], 201);
    }

    public function updatePost(Request $request, int $id): JsonResponse
    {
        $post = BlogPost::findOrFail($id);
        $data = $request->validate([
            'title'            => 'sometimes|string|max:255',
            'excerpt'          => 'nullable|string',
            'content'          => 'nullable|string',
            'cover_image'      => 'nullable|string',
            'blog_category_id' => 'nullable|exists:blog_categories,id',
            'read_time'        => 'nullable|string',
            'status'           => 'in:draft,published',
        ]);

        if (isset($data['status']) && $data['status'] === 'published' && !$post->published_at) {
            $data['published_at'] = now();
        }

        $post->update($data);
        return response()->json(['data' => $post->load('category')]);
    }

    public function deletePost(int $id): JsonResponse
    {
        BlogPost::findOrFail($id)->delete();
        return response()->json(['message' => 'Post deleted.']);
    }

    // ── Comments (public) ────────────────────────────────────────────────────

    public function submitComment(Request $request, int $postId): JsonResponse
    {
        $post = BlogPost::where('status', 'published')->findOrFail($postId);

        $data = $request->validate([
            'name'    => 'required|string|max:100',
            'email'   => 'required|email',
            'content' => 'required|string|max:2000',
        ]);

        $comment = $post->comments()->create([...$data, 'status' => 'pending']);

        return response()->json(['message' => 'Comment submitted and awaiting moderation.', 'data' => $comment], 201);
    }

    // ── Comments (admin) ─────────────────────────────────────────────────────

    public function adminComments(Request $request): JsonResponse
    {
        $query = BlogComment::with('post:id,title,slug')
            ->orderBy('created_at', 'desc');

        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        $comments = $query->paginate(20);

        return response()->json([
            'data' => $comments->items(),
            'meta' => ['current_page' => $comments->currentPage(), 'last_page' => $comments->lastPage(), 'total' => $comments->total()],
        ]);
    }

    public function updateComment(Request $request, int $id): JsonResponse
    {
        $comment = BlogComment::findOrFail($id);
        $data    = $request->validate(['status' => 'required|in:pending,approved,rejected']);
        $comment->update($data);
        return response()->json(['data' => $comment]);
    }

    public function deleteComment(int $id): JsonResponse
    {
        BlogComment::findOrFail($id)->delete();
        return response()->json(['message' => 'Comment deleted.']);
    }
}
