<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\BlogCategory;
use App\Models\BlogPost;
use App\Models\BlogTag;
use App\Models\Product;
use App\Services\AiBlogGenerator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Throwable;

class BlogPostController extends Controller
{
    public function index()
    {
        $posts = BlogPost::with('category', 'author')->latest()->paginate(30);
        return view('admin.blog.posts.index', compact('posts'));
    }

    public function create()
    {
        $categories = BlogCategory::flatTree();
        $tags = BlogTag::orderBy('name')->get();
        $products = Product::where('is_active', true)
            ->select('id', 'title', 'slug')
            ->orderBy('title')
            ->get();
        return view('admin.blog.posts.create', compact('categories', 'tags', 'products'));
    }

    public function store(Request $request)
    {
        $data = $this->validateRequest($request);

        $slug = BlogPost::generateSlug($request->slug ?: $request->title);

        $post = BlogPost::create([
            'user_id'            => auth()->id(),
            'category_id'        => $data['category_id'] ?: BlogCategory::default()->id,
            'title'              => $data['title'],
            'slug'               => $slug,
            'excerpt'            => $data['excerpt'] ?? null,
            'content'            => $data['content'] ?? null,
            'featured_image'     => $this->uploadFeatured($request),
            'featured_image_alt' => $data['featured_image_alt'] ?? null,
            'status'             => $data['status'],
            'published_at'       => $data['status'] === 'published' ? ($data['published_at'] ?? now()) : null,
            'seo_title'          => $data['seo_title'] ?? null,
            'seo_description'    => $data['seo_description'] ?? null,
            'seo_keywords'       => $data['seo_keywords'] ?? null,
            'seo_schema'         => $data['seo_schema'] ?? null,
        ]);

        $this->syncTags($post, $request->input('tags_input', ''));

        return redirect()->route('admin.blog.posts.index')->with('success', 'مقاله ثبت شد.');
    }

    public function edit(BlogPost $post)
    {
        $categories = BlogCategory::flatTree();
        $tags = BlogTag::orderBy('name')->get();
        $post->load('tags');
        $tagNames = $post->tags->pluck('name')->implode(', ');
        return view('admin.blog.posts.edit', compact('post', 'categories', 'tags', 'tagNames'));
    }

    public function update(Request $request, BlogPost $post)
    {
        $data = $this->validateRequest($request, $post->id);

        $slug = $request->slug
            ? BlogPost::generateSlug($request->slug, $post->id)
            : BlogPost::generateSlug($request->title, $post->id);

        $newFeatured = $this->uploadFeatured($request);

        $post->update([
            'category_id'        => $data['category_id'] ?: BlogCategory::default()->id,
            'title'              => $data['title'],
            'slug'               => $slug,
            'excerpt'            => $data['excerpt'] ?? null,
            'content'            => $data['content'] ?? null,
            'featured_image'     => $newFeatured ?? $post->featured_image,
            'featured_image_alt' => $data['featured_image_alt'] ?? null,
            'status'             => $data['status'],
            'published_at'       => $data['status'] === 'published'
                ? ($post->published_at ?: now())
                : null,
            'seo_title'          => $data['seo_title'] ?? null,
            'seo_description'    => $data['seo_description'] ?? null,
            'seo_keywords'       => $data['seo_keywords'] ?? null,
            'seo_schema'         => $data['seo_schema'] ?? null,
        ]);

        $this->syncTags($post, $request->input('tags_input', ''));

        return redirect()->route('admin.blog.posts.edit', $post)
            ->with('success', 'مقاله ویرایش شد.');
    }

    public function destroy(BlogPost $post)
    {
        $post->delete();
        return back()->with('success', 'مقاله حذف شد.');
    }

    /**
     * TinyMCE-compatible image upload endpoint.
     * Expects file field "file"; returns { location: <url> }.
     */
    public function uploadMedia(Request $request)
    {
        $request->validate([
            'file' => 'required|image|max:8192',
        ]);

        $file = $request->file('file');
        $dir  = public_path('uploads/blog/content');
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }
        $filename = time() . '_' . bin2hex(random_bytes(4)) . '_' . preg_replace('/[^a-zA-Z0-9._-]/', '_', $file->getClientOriginalName());
        $file->move($dir, $filename);

        return response()->json([
            'location' => url('uploads/blog/content/' . $filename),
        ]);
    }

    public function aiGenerateProgress(string $jobId)
    {
        if (!preg_match('/^[a-zA-Z0-9_-]{8,80}$/', $jobId)) {
            return response()->json(['ok' => false, 'message' => 'شناسه نامعتبر است.'], 422);
        }

        $data = Cache::store('file')->get(AiBlogGenerator::progressCacheKey($jobId));

        if (!$data) {
            return response()->json([
                'ok'      => true,
                'status'  => 'pending',
                'percent' => 0,
                'stage'   => 'prepare',
                'label'   => 'در انتظار شروع…',
                'stages'  => AiBlogGenerator::stages(),
            ]);
        }

        return response()->json(array_merge(['ok' => true], $data), 200, [
            'Cache-Control' => 'no-store, no-cache, must-revalidate',
        ]);
    }

    public function aiGenerate(Request $request, AiBlogGenerator $generator)
    {
        $data = $request->validate([
            'mode'       => 'required|in:product,topic,keyword',
            'product_id' => 'required_if:mode,product|nullable|exists:products,id',
            'topic'      => 'required_if:mode,topic|nullable|string|max:300',
            'keyword'    => 'required_if:mode,keyword|nullable|string|max:200',
            'job_id'     => 'nullable|string|max:80|regex:/^[a-zA-Z0-9_-]+$/',
        ], [
            'product_id.required_if' => 'یک محصول انتخاب کنید.',
            'topic.required_if'      => 'موضوع را وارد کنید.',
            'keyword.required_if'    => 'واژه کلیدی را وارد کنید.',
        ]);

        $jobId = $data['job_id'] ?? null;

        // Release session lock so progress polling is not blocked by this long request.
        if ($request->hasSession()) {
            $request->session()->save();
        }
        if (session_status() === PHP_SESSION_ACTIVE) {
            session_write_close();
        }

        AiBlogGenerator::reportProgress($jobId, 2, 'prepare', 'شروع تولید محتوا…');

        $subject = $this->buildSubjectDescription($data);
        $focusKeyword = $this->resolveFocusKeyword($data);

        try {
            $generated = $generator->generate($subject, $focusKeyword, $jobId);
        } catch (Throwable $e) {
            AiBlogGenerator::reportProgress(
                $jobId,
                0,
                'error',
                'خطا در تولید محتوا',
                'failed',
                $e->getMessage()
            );

            return response()->json([
                'ok'      => false,
                'message' => $e->getMessage(),
            ], 422);
        }

        if (!$generated['title']) {
            $msg = 'مدل عنوان مقاله را تولید نکرد. لطفاً دوباره تلاش کنید.';
            AiBlogGenerator::reportProgress($jobId, 0, 'error', $msg, 'failed', $msg);

            return response()->json([
                'ok'      => false,
                'message' => $msg,
            ], 422);
        }

        AiBlogGenerator::reportProgress($jobId, 97, 'save', 'در حال ذخیره پیش‌نویس…');

        $slugSource = $generated['slug'] ?: $generated['title'];
        $slug = BlogPost::generateSlug($slugSource);

        $post = BlogPost::create([
            'user_id'            => auth()->id(),
            'category_id'        => BlogCategory::default()->id,
            'title'              => $generated['title'],
            'slug'               => $slug,
            'excerpt'            => $generated['excerpt'] ?: null,
            'content'            => $generated['content'] ?: null,
            'featured_image'     => $generated['featured_image'] ?? null,
            'featured_image_alt' => $generated['featured_image_alt'] ?? null,
            'status'             => 'draft',
            'seo_title'          => $generated['seo_title'] ?: null,
            'seo_description'    => $generated['seo_description'] ?: null,
            'seo_keywords'       => $generated['seo_keywords'] ?: null,
            'seo_schema'         => $generated['seo_schema'] ?: null,
        ]);

        if (!empty($generated['tags'])) {
            $this->syncTags($post, implode(',', $generated['tags']));
        }

        $redirect = route('admin.blog.posts.edit', $post->slug);

        AiBlogGenerator::reportProgress(
            $jobId,
            100,
            'done',
            'تولید با موفقیت انجام شد',
            'done',
            $redirect
        );

        return response()->json([
            'ok'           => true,
            'message'      => 'مقاله پیش‌نویس با موفقیت توسط هوش مصنوعی تولید شد.',
            'redirect_url' => $redirect,
        ]);
    }

    private function buildSubjectDescription(array $data): string
    {
        return match ($data['mode']) {
            'product' => (function () use ($data) {
                $p = Product::findOrFail($data['product_id']);
                $info = "نام محصول: {$p->title}";
                if ($p->title_en) {
                    $info .= " ({$p->title_en})";
                }
                if ($p->description) {
                    $info .= "\nتوضیحات اولیه محصول: " . mb_substr(strip_tags($p->description), 0, 600);
                }
                $productUrl = route('product.show', $p->slug);
                return "موضوع: نوشتن مقاله وبلاگ تخصصی، مفصل و سئوشده دربارهٔ محصول زیر. در متن دست‌کم یک‌بار به صفحهٔ محصول با لینک «{$productUrl}» اشاره و راهنمایی به خرید کنید.\n{$info}";
            })(),
            'topic'   => "موضوع: نوشتن مقاله وبلاگ تخصصی و سئوشده دربارهٔ این موضوع: «{$data['topic']}»",
            'keyword' => "موضوع: نوشتن مقاله وبلاگ تخصصی و سئوشده با تمرکز بر کلمه کلیدی اصلی: «{$data['keyword']}».",
        };
    }

    private function resolveFocusKeyword(array $data): ?string
    {
        return match ($data['mode']) {
            'keyword' => trim((string) ($data['keyword'] ?? '')) ?: null,
            'topic'   => trim((string) ($data['topic'] ?? '')) ?: null,
            'product' => optional(Product::find($data['product_id'] ?? null))->title,
            default   => null,
        };
    }

    private function validateRequest(Request $request, ?int $id = null): array
    {
        $uniqueSlug = 'unique:blog_posts,slug' . ($id ? ',' . $id : '');

        return $request->validate([
            'title'              => 'required|string|max:255',
            'slug'               => 'nullable|string|max:255|' . $uniqueSlug,
            'category_id'        => 'nullable|exists:blog_categories,id',
            'excerpt'            => 'nullable|string|max:1000',
            'content'            => 'nullable|string',
            'featured_image'     => 'nullable|image|max:8192',
            'featured_image_alt' => 'nullable|string|max:255',
            'status'             => 'required|in:draft,published',
            'published_at'       => 'nullable|date',
            'seo_title'          => 'nullable|string|max:255',
            'seo_description'    => 'nullable|string|max:500',
            'seo_keywords'       => 'nullable|string|max:500',
            'seo_schema'         => 'nullable|string',
        ], [
            'title.required'    => 'عنوان مقاله الزامی است.',
            'status.required'   => 'وضعیت مقاله را انتخاب کنید.',
            'slug.unique'       => 'این اسلاگ قبلاً استفاده شده است.',
        ]);
    }

    private function uploadFeatured(Request $request): ?string
    {
        if (!$request->hasFile('featured_image')) {
            return null;
        }
        $file = $request->file('featured_image');
        $dir  = public_path('uploads/blog/posts');
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }
        $filename = time() . '_' . $file->getClientOriginalName();
        $file->move($dir, $filename);
        return $filename;
    }

    private function syncTags(BlogPost $post, string $raw): void
    {
        $names = collect(preg_split('/[,،]/u', $raw))
            ->map(fn($n) => trim($n))
            ->filter()
            ->unique()
            ->values();

        $ids = $names->map(fn($name) => BlogTag::findOrCreateByName($name)->id)->all();
        $post->tags()->sync($ids);
    }
}
