<?php
namespace App\Alias;

use App\Contract\Auth;
use Stringy\Stringy;

class Model extends \Model
{
	public function getTable()
	{
		return parent::_get_table_name(static::class);
	}
	protected function log()
	{
		if (strpos(get_called_class(), 'Incoviba\\common\\') !== false) {
			return;
		}
		$user = Auth::User()->id;
		$orm = $this->orm;
		$ref = new \ReflectionObject($orm);
		if (!$ref->hasProperty('_dirty_fields')) {
			return;
		}
		$dirty = $ref->getProperty('_dirty_fields');
		$dirty->setAccessible(true);
		$new_values = $dirty->getValue($orm);
		$changes = array_combine(array_keys($new_values), array_fill(0, count($new_values), ['old' => '', 'new' => '']));
		if ($this->isNew()) {
			$old = (object) array_combine(array_keys($new_values), array_fill(0, count($new_values), ''));
		} else {
			$old = model(get_called_class())->findOne($this->{$this->getId()});
		}
		foreach ($new_values as $column => $value) {
			$changes[$column] = ['column' => $column, 'old' => $old->$column, 'new' => $value];
		}
		$action = '[' . get_called_class() . ']';
		doLog($user, $action, $changes);
	}
	public function getId()
	{
		if (property_exists(get_called_class(), '_id_column')) {
			return static::$_id_column;
		}
		return $this->id;
	}
	public function save()
	{
		$ref = new \ReflectionObject($this);
		if ($ref->hasProperty('_timestamps')) {
			$ref = $ref->getProperty('_timestamps');
			$ref->setAccessible(true);
			if ($ref->getValue()) {
				if ($this->is_new()) {
					$this->setExpr('created_at', 'NOW()');
				}
				$this->setExpr('updated_at', 'NOW()');
			}
		}
		if (!\ORM::getDb()->inTransaction()) {
			\ORM::getDb()->beginTransaction();
		}
		try {
			parent::save();
			if (\ORM::getDb()->inTransaction()) {
				\ORM::getDb()->commit();
			}
		} catch (\Exception $e) {
			if (\ORM::getDb()->inTransaction()) {
				\ORM::getDb()->rollBack();
			}
			throw $e;
		}
		$this->log();
	}
	public function __call($method, $args)
	{
		if (!method_exists($this, $method)) {
			$str = '' . Stringy::create($method)->underscored();
			if (method_exists($this, $str)) {
				return call_user_func_array([$this, $str], $args);
			}
			throw new \BadMethodCallException($method . ' not found in ' . get_class($this));
		}
		return call_user_func_array([$this, $str], $args);
	}
}
?>
