<?php

namespace App;

use App\Contracts\InteractsWithContentSync;
use Illuminate\Support\Arr;
use Mtc\MercuryDataModels\Property;
use Mtc\MercuryDataModels\PropertyCategory;
use Mtc\MercuryDataModels\PropertyCategoryField;

class PropertyRepository implements InteractsWithContentSync
{
    public function importRecord(array $entry): bool
    {
        $propertyCategory = PropertyCategory::query()
            ->updateOrCreate(
                ['slug' => $entry['slug']],
                Arr::only($entry, new PropertyCategory()->getFillable())
            );

        if (!empty($entry['fields'])) {
            foreach ($entry['fields'] as $fieldEntry) {
                $field = PropertyCategoryField::query()->updateOrCreate(
                    ['slug' => $fieldEntry['slug']],
                    array_merge(
                        Arr::except($fieldEntry, ['id', 'category_id', 'values']),
                        ['category_id' => $propertyCategory->id]
                    )
                );

                if (!empty($entry['properties'])) {
                    foreach ($entry['properties'] as $propertyEntry) {
                        $property = $propertyCategory->properties()->updateOrCreate(
                            ['slug' => $propertyEntry['slug']],
                            array_merge(
                                Arr::except($propertyEntry, ['id', 'fields']),
                                ['category_id' => $propertyCategory->id]
                            )
                        );

                        if (!empty($fieldEntry['values'])) {
                            foreach ($fieldEntry['values'] as $valueEntry) {
                                if ($propertyEntry['id'] == $valueEntry['property_id']) {
                                    $field->values()->updateOrCreate(
                                        ['slug' => $valueEntry['slug']],
                                        array_merge(
                                            Arr::except($valueEntry, ['id', 'property_id', 'field_id']),
                                            ['property_id' => $property->id]
                                        )
                                    );
                                }
                            }
                        }
                    }
                }
            }
        } else {
            if (!empty($entry['properties'])) {
                foreach ($entry['properties'] as $propertyEntry) {
                    $property = $propertyCategory->properties()->updateOrCreate(
                        ['slug' => $propertyEntry['slug']],
                        array_merge(
                            Arr::except($propertyEntry, ['id', 'fields']),
                            ['category_id' => $propertyCategory->id]
                        )
                    );
                }
            }
        }

        return true;
    }

    public function canBeImported(array $entry): bool
    {
        if (!empty($entry['properties'])) {
            return true;
        }

        return false;
    }

    public function exportToRemote(array $selections): array
    {
        return PropertyCategory::query()
            ->with([
                'properties' => function ($query) use ($selections) {
                    $query->whereIn('id', $selections)
                        ->with('attributeValues');
                },
                'fields' => function ($query) {
                    $query->with('values');
                }
            ])
            ->whereHas('properties', function ($query) use ($selections) {
                $query->whereIn('id', $selections);
            })
            ->get()
            ->toArray();
    }

    public function checkImportEntryValidity(array $dataEntry, array $allEntries): array
    {
        $errors = [];

        if (!empty($dataEntry['properties'])) {
            foreach ($dataEntry['properties'] as $property) {
                $slug = $property['slug'] ?? null;

                if ($slug) {
                    $existingProperty = Property::query()->where('slug', $slug)->first();

                    if ($existingProperty) {
                        $errors[] = __('validation.import_slug_taken', ['slug' => $slug]);
                    }
                } else {
                    $errors[] = __('validation.import_property_slug_missing', ['slug' => $slug]);
                }
            }
        }

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