<?php

namespace Lucent\Record;

use Illuminate\Contracts\Session\Session;
use Lucent\Query\Query;

class Manager
{

    public array $records = [];
    public Session $session;

    public function fromSession(Session $session): Manager
    {
        $this->session = $session;
        $this->records = $session->get("manager") ?? [];
        return $this;
    }


    public function __construct(
        private readonly Query $query
    )
    {
    }

    /**
     * @param string[] $records
     */

    public function addRecords(array $records): Manager
    {
        $this->records = $records;
        return $this;

    }

    public function push(string $recordId): Manager
    {

        $records = $this->getIdsExcept($recordId);
        $records[] = $recordId;
        $records = array_unique($records);
        $records = array_values($records);
        $records = array_slice($records, -5);
        $records = array_values($records);
        $this->records = $records;
        $this->save();
        return $this;
    }

    private function save(): void
    {

        $this->session->put("manager", $this->records);

    }

    public function getIdsExcept(?string $id): array
    {
        return collect($this->records)->filter(fn($arec) => $arec !== $id)->values()->toArray();
    }

    /**
     * @param QueryRecord[] $records
     * @return QueryRecord[] $records
     */
    public function order(array $records): array
    {
        $recordsById = collect($records)->keyBy("id")->toArray();
        return collect($this->records)->reverse()->values()->reduce(function ($carry, $arecId) use ($recordsById) {
            if (isset($recordsById[$arecId])) {
                $carry[] = $recordsById[$arecId];
            }
            return $carry;
        }, []);
    }


    public function getRecords(?string $ignoreId = null): array
    {

        $graph = $this->query
            ->filter(["id_in" => $this->getIdsExcept($ignoreId)])
            ->limit(7)
            ->run();



        return $this->order($graph->records->toArray());
    }
}
