<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreProperty;
use App\Http\Requests\UpdateProperty;
use App\Http\Resources\PropertyList;
use App\Http\Resources\PropertyView;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Str;
use Mtc\ContentManager\Facades\Media;
use Mtc\MercuryDataModels\Property;
use Mtc\MercuryDataModels\PropertyCategory;

class PropertyController extends Controller
{
    public function index(PropertyCategory $category, Request $request): PropertyList
    {
        return (new PropertyList(Property::query()
            ->orderBy('order')
            ->when($request->input('filters') === 'active', fn($query) => $query->where('active', 1))
            ->when($request->input('filters') === 'drafts', fn($query) => $query->where('active', 0))
            ->where('category_id', $category->id)
            ->paginate($request->input('per_page'))))->setCategoryName($category->name);
    }

    public function store(StoreProperty $request, PropertyCategory $category): PropertyView
    {
        $property = $category->properties()
            ->create([
                'name' => $request->input('name'),
            ]);

        return new PropertyView($property);
    }

    public function show(PropertyCategory $category, Property $property): PropertyView
    {
        if ($category->id !== $property->category_id) {
            abort(400);
        }

        return new PropertyView($property);
    }

    public function update(UpdateProperty $request, PropertyCategory $category, Property $property): PropertyView
    {
        $data = $request->input('data', []);
        $data['canonical'] = $request->input('canonical');
        $property->update([
            'name' => $request->input('name'),
            'slug' => Str::slug($request->input('slug')),
            'active' => $request->input('active'),
            'data' => $data,
        ]);

        collect($request->input('fields', []))
            ->each(fn($attribute, $index) => $this->saveAttributeValue($property, $attribute, $index));
        return new PropertyView($property);
    }

    public function destroy(PropertyCategory $category, Property $property): Response
    {
        if ($category->id !== $property->category_id) {
            abort(400);
        }

        $property->delete();
        return response('ok');
    }

    public function reorder(PropertyCategory $category, Request $request): Response
    {
        collect($request->input('properties'))
            ->each(fn($property, $order) => Property::query()
                ->where('category_id', $category->id)
                ->where('id', $property['id'])
                ->update(['order' => $order]));

        return response('ok');
    }

    private function saveAttributeValue(Property $property, array $attribute, int $index): void
    {
        $value = $property->attributeValues()
            ->updateOrCreate([
                'field_id' => $attribute['id']
            ], [
                'field_id' => $attribute['id'],
                'slug' =>  $attribute['slug'],
                'type' => $attribute['type'],
                $this->attributeValueColumn($attribute) => $this->attributeValue($attribute),
                'order' => $index,
            ]);

        if ($attribute['type'] === 'image') {
            Media::setUsesForModel($attribute['value'] ?? [], $value);
        }
    }

    private function attributeValueColumn(array $attribute): string
    {
        return match ($attribute['type']) {
            'image', 'editor' => 'value_text',
            'number' => 'value_float',
            'datetime' => 'value_datetime',
            default => 'value',
        };
    }

    private function attributeValue(array $attribute)
    {
        return match ($attribute['type']) {
            'image' => json_encode($attribute['value']),
            default => $attribute['value']
        };
    }
}
