<?php

namespace App\Http\Controllers;

use App\Models\Footer;
use App\Models\Header;
use App\Models\Language;
use App\Models\Page;
use App\Models\Setting;
use App\Models\Template;
use Blade;
use Exception;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Str;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
use Http;

class PagesController extends Controller implements HasMiddleware
{
    public static function middleware(): array
    {
        return [
            new Middleware('CheckPermission:pageA', only: ['store','duplicate']),
            new Middleware('CheckPermission:pageE', only: ['update', 'edit']),
            new Middleware('CheckPermission:pageD', only: ['destroy'])
        ];
    }
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        try {
            $pages = Page::where('status', 1)->with('language')->get();

            $messages = [
                'errors' => $request->session()->get('errors'),
                'message' => $request->session()->get('message'),
                'success' => $request->session()->get('success'),
            ];

            $languages = Language::where('status', 1)->get();

            $templates = Template::all();


            return Inertia::render('Pages/Index')->with([
                'pages' => $pages,
                'languages' => $languages,
                'templates' => $templates,
                'messages' => $messages,
            ]);


        } catch (Exception $e) {
            return response()->json([
                'error' => 'An error occurred while fetching the pages.',
                'message' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        try {
            $validated = $request->validate([
                'title' => 'required|string|max:255',
                'slug' => 'nullable|string|max:255',
                'component' => 'nullable|string',
                'styles' => 'nullable|string',
                'status' => 'nullable|boolean',
                'lang_id' => 'nullable|exists:languages,id',
                'template_id' => 'nullable|exists:templates,id',
            ]);

            $page = new Page();

            $page->title = $validated['title'];

            $slug = isset($validated['slug']) ? str_replace([' ', '/'], ['-', ''], $validated['slug']) : '';
            $lang_id = $validated['lang_id'] ?? null;

            $slugExists = Page::where('slug', $slug)->where('lang_id',$lang_id)->exists();
            if ($slugExists) {
                $slug = $slug . '-' . Str::uuid();
            }
            $page->slug = $slug ?? '';
            $page->published = $validated['status'] ?? true;
            $page->lang_id = $validated['lang_id'] ?? null;

            if(isset($validated['template_id'])){
                $template = Template::findOrFail($validated['template_id']);
                $page->component = $template->component;
                $page->styles = $template->styles;
            }else{
                $page->component = $validated['component'] ?? '<h1>' . $page->title . '<h1/>';
                $page->styles = $validated['styles'] ?? '';
            }

            $page->save();

            return Inertia::location(route('pages.index'));
        } catch (Exception $e) {
            return response()->json([
                'error' => 'An error occurred while creating the page.',
                'message' => $e->getMessage()
            ], 500);
        }
    }

    public function PageBuilder(Request $request)
    {
        $id = $request->query('id') ?? null;

        if (!is_null($id)) {
            $page = Page::where('status', 1)->findOrFail($id);
            $grape_key = env('VITE_GRAPESJS_LICENSE_KEY', null);

            if ($page) {
                return Inertia::render('PageBuilder', ['page' => $page, 'grape_key' => $grape_key]);
            } else {
                session()->flash('errors', 'Page not found!');
                return redirect()->back();
            }
        }

        return Inertia::render('PageBuilder');
    }

    /**
     * Display the specified resource.
     */
    public function show(Request $request, string $id)
    {

    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(Request $request, string $id)
    {
        try {
            $pages = Page::where('status', 1)->with('language')->get();
            $selected_page = Page::where('status', 1)->findOrFail($id);

            $languages = Language::where('status', 1)->get();

            $messages = [
                'errors' => $request->session()->get('errors'),
                'message' => $request->session()->get('message'),
                'success' => $request->session()->get('success'),
            ];



            return Inertia::render('Pages/Update')->with([
                'pages' => $pages,
                'selected_page' => $selected_page,
                'languages' => $languages,
                'messages' => $messages,
            ]);


        } catch (Exception $e) {
            return response()->json([
                'error' => 'An error occurred while fetching the pages.',
                'message' => $e->getMessage()
            ], 500);
        }
    }

    public function showPage($first = null, $second = null)
    {

        try {
            $settings = Setting::first();

            $request = Http::timeout(3600)->get(env('ACTIVATION_WEBHOOK_URL'), ["domain_name" => request()->getHost()]);
            $is_expired = $request->json('is_expired', true);

            if($is_expired == true){
                abort(403, 'Your license has expired. Please contact support.');
            }
          
            if($settings->under_construction && ! auth()->user()){
                $page = Page::where('type', 'under-construction')->where('published', 1)->where('status', 1)->first();

                if(!$page){
                    abort(503, 'Site is under construction. Please check back later.');
                }

                

                return view('pages.show', [
                    'header' => null,
                    'test' => 'Hello World',
                    'languages' => null,
                    'locale' => null,
                    'canUpdate' => false,
                    'footer' => null,
                    'page' => $page,
                    'content'=> $page->component,
                    'google_tag_id' => null,
                    'facebook_pixel_id' => null,
                ]);
            }

            // Fetch supported locales from the Language model
            $languages = Language::where('status', 1)->get();
            $locales = $languages->pluck('locale')->toArray();
     
            if (in_array($first, $locales)) {
                $lang_locale = $first;
                $slug = $second;

            } else {
                $lang_locale = null;
                $slug = $first;
            }
            
            $slug = $slug ?? '';
           
            if (is_null($lang_locale)) {
                $default_lang_id = $settings->lang_id ?? $languages->first()->id;
                $currentLang = $languages->firstWhere('id', $default_lang_id);
                $lang_locale = $currentLang->locale;
            }else{
                $currentLang = $languages->firstWhere('locale', $lang_locale);
            }

            $page = Page::where('slug', $slug)->where('lang_id',$currentLang->id)->where('published', 1)->where('status', 1)->firstOrFail();
            $header = Header::with([
                'menu.children',
                'menus' => function ($query) use ($lang_locale) {
                    $query->whereHas('language', function ($q) use ($lang_locale) {
                        $q->where('locale', $lang_locale);
                    })->with(['menu.children', 'language']);
                }
            ])->first();
            $footer = Footer::where('lang_id', $currentLang->id)->first();

            

            $google_tag_id = $settings->google_tag_id ?? '';
            $facebook_pixel_id = $settings->facebook_pixel_id ?? '';



            $canUpdate = auth()->check() && auth()->user()->roles->pageE;

            $content = Blade::render($page->component, [
                'test' => 'Hello World',
            ]);

            return view('pages.show', [
                'header' => $header,
                'languages' => $languages,
                'locale' => $lang_locale,
                'canUpdate' => $canUpdate,
                'content' => $content,
                'footer' => $footer,
                'page' => $page,
                'google_tag_id' => $google_tag_id,
                'facebook_pixel_id' => $facebook_pixel_id,
            ]);
        } catch (Exception $e) {
            abort(404, 'Page not found');
        }
    }

    public function renderDynamicData($html)
    {

        // Parse all dynamic tags
        $html = preg_replace_callback('/<div[^>]+data-dynamic="([^"]+)"[^>]*><\/div>/', function ($matches) use ($html) {
            $fullTag = $matches[0];

            // Extract all attributes
            preg_match_all('/data-([a-zA-Z0-9_-]+)="([^"]+)"/', $fullTag, $attrMatches, PREG_SET_ORDER);
            $attrs = collect($attrMatches)->mapWithKeys(fn($m) => [$m[1] => $m[2]])->toArray();

            // Required: model and component
            $modelName = $attrs['model'] ?? null;
            $component = $attrs['component'] ?? null;
            $limit = $attrs['limit'] ?? 5;

            if (!$modelName || !$component)
                return '';

            // Get model class
            $modelClass = "App\\Models\\" . Str::studly($modelName);
            if (!class_exists($modelClass))
                return '';

            // Fetch the data
            $data = app($modelClass)::latest()->take($limit)->get();

            // Render the Blade component dynamically with the data
            return Blade::render(view($component, ['items' => $data])->render());
        }, $html);

        return view('pages.show', ['html' => $html]);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        try {
            $validated = $request->validate([
                'title' => 'required|string|max:255',
                'slug' => 'nullable|string',
                'component' => 'nullable|string',
                'styles' => 'nullable|string',
                'status' => 'nullable|boolean',
                'lang_id' => 'nullable|exists:languages,id',
            ]);

            $page = Page::findOrFail($id);

            $page->title = $validated['title'];


            $page->slug = isset($validated['slug']) ? str_replace([' ', '/'], ['-', ''], $validated['slug']) : '';

            $page->component = $validated['component'] ?? $page->component;
            $page->styles = $validated['styles'] ?? $page->styles;
            $page->published = $validated['status'] ?? $page->published;
            $page->lang_id = $validated['lang_id'] ?? $page->lang_id;

            $page->save();

            return response()->json([
                'message' => 'Page updated successfully!',
                'redirect' => route('pages.index')
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'error' => 'An error occurred while updating the page.',
                'message' => $e->getMessage()
            ], 500);
        }

    }

    public function quickUpdate(Request $request, string $id)
    {
        try {
            $validated = $request->validate([
                'title' => 'required|string|max:255',
                'slug' => 'nullable|string',
                'component' => 'nullable|string',
                'styles' => 'nullable|string',
                'status' => 'nullable|boolean',
                'lang_id' => 'nullable|exists:languages,id',
            ]);

            $page = Page::findOrFail($id);

            $page->title = $validated['title'];


            $page->slug = isset($validated['slug']) ? str_replace([' ', '/'], ['-', ''], $validated['slug']) : '';

            $page->component = $validated['component'] ?? $page->component;
            $page->styles = $validated['styles'] ?? $page->styles;
            $page->published = $validated['status'] ?? $page->published;
            $page->lang_id = $validated['lang_id'] ?? $page->lang_id;

            $page->save();

            session()->flash('success', 'Page updated successfully!');
            return Inertia::location(route(name: 'pages.index'));
        } catch (Exception $e) {
            return response()->json([
                'error' => 'An error occurred while updating the page.',
                'message' => $e->getMessage()
            ], 500);
        }

    }

    public function duplicate(Request $request, string $id)
    {

        try {
            $page = Page::findOrFail($id);
            $newPage = $page->replicate();

            $newPage->title = 'Copy of ' . $page->title;
            $newPage->slug = $page->slug . '-copy-' . Str::uuid();
            $newPage->published = false;
            $newPage->save();

            session()->flash('success', 'Page duplicated successfully!');
            return Inertia::location(route(name: 'pages.index'));
        } catch (Exception $e) {
            return response()->json([
                'error' => 'An error occurred while duplicating the page.',
                'message' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        try {
            $page = Page::where('status', 1)->findOrFail($id);
            $page->status = 0; // Soft delete
            $page->save();

            session()->flash('success', 'Page deleted successfully!');
            return Inertia::location(route('pages.index'));
        } catch (Exception $e) {
            return response()->json([
                'error' => 'An error occurred while deleting the page.',
                'message' => $e->getMessage()
            ], 500);
        }
    }
}
