<?php

namespace App\Services\Forms\Registries;

use App\Models\Asset;
use App\Models\Objects\FieldType;
use App\Models\Objects\ObjectType;
use App\Models\Registries\Category;
use App\Models\Registries\Entry;
use App\Models\Registries\Registry;
use App\Services\Forms\FormsService;
use App\Transformers\Assets\AssetTransformer;
use App\Transformers\Objects\FieldTransformer;
use App\Transformers\Objects\ObjectPropertyTransformer;
use App\Transformers\Registries\EntryTransformer;
use Illuminate\Http\JsonResponse;

class EntryForms extends FormsService {
    public array $formTitles = ['create' => 'Создание записи', 'update' => 'Редактирование записи'];

    public function form(?string $id = null, array $data = []): array {
        $registry = Registry::byUuid($data['registry'] ?? null)->firstOrFail();
        $model = Entry::byUuid($id)->first();
        $groups = [
            ['name' => 'common', 'title' => 'Общие сведения', 'fields' => $this->commonGroupFields($model)]
        ];
        if ($registry->parsedType['options']['states'] ?? null) $groups[] = ['name' => 'dates', 'title' => 'Сроки действия', 'fields' => $this->datesGroupFields($model)];
        if ($objectType = $registry->parsedType['options']['properties'] ?? null) $groups[] = ['name' => 'specific', 'title' => 'Подробности', 'fields' => $this->specificGroupFields($objectType, $model)];
        return ['title' => $this->formTitle($model), 'data' => $groups];
    }

    public function commonGroupFields(?Entry $model): array {
        $fields = [
            [
                'name' => 'name',
                'title' => 'Наименование записи',
                'type' => FieldType::STRING,
                'required' => true,
                'value' => $model->name ?? null
            ],
            [
                'name' => 'number',
                'title' => 'Номер записи',
                'type' => FieldType::STRING,
                'value' => $model->number ?? null
            ],
            [
                'name' => 'asset',
                'title' => 'Документ',
                'type' => FieldType::DOCUMENT,
                'value' => ($asset = $model->asset ?? null) ? fractal($asset, new AssetTransformer()) : null
            ]
        ];
        return ['data' => $fields];
    }

    public function datesGroupFields(?Entry $model): array {
        $fields = [
            [
                'name' => 'active_since',
                'title' => 'Дата начала действия',
                'type' => FieldType::DATE,
                'required' => true,
                'value' => ($v = $model->active_since ?? null) ? $v->toIso8601String() : null
            ],
            [
                'name' => 'active_till',
                'title' => 'Дата окончания действия',
                'type' => FieldType::DATE,
                'value' => ($v = $model->active_till ?? null) ? $v->toIso8601String() : null
            ],
            [
                'name' => 'suspended_since',
                'title' => 'Дата начала приостановки',
                'type' => FieldType::DATE,
                'value' => ($v = $model->suspended_since ?? null) ? $v->toIso8601String() : null
            ],
            [
                'name' => 'suspended_till',
                'title' => 'Дата окончания приостановки',
                'type' => FieldType::DATE,
                'value' => ($v = $model->suspended_till ?? null) ? $v->toIso8601String() : null
            ],
            [
                'name' => 'cancelled_at',
                'title' => 'Дата отмены',
                'type' => FieldType::DATE,
                'value' => ($v = $model->cancelled_at ?? null) ? $v->toIso8601String() : null
            ],
        ];
        return ['data' => $fields];
    }


    public function specificGroupFields(string $objectType, ?Entry $model): array {
        $object = $model->properties ?? null;
        return $object ? fractal($object->groups->first()->fields, new ObjectPropertyTransformer($object))->toArray() :
            fractal(ObjectType::byName($objectType)->first()->groups()->first()->fields, new FieldTransformer())->toArray();
    }




    public function store(array $data): ?JsonResponse {
        $registry = Registry::byUuid($data['registry'] ?? null)->firstOrFail();
        $category = Category::byUuid($data['category'] ?? null)->first();
        $data['asset_id'] = ($asset = Asset::byUuid($data['asset'] ?? null)->first()) ? $asset->id : null;
        $data['category_id'] = $category->id ?? 0;
        $model = $registry->entries()->create($data);
        if ($object = $model->properties ?? null) $object->setValues($data);
        return fractal($model, new EntryTransformer())->respond();
    }

    public function update(string $id, array $data): ?JsonResponse {
        $model = Entry::byUuid($id)->firstOrFail();
        $data['asset_id'] = ($asset = Asset::byUuid($data['asset'] ?? null)->first()) ? $asset->id : null;
        $model->update($data);
        if ($object = $model->properties ?? null) $object->setValues($data);
        return fractal($model->fresh(), new EntryTransformer())->respond();
    }
}
