<?php

	use vlw\MySQL\Operators;
	use Reflect\{Response, Path, Call};
	use Reflect\Rules\{Ruleset, Rules, Type};

	use VLW\API\Endpoints;
	use VLW\Database\Database;
	use const VLW\SEARCH_QUERY_MAX_LENGTH;
	use VLW\Database\Tables\Search\{SearchTable, SearchCategoryEnum};
	use VLW\Database\Tables\Work\{WorkTable, ActionsTable};

	require_once Path::root("src/Consts.php");
	require_once Path::root("src/API/Endpoints.php");
	require_once Path::root("src/Database/Database.php");
	require_once Path::root("src/Database/Tables/Work/Work.php");
	require_once Path::root("src/Database/Tables/Work/Actions.php");
	require_once Path::root("src/Database/Tables/Search/Search.php");

	class POST_Search extends Database {
		protected Ruleset $ruleset;

		public function __construct() {
			$this->ruleset = new Ruleset(strict: true);
			$this->ruleset->validate_or_exit();

			parent::__construct();
		}

		private static function truncate_string(string $input): string {
			return substr($input, 0, SEARCH_QUERY_MAX_LENGTH);
		}

		private static function create_query(string $input): string {
			preg_match_all("/[a-zA-Z0-9]+/", $input, $matches);
			
			return self::truncate_string(strtolower(implode("", $matches[0])));
		}

		private function index_work(): void {
			foreach ((new Call(Endpoints::WORK->value))->get()->output() as $result) {
				$query = self::create_query(implode("", array_values($result)), 0, SEARCH_QUERY_MAX_LENGTH);

				// Get actions related to current result
				$actions = (new Call(Endpoints::WORK_ACTIONS->value))->params([
					ActionsTable::REF_WORK_ID->value => $result[WorkTable::ID->value]
				])->get()->output();

				$this->db->for(SearchTable::NAME)->insert([
					SearchTable::QUERY->value    => $query,
					SearchTable::ID->value       => crc32($query),
					SearchTable::TITLE->value    => self::truncate_string($result[WorkTable::TITLE->value]),
					SearchTable::SUMMARY->value  => self::truncate_string($result[WorkTable::SUMMARY->value]),
					SearchTable::CATEGORY->value => SearchCategoryEnum::WORK->name,
					// Use first action as link for search result
					SearchTable::HREF->value     => $actions
						? self::truncate_string($actions[0][ActionsTable::HREF->value])
						: null
				]);
			}
		}

		public function main(): Response {
			$this->index_work();
			return new Response();
		}
	}