<?php

/**
 * Class For Database Migration
 *
 * @category Database
 * @author   BitCode Developer <developer@bitcode.pro>
 */

namespace BitCode\BitForm\Core\Database;

use BitCode\BitForm\Core\Util\Log;

/**
 * Database Migration
 */
final class DB
{
  /**
   * Undocumented function
   *
   * @return void
   */
  public static function migrate()
  {
    global $wpdb;
    global $bitforms_db_version;
    $collate = '';

    if ($wpdb->has_cap('collation')) {
      if (!empty($wpdb->charset)) {
        $collate .= "DEFAULT CHARACTER SET $wpdb->charset";
      }

      if (!empty($wpdb->collate)) {
        $collate .= " COLLATE $wpdb->collate";
      }
    }

    $max_index_length = 191;

    $table_schema = [
      "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}bitforms_reports` (
                `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
                `category` varchar(50)  NOT NULL,
                `type` varchar(20)  NOT NULL,
                `context` varchar(20)  NOT NULL,
                `details` longtext DEFAULT NULL,
                `isDefault` tinyint(1) DEFAULT 0,/* 0 not default, 1 default */
                `user_id` bigint(20) unsigned DEFAULT NULL,
                `user_ip` int(11) unsigned DEFAULT NULL,
                `user_device` varchar(50) DEFAULT NULL,
                `created_at` datetime DEFAULT NULL,
                `updated_at` datetime DEFAULT NULL,
                PRIMARY KEY (`id`)
            ) $collate;",

      "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}bitforms_form` (
                `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
                `form_name` varchar(255) DEFAULT NULL,
                `form_content` longtext DEFAULT NULL,
                `builder_helper_state` longtext DEFAULT NULL,
                `atomic_class_map` longtext DEFAULT NULL,
                `generated_script_page_ids` longtext DEFAULT NULL,
                `user_id` bigint(20) unsigned DEFAULT NULL,
                `user_ip` int(11) unsigned DEFAULT NULL,
                `views` int(11) unsigned DEFAULT 0,
                `entries` int(11) unsigned DEFAULT 0,
                `user_device` varchar(50) DEFAULT NULL,
                `status` tinyint(1) DEFAULT 1,/* 0 not published, 1 published,  2 trashed */
                `created_at` datetime DEFAULT NULL,
                `updated_at` datetime DEFAULT NULL,
                PRIMARY KEY (`id`)
            ) $collate;",

      "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}bitforms_workflows` (
                `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
                `workflow_name` varchar(255) NOT NULL,
                `workflow_type` varchar(50) NOT NULL,
                `workflow_run` varchar(50) NOT NULL,
                `workflow_behaviour` varchar(25) NOT NULL,
                `workflow_condition` longtext DEFAULT NULL,
                `workflow_info` longtext DEFAULT NULL,
                `workflow_order` int(11) unsigned DEFAULT NULL,
                `workflow_status` tinyint(1) DEFAULT 1,/* 0 disable, 1 enable,  2 enable in field settings */
                `form_id` bigint(20) unsigned DEFAULT NULL,
                `user_id` bigint(20) unsigned DEFAULT NULL,
                `user_ip` int(11) unsigned DEFAULT NULL,
                `user_location` text DEFAULT NULL,
                `user_device` varchar(50) DEFAULT NULL,
                `created_at` datetime DEFAULT NULL,
                `updated_at` datetime DEFAULT NULL,
                PRIMARY KEY (`id`),
                KEY `form_id` (`form_id`)
            ) $collate;",

      "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}bitforms_success_messages` (
                `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
                `message_title` varchar(255) DEFAULT NULL,
                `message_content` longtext DEFAULT NULL,
                `message_config` longtext DEFAULT NULL,
                `form_id` bigint(20) unsigned DEFAULT NULL,
                `user_id` bigint(20) unsigned DEFAULT NULL,
                `user_ip` int(11) unsigned DEFAULT NULL,
                `created_at` datetime DEFAULT NULL,
                `updated_at` datetime DEFAULT NULL,
                PRIMARY KEY (`id`)
            ) $collate;",

      "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}bitforms_email_template` (
                `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
                `title` text DEFAULT NULL,
                `sub` text DEFAULT NULL,
                `body` longtext DEFAULT NULL,
                `form_id` bigint(20) unsigned DEFAULT NULL,
                `user_id` bigint(20) unsigned DEFAULT NULL,
                `user_ip` int(11) unsigned DEFAULT NULL,
                `created_at` datetime DEFAULT NULL,
                `updated_at` datetime DEFAULT NULL,
                PRIMARY KEY (`id`)
            ) $collate;",

      "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}bitforms_integration` (
                `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
                `category` varchar(50)  NOT NULL,
                `integration_name` varchar(255) DEFAULT NULL,
                `integration_type` varchar(50)  NOT NULL,
                `integration_details` longtext DEFAULT NULL,
                `form_id` bigint(20) unsigned DEFAULT NULL, /* form_id = 0 means all/app */
                `user_id` bigint(20) unsigned DEFAULT NULL,
                `user_ip` int(11) unsigned DEFAULT NULL,
                `status` tinyint(1) DEFAULT 1,/* 0 disabled, 1 published,  2 trashed */
                `created_at` datetime DEFAULT NULL,
                `updated_at` datetime DEFAULT NULL,
                PRIMARY KEY (`id`)
            ) $collate;",

      "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}bitforms_form_entries` (
                `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
                `form_id` bigint(20) unsigned DEFAULT NULL,
                `user_id` bigint(20) unsigned DEFAULT NULL,
                `user_ip` varchar(255) DEFAULT NULL,
                `user_location` text DEFAULT NULL,
                `user_device` varchar(50) DEFAULT NULL,
                `referer` TEXT DEFAULT NULL,
                `status` tinyint(1) DEFAULT 0,/* 0 not viewed, 1 viewed,  2 trashed */
                `created_at` datetime DEFAULT NULL,
                `updated_at` datetime DEFAULT NULL,
                PRIMARY KEY (`id`),
                KEY `form_id` (`form_id`)
            ) $collate;",

      "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}bitforms_form_entrymeta` (
                `meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
                `bitforms_form_entry_id` bigint(20) unsigned DEFAULT NULL,
                `meta_key` varchar(255) DEFAULT NULL,
                `meta_value` longtext,
                PRIMARY KEY (`meta_id`),
                KEY `meta_key` (`meta_key`({$max_index_length})),
                KEY `entry_id` (`bitforms_form_entry_id`)
            ) $collate;",

      "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}bitforms_form_entry_log` (
                `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
                `user_id` int(11) NOT NULL,
                `log_type` varchar(50) DEFAULT NULL,
                `ip` int(11) DEFAULT NULL,
                `action_type` varchar(50) DEFAULT NULL,
                `form_entry_id` bigint(20) DEFAULT NULL,
                `form_id` bigint(20) DEFAULT NULL,
                `content` longtext,
                `created_at` DATETIME NOT NULL,
                PRIMARY KEY (`id`),
                KEY `form_id` (`form_id`),
                KEY `form_entry_id` (`form_entry_id`)
            ) $collate;",

      "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}bitforms_form_log_details` (
                `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
                `log_id` bigint(20) NOT NULL,
                `integration_id` bigint(20) DEFAULT NULL,
                `api_type` varchar(255) DEFAULT NULL,
                `response_type` varchar(50) DEFAULT NULL,
                `response_obj` LONGTEXT DEFAULT NULL,
                `created_at` DATETIME NOT NULL,
                PRIMARY KEY (`id`),
                KEY `log_id` (`log_id`),
                KEY `integration_id` (`integration_id`)
            ) $collate;",
      "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}bitforms_form_entry_relatedinfo` (
                `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
                `info_type` VARCHAR(50) NOT NULL,
                `info_details` LONGTEXT NULL,
                `form_id` BIGINT(20) UNSIGNED NOT NULL,
                `entry_id` BIGINT(20) UNSIGNED NOT NULL,
                `user_id` BIGINT(20) UNSIGNED NULL DEFAULT NULL,
                `user_ip` INT(11) UNSIGNED NULL DEFAULT NULL,
                `status` INT(1) UNSIGNED NOT NULL DEFAULT '1',
                `created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
                `updated_at` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
                PRIMARY KEY (`id`),
                KEY `form_id` (`form_id`),
                KEY `entry_id` (`entry_id`)
            ) $collate;"
    ];

    try {
      include_once ABSPATH . 'wp-admin/includes/upgrade.php';
      foreach ($table_schema as $table) {
        dbDelta($table);
      }
      $installed_db_version = get_option('bitforms_db_version');
      if ($installed_db_version && version_compare('1.1', $installed_db_version, '>=')) {
        // if new db version is equal or higher than 1.1
        // Schema migration: table name interpolation only (no user input). $wpdb->prepare() cannot parameterize DDL statements.
        try {
          $wpdb->query("ALTER TABLE `{$wpdb->prefix}bitforms_form_entry_log`
                MODIFY `log_type` VARCHAR(50) NULL DEFAULT NULL,
                MODIFY `created_at` DATETIME NOT NULL,
                CHANGE COLUMN `meta_key` `content` LONGTEXT NULL,
                ADD COLUMN `action_type` VARCHAR(50) NULL DEFAULT NULL,
                ADD COLUMN `content` LONGTEXT NULL AFTER `action_type`");
        } catch (\Exception $e) {
          Log::debug_log("Update failed: {$e->getMessage()} in query: ALTER TABLE `{$wpdb->prefix}bitforms_form_entry_log`...");
        }
        try {
          $wpdb->query("ALTER TABLE `{$wpdb->prefix}bitforms_form_log_details`
                MODIFY `api_type` VARCHAR(255) NULL DEFAULT NULL,
                MODIFY `response_obj` LONGTEXT NULL,
                MODIFY `created_at` DATETIME NOT NULL");
        } catch (\Exception $e) {
          Log::debug_log("Update failed: {$e->getMessage()} in query: ALTER TABLE `{$wpdb->prefix}bitforms_form_log_details`...");
        }
      }
      if ($installed_db_version && version_compare('1.3', $installed_db_version, '>=')) {
        // if new db version is equal or higher than 1.3
        $wpdb->query("ALTER TABLE `{$wpdb->prefix}bitforms_form_entries` MODIFY `user_ip` VARCHAR(255) NULL DEFAULT NULL");
      }

      if ($installed_db_version && version_compare('2.0', $installed_db_version, '>=')) {
        if (null === $wpdb->get_var("SHOW COLUMNS FROM `{$wpdb->prefix}bitforms_success_messages` LIKE 'message_config'")) {
          $wpdb->query(
            "ALTER TABLE `{$wpdb->prefix}bitforms_success_messages`
                ADD COLUMN `message_config` LONGTEXT NULL AFTER `message_content`"
          );
        }
        if (null === $wpdb->get_var("SHOW COLUMNS FROM `{$wpdb->prefix}bitforms_form` LIKE 'builder_helper_state'")) {
          $wpdb->query(
            "ALTER TABLE `{$wpdb->prefix}bitforms_form`
                ADD COLUMN `builder_helper_state` LONGTEXT NULL AFTER `form_content`,
                ADD COLUMN `atomic_class_map` LONGTEXT NULL AFTER `builder_helper_state`,
                ADD COLUMN `generated_script_page_ids` LONGTEXT NULL AFTER `atomic_class_map`"
          );
        }
        if (null === $wpdb->get_var("SHOW COLUMNS FROM `{$wpdb->prefix}bitforms_workflows` LIKE 'workflow_order'")) {
          $wpdb->query(
            "ALTER TABLE `{$wpdb->prefix}bitforms_workflows`
                ADD COLUMN `workflow_order` INT(11) DEFAULT NULL AFTER `workflow_condition`"
          );
        }
      }

      if ($installed_db_version && version_compare('2.2', $installed_db_version, '>=')) {
        if (null === $wpdb->get_var("SHOW COLUMNS FROM `{$wpdb->prefix}bitforms_form_entries` LIKE 'referer'")) {
          $wpdb->query(
            "ALTER TABLE `{$wpdb->prefix}bitforms_form_entries`
                ADD COLUMN `referer` TEXT NULL DEFAULT NULL"
          );
        }
      }

      if ($installed_db_version && version_compare('2.4', $installed_db_version, '>=')) {
        if (null === $wpdb->get_var("SHOW COLUMNS FROM `{$wpdb->prefix}bitforms_workflows` LIKE 'workflow_status'")) {
          $wpdb->query(
            "ALTER TABLE `{$wpdb->prefix}bitforms_workflows`
                ADD COLUMN `workflow_status` TINYINT(1) DEFAULT 1 NOT NULL AFTER `workflow_order`"
          );
        }
      }

      // add workflow_info column if not exists
      if ($installed_db_version && version_compare('3.0', $installed_db_version, '>=')) {
        $table_name = $wpdb->prefix . 'bitforms_workflows';
        if (null === $wpdb->get_var("SHOW COLUMNS FROM `{$table_name}` LIKE 'workflow_info'")) {
          $wpdb->query(
            "ALTER TABLE `{$table_name}`
                ADD COLUMN `workflow_info` LONGTEXT NULL AFTER `workflow_condition`"
          );
        }
      }

      update_option('bitforms_db_version', $bitforms_db_version, true);
    } catch (\Exception $e) {
      // Log the error to a file or the database
      Log::debug_log('Error during DB migration: ' . $e->getMessage());
    }
  }
}
