<?php

namespace Lucent\Http\Controller\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Lucent\Channel\ChannelRepo;
use Lucent\LucentException;
use Lucent\Query\Query;
use Lucent\Record\RecordService;
use Lucent\Schema\Validator\ValidatorException;
use Throwable;
use function Lucent\Response\fail;
use function Lucent\Response\ok;

class RecordController extends Controller
{
    public function __construct(
        private readonly RecordService $recordService,
        private readonly Query         $query
    )
    {
    }

    public function records(Request $request)
    {
        $channel = ChannelRepo::current();
        $urlParams = $request->all();
        $sort = data_get($urlParams, "sort") ?? "-_sys.updatedAt";
        $filter = data_get($urlParams, "filter") ?? [];
        $arguments = array_merge([

        ], $filter);

        $skip = data_get($urlParams, "skip") ?? 0;
        $limit = data_get($urlParams, "limit") ?? 15;
        $queryResult = $this->query
            ->filter($arguments)
            ->limit($limit)
            ->skip($skip)
            ->sort($sort)
            ->childrenDepth($request->input("childrenDepth") ?? 1)
            ->parentsDepth($request->input("parentsDepth") ?? 0)
            ->runWithCount();

        $graph = $queryResult->getQueryRecords($channel->schemas);
        $total = $queryResult->getTotal();

        return ok([
            "graph" => $graph->toArray(),
            "sort" => $sort,
            "limit" => $limit,
            "skip" => $skip,
            "total" => $total,
        ]);
    }

    public function create(Request $request)
    {

        try {

            $recordId = $this->recordService->create(
                userId: $request->input("userId"),
                schemaName: $request->input("schema"),
                data: $request->input("data") ?? [],
                file: $request->input("file") ?? [],
                edges: $request->input("edges") ?? [],
                status: $request->input("status") ?? "draft",
                uploadFromUrl: $request->input("uploadFromUrl") ?? ""
            );

        } catch (ValidatorException $th) {
            return fail($th->getValidatorErrors());
        } catch (LucentException $th) {
            return fail($th);
        }
        return ok(["id" => $recordId]);
    }

    public function update(Request $request)
    {

        try {
            $this->recordService->update(
                userId: $request->input("userId"),
                id: $request->route("id"),
                data: $request->input("data"),
                status: $request->input("status"),
                edges: $request->input("edges") ?? [],
                updateEdges: false,
            );
        } catch (ValidatorException $th) {
            return fail($th->getValidatorErrors());
        } catch (LucentException $th) {
            return fail($th);
        } catch (Throwable $th) {
            if ($th->getCode() == 11000) {
                return fail("ID has to be unique in the channel");
            }
            return fail($th);
        }

        return ok();
    }

}
