<?php

namespace App;

use App\Contracts\AbleToSyncContentElements;
use App\Contracts\InteractsWithContentSync;
use App\Traits\EnsuresVehicleAttribute;
use App\Traits\RetrievesFieldData;
use App\Traits\SavesContent;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Mtc\ContentManager\Facades\Media;
use Mtc\MercuryDataModels\VehicleTrim;

class VehicleTrimRepository implements InteractsWithContentSync, AbleToSyncContentElements
{
    use SavesContent;
    use SavesSeoData;
    use RetrievesFieldData;
    use EnsuresVehicleAttribute;

    protected function elementParentColumnName(): string
    {
        return 'trim_id';
    }

    protected function contentOwnerType(): string
    {
        return 'trim-version';
    }

    protected function getQuery(): Builder
    {
        return VehicleTrim::query();
    }

    public function save(VehicleTrim $trim, Request $request): void
    {
        $this->saveContent($trim, $request->input('content', []));

        $trim->slug = $request->input('seo.slug') ?? $trim->slug;
        $trim->fill($request->except([
            'data', 'content', 'structure_in_sync', 'extra', 'seo', 'site_url',
            'image', 'image_uses', 'listing_image', 'listing_image_uses',
        ]));
        $trim->save();

        if (empty($request->input('image'))) {
            $trim->mediaUses()->where('primary', true)->delete();
        } else {
            $trim->mediaUses()
                ->where('primary', true)
                ->whereNotIn('media_id', $request->input('image'))
                ->delete();

            Media::setUsesForModel(
                $request->input('image'),
                $trim,
                ['primary' => true],
                false
            );
        }

        if (empty($request->input('listing_image'))) {
            $trim->mediaUses()->where('primary', false)->delete();
        } else {
            $trim->mediaUses()
                ->where('primary', false)
                ->whereNotIn('media_id', $request->input('listing_image'))
                ->delete();

            Media::setUsesForModel(
                $request->input('listing_image'),
                $trim,
                ['flags' => ['listing' => true]],
                false
            );
        }

        if ($request->filled('seo')) {
            $this->saveSeo($trim, $request->input('seo', []));
        }

        collect($request->input('extra', []))
            ->filter(fn ($attribute) => isset($attribute['value']) && empty($attribute['readonly']))
            ->each(fn ($attribute) => $this->saveAttributeValue($trim, $attribute));
    }

    public function saveContent(VehicleTrim $trim, array $content): void
    {
        $this->dropOrphanedContent($trim, $this->getFlatContentElementIds($content));
        collect($content)
            ->each(fn ($element, $index) => $this->saveContentElement($trim, $element, $index));
    }

    public function importRecord(array $entry): bool
    {
        $vehicleTrim = VehicleTrim::query()->create($entry);

        return $vehicleTrim->exists;
    }

    public function canBeImported(array $entry): bool
    {
        return !VehicleTrim::query()
            ->where('name', $entry['name'])
            ->exists();
    }

    public function exportToRemote(array $selections): array
    {
        return VehicleTrim::query()->newQuery()
            ->select([
                'name',
                'make_id',
                'active',
                'model_id',
                'fuel_types',
                'colours',
                'transmission_types',
                'mpg',
                'emissions',
                'engine_size',
                'bhp',
                'zero_to_sixty',
                'doors',
                'seats',
                'battery_size',
                'range_miles',
                'battery_charge_time',
                'battery_quick_charge_time',
                'wheelbase',
            ])
            ->whereIn('id', $selections)
            ->get()
            ->toArray();
    }

    public function checkImportEntryValidity(array $dataEntry, array $allEntries): array
    {
        $vehicleTrimExists = VehicleTrim::query()
            ->where('name', $dataEntry['name'])
            ->exists();

        $errors = [];
        if ($vehicleTrimExists) {
            $errors[] = __('validation.import_name_taken', ['name' => $dataEntry['name']]);
        }

        return [
            'data' => $dataEntry,
            'errors' => $errors,
        ];
    }
}
