<?php

	namespace VLW\Database\Models\Work;

	use \VV;
	use \vlw\MySQL\Order;
	use \DateTimeImmutable;

	use VLW\Helpers\UUID;
	use VLW\Database\Database;
	use VLW\Database\Models\Model;
	use VLW\Database\Models\Work\{Tag, Action};
	use VLW\Database\Tables\Work\Work as WorkTable;

	require_once VV::root("src/Helpers/UUID.php");
	require_once VV::root("src/Database/Database.php");
	require_once VV::root("src/Database/Models/Model.php");
	require_once VV::root("src/Database/Models/Work/Tag.php");
	require_once VV::root("src/Database/Tables/Work/Work.php");
	require_once VV::root("src/Database/Models/Work/Action.php");

	class Work extends Model {
		final public static function new(string $namespace): self {
			$id = UUID::v4();

			if (!parent::create(WorkTable::TABLE, [
				WorkTable::ID->value           => $id,
				WorkTable::NAMESPACE->value    => $namespace,
				WorkTable::TITLE->value        => $pathname,
				WorkTable::SUMMARY->value      => null,
				WorkTable::DATE_CREATED->value => date(parent::DATE_FORMAT)
			])) { throw new Exception("Failed to create Work entity"); }

			return new Work($id);
		}

		final public static function all(): array {
			return array_map(fn(array $work): Work => new Work($work[WorkTable::ID->value]), new Database()
				->from(WorkTable::TABLE)
				->order([WorkTable::DATE_CREATED->value => Order::DESC])
				->select(WorkTable::ID->value)
				->fetch_all(MYSQLI_ASSOC)
			);
		}

		final public static function from(string $namespace): ?self {
			$work = new Database()
				->from(WorkTable::TABLE)
				->where([WorkTable::NAMESPACE->value => $namespace])
				->limit(1)
				->select(WorkTable::ID->value)
				->fetch_assoc();

			return $work ? new Work($work[WorkTable::ID->value]) : null;
		}

		public function __construct(public readonly string $id) {
			parent::__construct(WorkTable::TABLE, WorkTable::values(), [
				WorkTable::ID->value => $this->id
			]);
		}

		final public function tags(): array {
			return Tag::from($this);
		}

		final public function actions(): array {
			return Action::from($this);
		}

		final public string $namespace {
			get                     => $this->get(WorkTable::NAMESPACE->value);
			set (string $namespace) => $this->set(WorkTable::NAMESPACE->value, $namespace);
		}

		final public string $title {
			get                 => $this->get(WorkTable::TITLE->value);
			set (string $title) => $this->set(WorkTable::TITLE->value, $title);
		}

		final public ?string $summary {
			get                    => $this->get(WorkTable::SUMMARY->value);
			set (?string $summary) => $this->set(WorkTable::SUMMARY->value, $summary);
		}

		final public DateTimeImmutable $date_created {
			get                                   => new DateTimeImmutable($this->get(WorkTable::DATE_CREATED->value));
			set (DateTimeImmutable $date_created) => $this->set(WorkTable::DATE_CREATED->value, $date_created->format(parent::DATE_FORMAT));
		}
	}