<?php

namespace App\ImportEmailBookings;

class EmailsStorage
{

	/**
	 * The DB table name.
	 * @var string
	 */
	private string $dbTable;

	/**
	 * Populates the DB table name.
	 */
	public function __construct()
	{
		global $DBTEmailBookings;
		$this->dbTable = $DBTEmailBookings;
	}


	/**
	 * Inserts a new record with a new email that was successfully parsed and imported as imported order.
	 * @param string $account
	 * @param string $idEmail
	 * @param string $supplier
	 * @param int $idImportedOrder
	 */
	public function insert(string $account, string $idEmail,  string $supplier, int $idImportedOrder) :void
	{

		$CFG = \Engine\Loader_Cfg::getInstance()->getGlobal();
		// CHECK INPUT ----------------------------------------------------------------------------
		if (!\DB::isInsideTransaction()) {
			throw new \Exception('You must be inside a transaction to insert a new booking email.');
		}
		if (!key_exists($account, $CFG['loadEmailBookings']['accountsList'])) {
			throw new \RuntimeException('Account code not set or invalid.');
		}
		if (!strlen($idEmail)) {
			throw new \RuntimeException('Email id not set.');
		}
		if (!in_array($supplier, $CFG['loadEmailBookings']['suppliersList'])) {
			throw new \RuntimeException('Supplier is not set or valid.');
		}

		// check for duplicates
		if ($this->getDetails($account, $idEmail, true)) {
			throw new \RuntimeException('Email id is already imported.');
		}

		// INSERT NEW RECORD ----------------------------------------------------------------------
		$db = \DB::getInstance();
		$sql = "
			INSERT INTO `{$this->dbTable}` (account, idEmail, supplier, idImportedOrder, importTime)
			VALUES (?, ?, ?, ?, ?)
		";
		$prepVars = [$account, $idEmail,  $supplier, $idImportedOrder, DATETIME];
		if (!$db->Execute($sql, $prepVars)) {
			throw new \DBException('Could not insert email in the history DB table.');
		}

	}

	/**
	 * Gets the details of an email based on account code and email id.
	 * Can also be used to see if an email has already been processed/imported.
	 * @param string $account
	 * @param string $idEmail
	 * @return array|false - the details of the email if found or false if not found
	 */
	public function getDetails(string $account, string $idEmail, bool $forUpdate) :array|false
	{

		$db = \DB::getInstance();

		$sql = "SELECT * FROM `{$this->dbTable}` WHERE account=? AND idEmail=?";
		if ($forUpdate) {
			$sql .= " FOR UPDATE";
		}
		$emailDetails = $db->GetRow($sql, [$account, $idEmail]);

		if ($db->ErrorNo()) {
			throw new \DBException('Could not get email message details.');
		}

		if (!$emailDetails) {
			return false;
		} else {
			return $emailDetails;
		}

	}

}
