<?php

namespace SHServ\Models;

class Timers extends \SHServ\Middleware\Model {

	public static $table_name = "shserv_timers";

	public function create_timer(String $timer_alias, String $scope_name, String $target_type, String $target_alias, Array $params, int $execute_at): bool {
		// Cancel any existing pending timer with same alias in same scope
		$existing = $this -> thin_builder() -> select(
			self::$table_name,
			[ "id" ],
			[
				[ "timer_alias", "=", $timer_alias ],
				"AND",
				[ "scope_name", "=", $scope_name ],
				"AND",
				[ "status", "=", "pending" ]
			]
		);

		if($existing) {
			$this -> thin_builder() -> update(
				self::$table_name,
				[ "status" => "cancelled" ],
				[ [ "id", "=", $existing[0]["id"] ] ]
			);
		}

		return $this -> thin_builder() -> insert(
			self::$table_name,
			[
				"timer_alias"  => $timer_alias,
				"scope_name"   => $scope_name,
				"target_type"  => $target_type,
				"target_alias" => $target_alias,
				"params"       => json_encode($params),
				"execute_at"   => date("Y-m-d H:i:s", $execute_at),
				"status"       => "pending",
				"created_at"   => date("Y-m-d H:i:s")
			]
		);
	}

	public function cancel_timer(String $timer_alias, String $scope_name): bool {
		return $this -> thin_builder() -> update(
			self::$table_name,
			[ "status" => "cancelled" ],
			[
				[ "timer_alias", "=", $timer_alias ],
				"AND",
				[ "scope_name", "=", $scope_name ],
				"AND",
				[ "status", "=", "pending" ]
			]
		);
	}

	public function cancel_by_alias(String $timer_alias): bool {
		return $this -> thin_builder() -> update(
			self::$table_name,
			[ "status" => "cancelled" ],
			[
				[ "timer_alias", "=", $timer_alias ],
				"AND",
				[ "status", "=", "pending" ]
			]
		);
	}

	public function get_pending_timers(): Array {
		$result = $this -> thin_builder() -> select(
			self::$table_name,
			[],
			[
				[ "status", "=", "pending" ],
				"AND",
				[ "execute_at", "<=", date("Y-m-d H:i:s") ]
			],
			[ "execute_at" ],
			"ASC"
		);

		return $result ?: [];
	}

	public function mark_status(int $id, String $status, ?String $error_message = null): bool {
		$data = [ "status" => $status ];

		if($status === "executed") {
			$data["executed_at"] = date("Y-m-d H:i:s");
		}

		if($error_message !== null) {
			$data["error_message"] = $error_message;
		}

		return $this -> thin_builder() -> update(
			self::$table_name,
			$data,
			[ [ "id", "=", $id ] ]
		);
	}

	public function get_timers(?String $status = null, int $limit = 100): Array {
		$where = [];

		if($status !== null) {
			$where = [ [ "status", "=", $status ] ];
		}

		$result = $this -> thin_builder() -> select(
			self::$table_name,
			[],
			$where,
			[ "created_at" ],
			"DESC",
			[ 0, $limit ]
		);

		return $result ?: [];
	}
}
