<?php

namespace Daylight\Core\Http\Controllers\Store;

use Daylight\Core\Http\Controllers\Controller;
use Daylight\Core\Http\Requests\Store\Categories\StoreCategoryRequest;
use Daylight\Core\Http\Requests\Store\Categories\UpdateCategoryRequest;
use Daylight\Core\Models\Category;
use Daylight\Core\Modules\PageBuilder\Concerns\InteractsWithPageBuilderRequest;
use Daylight\Core\Modules\PageBuilder\Registries\ComponentRegistry;
use Daylight\Core\Modules\PageBuilder\Registries\TemplateRegistry;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
use Illuminate\Support\Collection;
use Illuminate\View\View;

class CategoryController extends Controller implements HasMiddleware
{
    use InteractsWithPageBuilderRequest;

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

    public function index(): View
    {
        return view('daylight::store.categories.index');
    }

    public function create(): View
    {
        $parents = (daylightModel('category'))::query()
            ->whereParentId(null)
            ->with([
                'translations' => fn ($query) => $query->where('locale', request()->get('locale', app()->getLocale())),
                'children.translations' => fn ($query) => $query->where('locale', request()->get('locale', app()->getLocale())),
                'children.children.translations' => fn ($query) => $query->where('locale', request()->get('locale', app()->getLocale())),
            ])
            ->get();

        return view('daylight::store.categories.create', [
            'availableComponents' => $this->getAvailableComponents(),
            'templates' => app(TemplateRegistry::class)->all(),
            'parents' => $parents,
        ]);
    }

    public function store(StoreCategoryRequest $request)
    {
        $category = (daylightModel('category'))::create($request->safe()->only('parent_id'));

        $translation = $category->translations()->create(
            $request->safe()->only(['locale', 'name', 'meta_title', 'meta_description', 'robots']),
        );

        $components = $request->getComponentsFromRequest();

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

        return redirect()->route('daylight.store.categories.edit', [
            'category' => $category,
            'locale' => $request->get('locale', app()->getLocale()),
        ])->with('success', __('Category has been created.'));
    }

    public function edit(Category $category)
    {
        $translation = $category->translations()
            ->where('locale', request()->get('locale', app()->getLocale()))
            ->first();

        $parents = (daylightModel('category'))::query()
            ->whereParentId(null)
            ->with([
                'translations' => fn ($query) => $query->where('locale', request()->get('locale', app()->getLocale())),
                'children.translations' => fn ($query) => $query->where('locale', request()->get('locale', app()->getLocale())),
                'children.children.translations' => fn ($query) => $query->where('locale', request()->get('locale', app()->getLocale())),
            ])
            ->get();

        return view('daylight::store.categories.edit', [
            'components' => $category->translations->first()->formattedComponentData,
            'availableComponents' => $this->getAvailableComponents(),
            'category' => $category,
            'translation' => $translation,
            'parents' => $parents,
        ]);
    }

    public function update(UpdateCategoryRequest $request, Category $category)
    {
        $category->update($request->safe()->only('parent_id'));

        $media = collect($request->get('image'))
            ->mapWithKeys(function ($media, $order) {
                return [$media['id'] => [
                    'order' => $order,
                    'properties' => [
                        'field' => 'image',
                    ],
                ]];
            });

        $category->media()->sync($media);

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

        //        $this->syncComponentsFromRequest($request, $translation);
        app(\Daylight\Core\Modules\PageBuilder\Services\ComponentSyncService::class)->sync(
            $request->getComponentsFromRequest(),
            $translation
        );

        return redirect()
            ->route('daylight.store.categories.edit', [
                'category' => $category,
                'locale' => $request->get('locale', app()->getLocale()),
            ])
            ->with('success', __('Category has been updated.'));
    }

    public function destroy(Category $category)
    {
        $category->delete();

        return redirect()->route('daylight.store.categories.index')
            ->with('success', __('Category has been deleted.'));
    }

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