<?php

namespace SEOAIC\DB;

use SEOAIC\traits\WPDB;

abstract class AbstractTable
{
    use WPDB {
        getById as wpdbGetById;
        getByField as wpdbGetByField;
    }

    protected static $instances = [];
    public $tableName = '';
    protected $versionField;
    protected $tableVersion;

    public function __construct()
    {
        if (!empty($this->tableVersion)) {
            $installedVersion = get_option($this->versionField);

            if (false === $installedVersion) {
                update_option($this->versionField, $this->tableVersion);
            }

            if ($installedVersion != $this->tableVersion) {
                $this->runUpdate($this->tableVersion);
            }
        }
    }

    public static function getInstance()
    {
        $subclass = self::class;

        if (!isset(self::$instances[$subclass])) {
            $class = get_called_class();

            self::$instances[$subclass] = new $class();
        }

        return self::$instances[$subclass];
    }

    public function getTableName()
    {
        return $this->tableName;
    }

    protected function runUpdate(string $ver)
    {
        $funcName = 'update_' . str_replace('.', '_', $ver);

        if (method_exists($this, $funcName)) {
            $this->$funcName();
        }
    }

    abstract public static function createIfNotExists($tableName='');

    public static function truncate($tableName='')
    {
        $self = self::getInstance();
        $tableName = !empty($tableName) ? $tableName : $self->tableName;
        $self->truncateTable($tableName);
    }

    public static function drop()
    {
        $self = self::getInstance();
        $tableName = !empty($tableName) ? $tableName : $self->tableName;
        $self->dropTable($tableName);
    }

    public function getAllData()
    {
        return $this->getAll($this->tableName);
    }

    public function getById(int $id)
    {
        return $this->wpdbGetById($this->tableName, $id);
    }

    public function getByField(string $field, $value)
    {
        return $this->wpdbGetByField($this->tableName, $field, $value);
    }

    public function insertData(array $data)
    {
        return $this->insert($this->tableName, $data);
    }

    public function updateData(array $data, array $where)
    {
        return $this->update($this->tableName, $data, $where);
    }

    public function deleteByField(array $conditions)
    {
        return $this->deleteAllByField($this->tableName, $conditions);
    }
}