<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\BlogCategory;
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Schema;

class BlogController extends Controller
{
    private function categoryNames()
    {
        if (Schema::hasTable('blog_categories')) {
            return BlogCategory::query()->orderBy('name')->pluck('name');
        }

        return Post::query()
            ->select('category')
            ->whereNotNull('category')
            ->where('category', '!=', '')
            ->distinct()
            ->orderBy('category')
            ->pluck('category');
    }

    public function index(Request $request)
    {
        $query = Post::with('author');

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

        if ($request->filled('search')) {
            $query->where('title', 'like', '%' . $request->search . '%');
        }

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

        $categories = $this->categoryNames();

        $posts = $query->latest()->paginate(20);
        return view('admin.blog.index', compact('posts', 'categories'));
    }

    public function create()
    {
        $categories = $this->categoryNames();
        return view('admin.blog.create', compact('categories'));
    }

    public function store(Request $request)
    {
        $hasFeaturedColumn = Schema::hasColumn('posts', 'is_featured');

        $request->validate([
            'title' => 'required|string|max:255',
            'excerpt' => 'nullable|string|max:500',
            'content' => 'required|string',
            'category' => 'nullable|string|max:100',
            'tags' => 'nullable|string|max:500',
            'status' => 'required|in:draft,published,scheduled',
            'is_featured' => 'boolean',
            'meta_title' => 'nullable|string|max:255',
            'meta_description' => 'nullable|string|max:300',
            'published_at' => 'nullable|date',
            'featured_image' => 'nullable|image|max:2048'
        ]);

        $excerpt = $request->excerpt;
        if (!$excerpt) {
            $excerpt = Str::limit(strip_tags((string) $request->content), 200);
        }

        $tags = null;
        if ($request->filled('tags')) {
            $tags = collect(explode(',', (string) $request->tags))
                ->map(fn ($t) => trim($t))
                ->filter(fn ($t) => $t !== '')
                ->unique()
                ->values()
                ->all();
        }

        $data = [
            'title' => $request->title,
            'slug' => Str::slug($request->title),
            'excerpt' => $excerpt,
            'content' => $request->content,
            'category' => $request->category,
            'tags' => $tags,
            'status' => $request->status,
            'is_featured' => $hasFeaturedColumn ? $request->boolean('is_featured') : null,
            'author_id' => auth()->id(),
            'published_at' => $request->status === 'published'
                ? ($request->published_at ? $request->published_at : now())
                : ($request->status === 'scheduled' ? $request->published_at : null),
            'seo_meta' => [
                'title' => $request->meta_title ?: $request->title,
                'description' => $request->meta_description ?: $excerpt,
            ],
        ];

        $categoryName = trim((string) $request->category);
        if ($categoryName !== '' && Schema::hasTable('blog_categories')) {
            BlogCategory::firstOrCreate(['name' => $categoryName]);
        }

        if (!$hasFeaturedColumn) {
            unset($data['is_featured']);
        }

        if ($request->hasFile('featured_image')) {
            $data['featured_image'] = $request->file('featured_image')->store('blog', 'public');
        }

        Post::create($data);

        return redirect()->route('admin.blog.index')
            ->with('success', 'Article créé avec succès');
    }

    public function edit(Post $post)
    {
        $categories = $this->categoryNames();
        return view('admin.blog.edit', compact('post', 'categories'));
    }

    public function update(Request $request, Post $post)
    {
        $hasFeaturedColumn = Schema::hasColumn('posts', 'is_featured');

        $request->validate([
            'title' => 'required|string|max:255',
            'excerpt' => 'nullable|string|max:500',
            'content' => 'required|string',
            'category' => 'nullable|string|max:100',
            'tags' => 'nullable|string|max:500',
            'status' => 'required|in:draft,published,scheduled,archived',
            'is_featured' => 'boolean',
            'meta_title' => 'nullable|string|max:255',
            'meta_description' => 'nullable|string|max:300',
            'published_at' => 'nullable|date',
            'featured_image' => 'nullable|image|max:2048'
        ]);

        $excerpt = $request->excerpt;
        if (!$excerpt) {
            $excerpt = Str::limit(strip_tags((string) $request->content), 200);
        }

        $tags = null;
        if ($request->filled('tags')) {
            $tags = collect(explode(',', (string) $request->tags))
                ->map(fn ($t) => trim($t))
                ->filter(fn ($t) => $t !== '')
                ->unique()
                ->values()
                ->all();
        }

        $data = [
            'title' => $request->title,
            'excerpt' => $excerpt,
            'content' => $request->content,
            'category' => $request->category,
            'tags' => $tags,
            'status' => $request->status,
            'is_featured' => $hasFeaturedColumn ? $request->boolean('is_featured') : null,
            'published_at' => $request->status === 'published'
                ? ($request->published_at ? $request->published_at : ($post->published_at ?: now()))
                : ($request->status === 'scheduled' ? $request->published_at : null),
            'seo_meta' => [
                'title' => $request->meta_title ?: $request->title,
                'description' => $request->meta_description ?: $excerpt,
            ],
        ];

        $categoryName = trim((string) $request->category);
        if ($categoryName !== '' && Schema::hasTable('blog_categories')) {
            BlogCategory::firstOrCreate(['name' => $categoryName]);
        }

        if (!$hasFeaturedColumn) {
            unset($data['is_featured']);
        }

        if ($request->title !== $post->title) {
            $data['slug'] = Str::slug($request->title);
        }

        if ($request->hasFile('featured_image')) {
            $data['featured_image'] = $request->file('featured_image')->store('blog', 'public');
        }

        $post->update($data);

        return redirect()->route('admin.blog.index')
            ->with('success', 'Article mis à jour');
    }

    public function destroy(Post $post)
    {
        $post->delete();
        return redirect()->route('admin.blog.index')
            ->with('success', 'Article supprimé');
    }

    public function toggleFeatured(Post $post)
    {
        if (!Schema::hasColumn('posts', 'is_featured')) {
            return redirect()->back()->with('error', 'La colonne is_featured n\'existe pas encore. Lance la migration du blog.');
        }

        $post->update(['is_featured' => !$post->is_featured]);
        return redirect()->back()
            ->with('success', $post->is_featured ? 'Article mis en avant' : 'Mise en avant retirée');
    }

    public function categories()
    {
        if (!Schema::hasTable('blog_categories')) {
            $categories = Post::query()
                ->select('category', DB::raw('COUNT(*) as total'))
                ->whereNotNull('category')
                ->where('category', '!=', '')
                ->groupBy('category')
                ->orderByDesc('total')
                ->get();

            return view('admin.blog.categories', compact('categories'))
                ->with('error', 'Table blog_categories manquante: lance la migration des catégories pour activer la création.');
        }

        // Sync automatique: si des catégories existent dans posts mais pas dans blog_categories
        $existing = BlogCategory::query()->pluck('name')->all();
        $fromPosts = Post::query()
            ->select('category')
            ->whereNotNull('category')
            ->where('category', '!=', '')
            ->distinct()
            ->pluck('category')
            ->all();

        foreach ($fromPosts as $name) {
            if (!in_array($name, $existing, true)) {
                BlogCategory::create(['name' => $name]);
                $existing[] = $name;
            }
        }

        $categories = BlogCategory::query()
            ->leftJoin('posts', 'posts.category', '=', 'blog_categories.name')
            ->select('blog_categories.name as category', DB::raw('COUNT(posts.id) as total'))
            ->groupBy('blog_categories.name')
            ->orderByDesc('total')
            ->orderBy('blog_categories.name')
            ->get();

        return view('admin.blog.categories', compact('categories'));
    }

    public function createCategory(Request $request)
    {
        if (!Schema::hasTable('blog_categories')) {
            return redirect()->back()->with('error', 'Impossible de créer une catégorie: table blog_categories manquante. Lance la migration.');
        }

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

        $name = trim((string) $request->input('name'));
        if ($name === '') {
            return redirect()->back()->with('error', 'Catégorie invalide.');
        }

        BlogCategory::firstOrCreate(['name' => $name]);

        return redirect()->back()->with('success', 'Catégorie créée.');
    }

    public function renameCategory(Request $request)
    {
        if (!Schema::hasTable('blog_categories')) {
            return redirect()->back()->with('error', 'Impossible de renommer: table blog_categories manquante. Lance la migration.');
        }

        $request->validate([
            'from' => 'required|string|max:100',
            'to' => 'required|string|max:100',
        ]);

        $from = trim((string) $request->input('from'));
        $to = trim((string) $request->input('to'));

        if ($from === '' || $to === '') {
            return redirect()->back()->with('error', 'Catégorie invalide.');
        }

        if ($from === $to) {
            return redirect()->back()->with('success', 'Aucun changement.');
        }

        BlogCategory::query()->where('name', $from)->update(['name' => $to]);
        BlogCategory::firstOrCreate(['name' => $to]);
        $updated = Post::query()->where('category', $from)->update(['category' => $to]);

        return redirect()->back()->with('success', "Catégorie renommée ({$updated} article(s)).");
    }

    public function deleteCategory(Request $request)
    {
        if (!Schema::hasTable('blog_categories')) {
            return redirect()->back()->with('error', 'Impossible de supprimer: table blog_categories manquante. Lance la migration.');
        }

        $request->validate([
            'category' => 'required|string|max:100',
        ]);

        $category = trim((string) $request->input('category'));
        if ($category === '') {
            return redirect()->back()->with('error', 'Catégorie invalide.');
        }

        BlogCategory::query()->where('name', $category)->delete();
        $updated = Post::query()->where('category', $category)->update(['category' => null]);

        return redirect()->back()->with('success', "Catégorie supprimée des articles ({$updated} article(s)).");
    }

    public function tags()
    {
        $tags = collect(Post::query()->whereNotNull('tags')->pluck('tags')->all())
            ->flatten()
            ->filter(fn ($t) => is_string($t) && trim($t) !== '')
            ->map(fn ($t) => trim($t))
            ->countBy()
            ->sortDesc();

        return view('admin.blog.tags', compact('tags'));
    }

    public function renameTag(Request $request)
    {
        $request->validate([
            'from' => 'required|string|max:100',
            'to' => 'required|string|max:100',
        ]);

        $from = trim((string) $request->input('from'));
        $to = trim((string) $request->input('to'));

        if ($from === '' || $to === '') {
            return redirect()->back()->with('error', 'Tag invalide.');
        }
        if ($from === $to) {
            return redirect()->back()->with('success', 'Aucun changement.');
        }

        $posts = Post::query()->whereJsonContains('tags', $from)->get();

        foreach ($posts as $post) {
            $current = is_array($post->tags) ? $post->tags : [];
            $next = collect($current)
                ->filter(fn ($t) => is_string($t) && trim($t) !== '')
                ->map(fn ($t) => trim($t) === $from ? $to : trim($t))
                ->unique()
                ->values()
                ->all();

            $post->tags = $next;
            $post->save();
        }

        return redirect()->back()->with('success', "Tag renommé ({$posts->count()} article(s)).");
    }

    public function deleteTag(Request $request)
    {
        $request->validate([
            'tag' => 'required|string|max:100',
        ]);

        $tag = trim((string) $request->input('tag'));
        if ($tag === '') {
            return redirect()->back()->with('error', 'Tag invalide.');
        }

        $posts = Post::query()->whereJsonContains('tags', $tag)->get();
        foreach ($posts as $post) {
            $current = is_array($post->tags) ? $post->tags : [];
            $next = collect($current)
                ->filter(fn ($t) => is_string($t) && trim($t) !== '')
                ->map(fn ($t) => trim($t))
                ->reject(fn ($t) => $t === $tag)
                ->unique()
                ->values()
                ->all();

            $post->tags = $next;
            $post->save();
        }

        return redirect()->back()->with('success', "Tag supprimé ({$posts->count()} article(s)).");
    }
}
