<?php

namespace App\Http\Controllers;

use App\Models\PublishingPage;
use App\Http\Requests\StorePublishingPageRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Str;

/**
 * PublishingController
 *
 * Handles dynamic publishing pages for CMS functionality.
 * Managers and Super Managers can create pages; public users can view them.
 *
 * Requirements: 4.1-4.5, 7.1-7.5
 */
class PublishingController extends Controller
{
    // =========================================================================
    // PUBLIC METHODS
    // =========================================================================

    /**
     * Display dynamic page by slug.
     *
     * Requirements: 7.1, 7.2, 7.3
     */
    public function show(string $slug)
    {
        $page = PublishingPage::where('slug', $slug)
            ->published()
            ->firstOrFail();

        // Increment view count
        $page->incrementViewCount();

        // Set SEO meta tags
        $metaTitle = $page->meta_title;
        $metaDescription = $page->meta_description;
        $keywords = $page->keywords;
        $ogImage = $page->og_image;

        // Apply theme colors to CSS variables
        $themeColors = $page->theme_colors ?? [];

        return view('publishing.show', compact(
            'page',
            'metaTitle',
            'metaDescription',
            'keywords',
            'ogImage',
            'themeColors'
        ));
    }

    // =========================================================================
    // ADMIN METHODS
    // =========================================================================

    /**
     * Display all publishing pages.
     *
     * Requirements: 4.1
     */
    public function index(Request $request)
    {
        abort_unless(auth()->user()->can('view pages'), 403);

        $pages = PublishingPage::with('creator')
            ->when($request->search, function ($q, $search) {
                $q->where('title', 'like', "%{$search}%")
                    ->orWhere('slug', 'like', "%{$search}%");
            })
            ->when($request->status === 'published', fn($q) => $q->published())
            ->when($request->status === 'draft', fn($q) => $q->where('is_published', false))
            ->latest()
            ->paginate(15);

        $stats = [
            'total' => PublishingPage::count(),
            'published' => PublishingPage::published()->count(),
            'drafts' => PublishingPage::where('is_published', false)->count(),
        ];

        return view('publishing.admin.index', compact('pages', 'stats'));
    }

    /**
     * Show form to create new publishing page.
     *
     * Requirements: 4.1, 4.2
     */
    public function create()
    {
        abort_unless(auth()->user()->can('create pages'), 403);

        $blockTypes = PublishingPage::getBlockTypes();
        $layouts = PublishingPage::getLayouts();

        return view('publishing.admin.create', compact('blockTypes', 'layouts'));
    }

    /**
     * Store new publishing page.
     *
     * Requirements: 4.1, 4.2, 4.5
     */
    public function store(StorePublishingPageRequest $request)
    {
        abort_unless(auth()->user()->can('create pages'), 403);

        DB::beginTransaction();
        try {
            $data = $request->validated();
            $data['created_by'] = auth()->id();

            // Ensure unique slug
            if (PublishingPage::where('slug', $data['slug'])->exists()) {
                $data['slug'] = PublishingPage::generateUniqueSlug($data['slug']);
            }

            // Set published_at if publishing
            if ($data['is_published'] ?? false) {
                $data['published_at'] = now();
            }

            $page = PublishingPage::create($data);

            DB::commit();

            return redirect()->route('admin.pages.index')
                ->with('success', 'Page created successfully!');

        } catch (\Exception $e) {
            DB::rollBack();
            return back()->withInput()
                ->with('error', 'Failed to create page: ' . $e->getMessage());
        }
    }

    /**
     * Show form to edit publishing page.
     *
     * Requirements: 4.3
     */
    public function edit(PublishingPage $page)
    {
        abort_unless(auth()->user()->can('edit pages'), 403);

        $blockTypes = PublishingPage::getBlockTypes();
        $layouts = PublishingPage::getLayouts();

        return view('publishing.admin.edit', compact('page', 'blockTypes', 'layouts'));
    }

    /**
     * Update publishing page.
     *
     * Requirements: 4.3
     */
    public function update(StorePublishingPageRequest $request, PublishingPage $page)
    {
        abort_unless(auth()->user()->can('edit pages'), 403);

        DB::beginTransaction();
        try {
            $data = $request->validated();
            $data['updated_by'] = auth()->id();

            // Handle slug change
            if (isset($data['slug']) && $data['slug'] !== $page->slug) {
                if (PublishingPage::where('slug', $data['slug'])->where('id', '!=', $page->id)->exists()) {
                    $data['slug'] = PublishingPage::generateUniqueSlug($data['slug']);
                }
            }

            // Handle publish/unpublish
            if (($data['is_published'] ?? false) && !$page->is_published) {
                $data['published_at'] = now();
            }

            $page->update($data);

            DB::commit();

            return redirect()->route('admin.pages.index')
                ->with('success', 'Page updated successfully!');

        } catch (\Exception $e) {
            DB::rollBack();
            return back()->withInput()
                ->with('error', 'Update failed: ' . $e->getMessage());
        }
    }

    /**
     * Delete publishing page.
     */
    public function destroy(PublishingPage $page)
    {
        abort_unless(auth()->user()->can('delete pages'), 403);

        $page->delete();

        return redirect()->route('admin.pages.index')
            ->with('success', 'Page deleted successfully.');
    }

    /**
     * Toggle publish status.
     */
    public function togglePublish(PublishingPage $page)
    {
        abort_unless(auth()->user()->can('edit pages'), 403);

        if ($page->is_published) {
            $page->unpublish();
        } else {
            $page->publish();
        }

        return back()->with('success', 'Page status updated.');
    }

    /**
     * Preview page before publishing.
     */
    public function preview(PublishingPage $page)
    {
        abort_unless(
            auth()->user()->can('edit pages') ||
            $page->created_by === auth()->id(),
            403
        );

        // Set theme colors for preview
        $themeColors = $page->theme_colors ?? [];

        return view('publishing.show', [
            'page' => $page,
            'metaTitle' => $page->meta_title,
            'metaDescription' => $page->meta_description,
            'keywords' => $page->keywords,
            'ogImage' => $page->og_image,
            'themeColors' => $themeColors,
            'isPreview' => true,
        ]);
    }

    // =========================================================================
    // CONTENT BLOCK METHODS
    // =========================================================================

    /**
     * Get block template for page builder (AJAX).
     */
    public function getBlockTemplate(Request $request)
    {
        abort_unless(auth()->user()->can('create pages'), 403);

        $type = $request->get('type', 'text');
        $index = $request->get('index', 0);

        $blockTypes = PublishingPage::getBlockTypes();

        if (!isset($blockTypes[$type])) {
            return response()->json(['error' => 'Invalid block type'], 400);
        }

        $viewName = "publishing.blocks.{$type}";

        if (!View::exists($viewName)) {
            Log::warning("Publishing block view not found: {$viewName}");
            return response()->json(['error' => 'Block template not available'], 404);
        }

        $block = ['type' => $type];

        $html = view($viewName, [
            'block' => $block,
            'index' => $index,
            'page' => null,
        ])->render();

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

    /**
     * Upload image for content block.
     */
    public function uploadImage(Request $request)
    {
        abort_unless(auth()->user()->can('create pages'), 403);

        $request->validate([
            'image' => 'required|image|mimes:jpeg,jpg,png,webp|max:5120',
        ]);

        $path = $request->file('image')->store('publishing/images', 'public');

        return response()->json([
            'success' => true,
            'path' => $path,
            'url' => asset('storage/' . $path),
        ]);
    }

    /**
     * Reorder content blocks (AJAX).
     */
    public function reorderBlocks(Request $request, PublishingPage $page)
    {
        abort_unless(auth()->user()->can('edit pages'), 403);

        $request->validate([
            'order' => 'required|array',
            'order.*' => 'integer',
        ]);

        $page->reorderBlocks($request->order);

        return response()->json(['success' => true]);
    }
}
