<?php

namespace Daylight\Core\Http\Controllers\Content;

use Daylight\Core\Http\Controllers\Controller;
use Daylight\Core\Http\Requests\Content\Pages\StorePageRequest;
use Daylight\Core\Http\Requests\Content\Pages\UpdatePageRequest;
use Daylight\Core\Models\Page;
use Daylight\Core\Modules\PageBuilder\Concerns\InteractsWithPageBuilderRequest;
use Daylight\Core\Modules\PageBuilder\Registries\ComponentRegistry;
use Daylight\Core\Modules\PageBuilder\Registries\TemplateRegistry;
use Daylight\Core\Settings\General;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
use Illuminate\Support\Collection;
use Illuminate\View\View;
use Spatie\ResponseCache\Facades\ResponseCache;

class PageController extends Controller implements HasMiddleware
{
    use InteractsWithPageBuilderRequest;

    public static function middleware(): array
    {
        return [
            new Middleware('can:create:pages', only: ['create', 'store']),
            new Middleware('can:read:pages', only: ['index', 'show']),
            new Middleware('can:update:pages', only: ['edit', 'update']),
            new Middleware('can:delete:pages', only: ['destroy']),
        ];
    }

    public function index(): View
    {
        return view('daylight::content.pages.index');
    }

    public function create(): View
    {
        return view('daylight::content.pages.create', [
            'availableComponents' => $this->getAvailableComponents(),
            'templates' => app(TemplateRegistry::class)->all(),
        ]);
    }

    public function store(StorePageRequest $request)
    {
        $page = tap((daylightModel('page'))::create([
            'template' => $request->get('template', 'default'),
        ]), function (Page $page) use ($request) {
            $translation = $page->translations()->create(
                attributes: $request->safe(['locale', 'name', 'slug', 'meta_title', 'meta_description', 'robots'])
            );

            $translation->components()->createMany($request->getComponentsFromRequest());
        });

        return redirect()
            ->route('daylight.content.pages.edit', [
                'page' => $page,
                'locale' => $request->get('locale', app()->getLocale()),
            ])
            ->with('success', __('Page created'));
    }

    public function edit(Page $page)
    {
        $page->load([
            'translations' => function ($query) {
                $query
                    ->with('components.relatables', 'components.media')
                    ->where('locale', request()->get('locale', app()->getLocale()));
            },
        ]);

        return view('daylight::content.pages.edit', [
            'page' => $page,
            'components' => $page->translations->first()->formattedComponentData,
            'availableComponents' => $this->getAvailableComponents(),
            'templates' => app(TemplateRegistry::class)->all(),
        ]);
    }

    public function update(UpdatePageRequest $request, Page $page)
    {
        $page->update([
            'template' => $request->get('template', 'default'),
        ]);

        $translation = $page->translations()->updateOrCreate(
            ['locale' => $request->get('locale')],
            $request->safe(['name', 'slug', 'meta_title', 'meta_description', 'robots'])
        );

        if (app(General::class)->frontPage === $page->id) {
            ResponseCache::forget('/');
        } else {
            ResponseCache::forget(str_ireplace(config('app.url'), '', translatedRoute('page', $translation['slug'])));
        }

        $this->syncComponentsFromRequest($request, $translation);

        return redirect()
            ->route('daylight.content.pages.edit', [
                'page' => $page,
                'locale' => $request->get('locale', app()->getLocale()),
            ])
            ->with('success', __('Page updated'));
    }

    public function destroy(Page $page): RedirectResponse
    {
        $page->delete();

        return redirect()->route('daylight.content.pages.index')
            ->with('success', __('Page deleted'));
    }

    private function getAvailableComponents(): Collection
    {
        return app(ComponentRegistry::class)
            ->availableFor(daylightModel('page'))
            ->map(fn ($component) => $component->toArray())
            ->values();
    }
}
