<?php

namespace App\Http\Controllers\Admin;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Models\BlogPost;
use App\Models\BlogCategory;
use App\Models\BlogTag;
use App\Models\BlogPostTag;
use App\Services\UploadService;

class BlogController extends Controller
{
    // -------------------------------------------------------------------------
    // LIST
    // -------------------------------------------------------------------------

    public function index(Request $request, array $params = []): void
    {
        $posts = BlogPost::allWithDetails();

        $this->renderAdmin('blog/index', [
            'pageTitle' => 'Blog Posts',
            'posts'     => $posts,
            'auth'      => $this->auth(),
            'csrf'      => $this->csrf(),
        ]);
    }

    // -------------------------------------------------------------------------
    // CREATE
    // -------------------------------------------------------------------------

    public function create(Request $request, array $params = []): void
    {
        $categories = BlogCategory::all('name');

        $this->renderAdmin('blog/form', [
            'pageTitle'  => 'Create Blog Post',
            'post'       => null,
            'categories' => $categories,
            'postTags'   => [],
            'auth'       => $this->auth(),
            'csrf'       => $this->csrf(),
        ]);
    }

    public function store(Request $request, array $params = []): void
    {
        $this->validateCsrf();

        $title    = trim($request->input('title', ''));
        $slug     = trim($request->input('slug', ''));
        $content  = $request->input('content', '');
        $excerpt  = trim($request->input('excerpt', ''));
        $status   = $request->input('status', 'draft');
        $catId    = (int) $request->input('category_id', 0) ?: null;
        $seoTitle = trim($request->input('seo_title', ''));
        $seoDesc  = trim($request->input('seo_description', ''));
        $tagsRaw  = trim($request->input('tags', ''));

        if (empty($title)) {
            set_flash('error', __('messages.field_required'));
            Response::redirect('/admin/blog/create');
            return;
        }

        // Always normalize the slug, whether auto-generated or user-provided,
        // to guarantee a URL-safe value that matches the frontend route lookup.
        $slug = !empty($slug) ? slugify($slug) : slugify($title);

        $existing = BlogPost::findBySlug($slug);
        if ($existing) {
            $slug = $slug . '-' . bin2hex(random_bytes(4));
        }

        $featuredImage = UploadService::upload($request->file('featured_image') ?? [], 'blog', 'blog', true, true);

        // If no file was uploaded, check for a library-selected path
        if ($featuredImage === null) {
            $libraryPath = trim($request->input('featured_image_path', ''));
            if ($libraryPath !== '') {
                $featuredImage = $libraryPath;
            }
        }

        $publishedAt   = ($status === 'published') ? date('Y-m-d H:i:s') : null;

        $postId = BlogPost::create([
            'title'           => $title,
            'slug'            => $slug,
            'content'         => $content,
            'excerpt'         => $excerpt,
            'status'          => $status,
            'category_id'     => $catId,
            'author_id'       => $this->auth()->userId(),
            'featured_image'  => $featuredImage,
            'published_at'    => $publishedAt,
            'seo_title'       => $seoTitle,
            'seo_description' => $seoDesc,
            'created_at'      => date('Y-m-d H:i:s'),
            'updated_at'      => date('Y-m-d H:i:s'),
        ]);

        // Save tags
        $this->syncTags($postId, $tagsRaw);

        set_flash('success', __('messages.post_created', ['title' => $title]));
        Response::redirect('/admin/blog');
    }

    // -------------------------------------------------------------------------
    // EDIT / UPDATE
    // -------------------------------------------------------------------------

    public function edit(Request $request, array $params = []): void
    {
        $id   = (int) ($params['id'] ?? 0);
        $post = BlogPost::findForAdmin($id);

        if (!$post) {
            set_flash('error', __('messages.not_found', ['item' => 'Post']));
            Response::redirect('/admin/blog');
            return;
        }

        $categories = BlogCategory::all('name');
        $postTags   = BlogTag::findByPost($id);

        $this->renderAdmin('blog/form', [
            'pageTitle'  => 'Edit Blog Post',
            'post'       => $post,
            'categories' => $categories,
            'postTags'   => $postTags,
            'auth'       => $this->auth(),
            'csrf'       => $this->csrf(),
        ]);
    }

    public function update(Request $request, array $params = []): void
    {
        $this->validateCsrf();

        $id   = (int) ($params['id'] ?? 0);
        $post = BlogPost::findForAdmin($id);

        if (!$post) {
            set_flash('error', 'Post not found.');
            Response::redirect('/admin/blog');
            return;
        }

        $title    = trim($request->input('title', ''));
        $slug     = trim($request->input('slug', ''));
        $content  = $request->input('content', '');
        $excerpt  = trim($request->input('excerpt', ''));
        $status   = $request->input('status', 'draft');
        $catId    = (int) $request->input('category_id', 0) ?: null;
        $seoTitle = trim($request->input('seo_title', ''));
        $seoDesc  = trim($request->input('seo_description', ''));
        $tagsRaw  = trim($request->input('tags', ''));

        if (empty($title)) {
            set_flash('error', 'Title is required.');
            Response::redirect('/admin/blog/edit/' . $id);
            return;
        }

        // Always normalize the slug to guarantee a URL-safe value.
        $slug = !empty($slug) ? slugify($slug) : slugify($title);

        $slugConflict = BlogPost::findBySlug($slug);
        if ($slugConflict && (int) $slugConflict['id'] !== $id) {
            $slug = $slug . '-' . bin2hex(random_bytes(4));
        }

        $featuredImage = $post['featured_image'];

        $newUpload = UploadService::upload($request->file('featured_image') ?? [], 'blog', 'blog', true, true);

        if ($newUpload !== null) {
            // New file uploaded – delete old (direct upload) and use new
            if (!empty($featuredImage)) {
                UploadService::delete($featuredImage, true, true);
            }
            $featuredImage = $newUpload;
        } elseif ($request->input('remove_image') === '1') {
            // Remove requested – delete old file and clear reference
            UploadService::delete($post['featured_image'], true, true);
            $featuredImage = null;
        } else {
            // No new upload, no remove – check if a library image was selected
            $libraryPath = trim($request->input('featured_image_path', ''));
            if ($libraryPath !== '' && $libraryPath !== $post['featured_image']) {
                // Library path changed: update reference; do NOT delete old file
                // (it may be a media library image used elsewhere)
                $featuredImage = $libraryPath;
            }
        }

        $publishedAt = $post['published_at'];
        if ($status === 'published' && empty($publishedAt)) {
            $publishedAt = date('Y-m-d H:i:s');
        }

        BlogPost::updateById($id, [
            'title'           => $title,
            'slug'            => $slug,
            'content'         => $content,
            'excerpt'         => $excerpt,
            'status'          => $status,
            'category_id'     => $catId,
            'featured_image'  => $featuredImage,
            'published_at'    => $publishedAt,
            'seo_title'       => $seoTitle,
            'seo_description' => $seoDesc,
            'updated_at'      => date('Y-m-d H:i:s'),
        ]);

        // Sync tags
        $this->syncTags($id, $tagsRaw);

        set_flash('success', __('messages.post_updated'));
        Response::redirect('/admin/blog');
    }

    // -------------------------------------------------------------------------
    // DELETE
    // -------------------------------------------------------------------------

    public function delete(Request $request, array $params = []): void
    {
        $this->validateCsrf();

        $id   = (int) ($params['id'] ?? 0);
        $post = BlogPost::findForAdmin($id);

        if (!$post) {
            set_flash('error', __('messages.not_found', ['item' => 'Post']));
            Response::redirect('/admin/blog');
            return;
        }

        BlogPostTag::deleteForPost($id);
        UploadService::delete($post['featured_image'], true, true);
        BlogPost::deleteById($id);

        set_flash('success', __('messages.post_deleted'));
        Response::redirect('/admin/blog');
    }

    // -------------------------------------------------------------------------
    // CLONE / DUPLICATE
    // -------------------------------------------------------------------------

    public function clonePost(Request $request, array $params = []): void
    {
        $this->validateCsrf();

        $id   = (int) ($params['id'] ?? 0);
        $post = BlogPost::findForAdmin($id);

        if (!$post) {
            set_flash('error', __('messages.not_found', ['item' => 'Post']));
            Response::redirect('/admin/blog');
            return;
        }

        // Generate a unique slug: {slug}-copy, {slug}-copy-2, ...
        $baseSlug = $post['slug'] . '-copy';
        $newSlug  = $baseSlug;
        $counter  = 2;
        while (BlogPost::findBySlug($newSlug)) {
            $newSlug = $baseSlug . '-' . $counter;
            $counter++;
        }

        $newId = BlogPost::create([
            'title'           => 'Copy of ' . $post['title'],
            'slug'            => $newSlug,
            'content'         => $post['content'],
            'excerpt'         => $post['excerpt'],
            'status'          => 'draft',
            'category_id'     => $post['category_id'] ?: null,
            'author_id'       => $this->auth()->userId(),
            'featured_image'  => null,   // do not share file references (avoids accidental deletion)
            'published_at'    => null,
            'seo_title'       => $post['seo_title'],
            'seo_description' => $post['seo_description'],
            'created_at'      => date('Y-m-d H:i:s'),
            'updated_at'      => date('Y-m-d H:i:s'),
        ]);

        // Copy tags from original post
        $originalTagIds = BlogPostTag::tagIdsForPost($id);
        if (!empty($originalTagIds)) {
            BlogPostTag::syncForPost($newId, $originalTagIds);
        }

        set_flash('success', __('messages.post_duplicated'));
        Response::redirect('/admin/blog');
    }

    // -------------------------------------------------------------------------
    // HELPERS
    // -------------------------------------------------------------------------

    /**
     * Parse a comma-separated tag string, find-or-create each tag, sync pivot.
     */
    private function syncTags(int $postId, string $tagsRaw): void
    {
        if (trim($tagsRaw) === '') {
            BlogPostTag::syncForPost($postId, []);
            return;
        }

        $names  = array_filter(array_map('trim', explode(',', $tagsRaw)));
        $tagIds = [];

        foreach ($names as $name) {
            if ($name === '') {
                continue;
            }
            $tag = BlogTag::findOrCreateByName($name);
            if (!empty($tag['id'])) {
                $tagIds[] = (int) $tag['id'];
            }
        }

        BlogPostTag::syncForPost($postId, $tagIds);
    }
}
