<?php

namespace App\Http\Controllers\Api\Forms;

use App\Http\Controllers\Controller;
use App\Models\Objects\NirObject;
use App\Models\Objects\ObjectType;
use App\Services\Filters\FiltersService;
use App\Services\Forms\FormsService;
use App\Transformers\Objects\ObjectTransformer;
use App\Transformers\Objects\ObjectTypeTransformer;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class FormsController extends Controller {
    public function get(Request $request, $target, $type = null, $id = null) {
        if ($target === 'model') {
            $service = FormsService::getService($type);
            if ($request->user() || $service->unprotected) return $service->form($id, json_decode($request->get('extra_props'), true) ?? []);
            else return response()->json(['error' => 'Unauthenticated.'], 401);
            //return FormsService::getService($type)->form($id, json_decode($request->get('extra_props'), true) ?? []);
        } elseif ($object = NirObject::byUuid($id)->first()) {
            return fractal($object, new ObjectTransformer())->respond();
        } elseif ($objectType = ObjectType::byUuidOrName($type)->first()) {
            return fractal($objectType, new ObjectTypeTransformer())->respond();
        }
    }

    public function save(Request $request, $target, $type = null, $id = null) {
        if ($target === 'model') {
            return FormsService::getService($type)->save($request->all(), $id);
        } elseif ($object = NirObject::byUuid($id)->first()) {
            $object->setValues($request->all());
            return fractal($object->fresh(), new ObjectTransformer());
        } elseif ($objectType = ObjectType::byUuidOrName($type)->first()) {
            $object = $objectType->objects()->create();
            $object->setValues($request->all());
            $this->attachObject($object, $request->get('attach'));
            return fractal($object->fresh(), new ObjectTransformer());
        }
    }

    public function attachObject(NirObject $object, $attach) {
        if (($type = $attach['model_type'] ?? null) && ($className = Relation::$morphMap[$type] ?? null) && ($id = $attach['model_id'] ?? null)) {
            if ($model = $className::byUuid($id)->first()) $model->attachObject($object, $attach['ord'] ?? null, $attach['group'] ?? null);
        }
    }

    public function getFeedbackFormSupport(Request $request): ?JsonResponse {
        return ($objectType = ObjectType::byName('feedback-form-support')->first()) ? fractal($objectType, new ObjectTypeTransformer())->respond() : null;
    }
    public function saveFeedbackFormSupport(Request $request): ?JsonResponse {
        return FormsService::getService('feedback-form-support')->save($request->all());
    }



    public function filters(Request $request, $type) {
        $filters = collect(json_decode($request->get('filters', []), true));
        return ($service = FiltersService::getService($type)) ? $service->get($filters) : null;
    }

}
