<?php

namespace SEOAIC\DB;

use Exception;
use SEOAIC\traits\WPDB;

class KeywordsPostsTable
{
    use WPDB;

    public const OLD_TABLE_NAME = 'seoaic_keywords_posts';
    public const VERSION_OPTION_NAME = 'seoaic_keywords_posts_version';
    public const TABLE_NAME_VERSION = '2.0';

    public $tableName = '';

    private static $instances = [];

    protected function __construct() {
        $this->tableName = $this->getTableName();
    }

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

        if (!isset(self::$instances[$subclass])) {
            self::$instances[$subclass] = new self();
        }

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

    private function getNewTableName()
    {
        global $wpdb;

        $newTableName = $wpdb->prefix . self::OLD_TABLE_NAME;

        return $newTableName;
    }

    private function getVersion()
    {
        global $SEOAIC_OPTIONS;

        return !empty($SEOAIC_OPTIONS[self::VERSION_OPTION_NAME]) ? $SEOAIC_OPTIONS[self::VERSION_OPTION_NAME] : '';
    }

    private function setVersion($version)
    {
        global $SEOAIC;

        $SEOAIC->set_option(self::VERSION_OPTION_NAME, $version);
    }

    public function doNewTableNameMigration()
    {
        try {
            if (self::TABLE_NAME_VERSION != $this->getVersion()) {
                self::createIfNotExists($this->getNewTableName());
                $this->truncate($this->getNewTableName());
                $result = $this->migrateTableData(self::OLD_TABLE_NAME, $this->getNewTableName());

                if ($result) {
                    $this->setVersion(self::TABLE_NAME_VERSION);
                }

                return $result;
            }
        } catch(Exception $e) {
            error_log('[Exception]. Error: '.print_r($e->getMessage(), true));
        }

        return false;
    }

    /**
     * Obtains the actual table name, depending on version
     */
    public function getTableName()
    {
        if ($this->existsTable(self::OLD_TABLE_NAME)) {
            if (self::TABLE_NAME_VERSION == $this->getVersion()) {
                return $this->getNewTableName();
            } else {
                return self::OLD_TABLE_NAME;
            }
        }

        return $this->getNewTableName();
    }

    public static function createIfNotExists($tableName='')
    {
        $self = self::getInstance();
        $tableName = !empty($tableName) ? $tableName : $self->getNewTableName();
        $columns = "
            id bigint(20) unsigned NOT NULL auto_increment,
            keyword_id bigint(20) unsigned NOT NULL,
            post_id bigint(20) unsigned NOT NULL,
            PRIMARY KEY  (id),
            KEY keyword_id (keyword_id),
            KEY post_id (post_id)";

        return $self->createIfNotExistsTable($tableName, $columns);
    }

    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 static function dropOldIfExists()
    {
        $self = self::getInstance();
        if ($self->existsTable(self::OLD_TABLE_NAME)) {
            $self->dropTable(self::OLD_TABLE_NAME);
        }
    }

    public static function isNewTableNameMigrationNeeded()
    {
        $self = self::getInstance();
        $oldTableExists = $self->existsTable(self::OLD_TABLE_NAME);
        $newTableExists = $self->existsTable($self->getNewTableName());
        $currentVersion = $self->getVersion();

        return $oldTableExists
            && (
                !$newTableExists
                || self::TABLE_NAME_VERSION != $currentVersion
            );
    }
}
