<?php

namespace Daylight\Core\Http\Controllers\Store;

use Daylight\Core\Http\Controllers\Controller;
use Daylight\Core\Http\Requests\Store\Attributes\StoreAttributeRequest;
use Daylight\Core\Http\Requests\Store\Attributes\UpdateAttributeRequest;
use Daylight\Core\Models\Attribute;
use Daylight\Core\Models\AttributeValue;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
use Illuminate\View\View;

class AttributeController extends Controller implements HasMiddleware
{
    public static function middleware(): array
    {
        return [
            new Middleware('can:create:attributes', only: ['create', 'store']),
            new Middleware('can:read:attributes', only: ['index', 'show']),
            new Middleware('can:update:attributes', only: ['edit', 'update']),
            new Middleware('can:delete:attributes', only: ['destroy']),
        ];
    }

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

    public function create(): View
    {
        $categories = (daylightModel('category'))::query()
            ->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())),
            ])
            ->whereNull('parent_id')
            ->get();

        return view('daylight::store.attributes.create', [
            'categories' => $categories,
        ]);
    }

    public function store(StoreAttributeRequest $request)
    {
        $attribute = (daylightModel('attribute'))::create($request->safe()->only(['key', 'filterable', 'visible', 'order']));
        $attribute->categories()->sync($request->get('categories'));

        collect($request->get('translations'))
            ->each(function ($translation, $locale) use ($attribute) {
                $attribute->translations()->create([
                    'locale' => $locale,
                    ...$translation,
                ]);
            });

        collect($request->get('values'))
            ->each(function ($value) use ($attribute) {
                tap($attribute->values()->create(['order' => $value['order'] ?? 0]), function (AttributeValue $attributeValue) use ($value) {
                    collect($value['translations'])
                        ->each(function ($translation, $locale) use ($attributeValue) {
                            $attributeValue->translations()->create([
                                'locale' => $locale,
                                ...$translation,
                            ]);
                        });
                });
            });

        return redirect()->route('daylight.store.attributes.edit', $attribute)
            ->with('success', __('daylight::store.attribute_created'));
    }

    public function edit(Attribute $attribute)
    {
        $attribute->loadMissing('translations');

        $categories = (daylightModel('category'))::query()
            ->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())),
            ])
            ->whereNull('parent_id')
            ->get();

        return view('daylight::store.attributes.edit', [
            'attribute' => $attribute,
            'categories' => $categories,
        ]);
    }

    public function update(UpdateAttributeRequest $request, Attribute $attribute)
    {
        $attribute->update($request->safe()->only(['key', 'filterable', 'visible', 'order']));
        $attribute->categories()->sync($request->get('categories'));

        collect($request->get('translations'))
            ->each(function ($translation, $locale) use ($attribute) {
                $attribute->translations()->updateOrCreate([
                    'locale' => $locale,
                ], $translation);
            });

        $attribute->values()
            ->whereNotIn('id', collect($request->get('values'))->pluck('id'))
            ->delete();

        collect($request->get('values'))
            ->each(function ($value) use ($attribute) {
                if (is_null($value['id'])) {
                    $attributeValue = $attribute->values()->create(['order' => $value['order'] ?? 0]);
                } else {
                    $attributeValue = $attribute->values()->find($value['id']);
                    $attributeValue->update(['order' => $value['order'] ?? 0]);
                }

                collect($value['translations'])
                    ->each(function ($translation, $locale) use ($attributeValue) {
                        $attributeValue->translations()->updateOrCreate([
                            'locale' => $locale,
                        ], $translation);
                    });
            });

        return redirect()->route('daylight.store.attributes.edit', $attribute)
            ->with('success', __('daylight::store.attribute_updated'));
    }

    public function destroy(Attribute $attribute)
    {
        $attribute->delete();

        return redirect()->route('daylight.store.attributes.index')
            ->with('success', __('daylight::store.attribute_deleted'));
    }
}
