<?php

namespace Limb_Chatbot\Includes\Migrations;

use Limb_Chatbot\Includes\Chatbot_Tools\Seeders\Actions_Seeder;
use Limb_Chatbot\Includes\Data_Objects\Action;
use Limb_Chatbot\Includes\Data_Objects\Action_Callback;
use Limb_Chatbot\Includes\Data_Objects\Chatbot;
use Limb_Chatbot\Includes\Data_Objects\Parameter;

/**
 * Migration for version 1.0.4
 *
 * Creates the action system tables:
 * - lbaic_actions: Stores action definitions
 * - lbaic_parameters: Stores parameters for actions
 * - lbaic_action_callbacks: Stores callbacks associated with actions
 *
 * @since 1.0.4
 */
class Migration_1_0_4 extends Abstract_Migration {

	/**
	 * Get the target version this migration upgrades to.
	 *
	 * @return string
	 * @since 1.0.4
	 */
	public function get_version(): string {
		return '1.0.4';
	}

	/**
	 * Get migration description.
	 *
	 * @return string
	 * @since 1.0.4
	 */
	public function get_description(): string {
		return 'Create action system tables (actions, parameters, action_callbacks)';
	}

	/**
	 * Execute the migration.
	 *
	 * Creates three new tables for the action system:
	 * 1. lbaic_actions - Main actions table
	 * 2. lbaic_parameters - Parameters for actions
	 * 3. lbaic_action_callbacks - Callbacks associated with actions
	 *
	 * @return bool True on success, false on failure.
	 * @since 1.0.4
	 */
	public function up(): bool {
		$this->log( 'Starting migration 1.0.4 - Creating action system tables' );

		// Create actions table
		if ( ! $this->create_actions_table() ) {
			return false;
		}

		// Create parameters table
		if ( ! $this->create_parameters_table() ) {
			return false;
		}

		// Create action callbacks table
		if ( ! $this->create_action_callbacks_table() ) {
			return false;
		}

		// Seed the new actions
		$action_seeder = new Actions_Seeder();
		if ( ! $action_seeder->seed_contact_action() ) {
			return false;
		}

		$this->log( 'Migration 1.0.4 completed successfully - All action system tables created' );

		return true;
	}

	/**
	 * Create the lbaic_actions table.
	 *
	 * Stores action definitions with AI instructions and status.
	 *
	 * @return bool True on success, false on failure.
	 * @since 1.0.4
	 */
	private function create_actions_table(): bool {
		$table_name = $this->wpdb->prefix . 'lbaic_actions';

		// Check if table already exists
		if ( $this->table_exists( $table_name ) ) {
			$this->log( "Table {$table_name} already exists, skipping creation" );

			return true;
		}

		$collate = $this->wpdb->get_charset_collate();

		$sql = "CREATE TABLE `{$table_name}` (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			title VARCHAR(255) NOT NULL,
			name VARCHAR(255) NOT NULL,
			ai_instructions TEXT NULL,
			status TINYINT(1) DEFAULT 1 NOT NULL,
			created_at datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
			updated_at datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
			PRIMARY KEY (id),
			UNIQUE KEY name (name),
			UNIQUE KEY title (title),
			KEY `status` (status)
		) {$collate};";

		$results = $this->db_delta( $sql );

		// Verify table was created
		if ( ! $this->table_exists( $table_name ) ) {
			$this->log( "Failed to create table {$table_name}", 'error' );

			return false;
		}

		$this->log( "Successfully created table {$table_name}" );

		return true;
	}

	/**
	 * Create the lbaic_parameters table.
	 *
	 * Stores parameters associated with actions, including validation rules
	 * and configuration options.
	 *
	 * @return bool True on success, false on failure.
	 * @since 1.0.4
	 */
	private function create_parameters_table(): bool {
		$table_name = $this->wpdb->prefix . 'lbaic_parameters';

		// Check if table already exists
		if ( $this->table_exists( $table_name ) ) {
			$this->log( "Table {$table_name} already exists, skipping creation" );

			return true;
		}

		$collate = $this->wpdb->get_charset_collate();

		$sql = "CREATE TABLE `{$table_name}` (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			action_id BIGINT NOT NULL,
			name VARCHAR(255) NOT NULL,
			label VARCHAR(255) NOT NULL,
			type VARCHAR(255) NOT NULL DEFAULT 'text',
			`order` INT NOT NULL DEFAULT 1,
			question TEXT NULL,
			required VARCHAR(10) DEFAULT '0',
			default_value TEXT NULL,
			placeholder VARCHAR(255) NULL,
			validation_rules TEXT NULL,
			suggestions TEXT NULL,
			config TEXT NULL,
			PRIMARY KEY (id),
			KEY action_id (action_id),
			KEY `order` (`order`),
			KEY name (name)
		) {$collate};";

		$results = $this->db_delta( $sql );

		// Verify table was created
		if ( ! $this->table_exists( $table_name ) ) {
			$this->log( "Failed to create table {$table_name}", 'error' );

			return false;
		}

		$this->log( "Successfully created table {$table_name}" );

		return true;
	}

	/**
	 * Create the lbaic_action_callbacks table.
	 *
	 * Stores callbacks associated with actions, including configuration
	 * and execution order.
	 *
	 * @return bool True on success, false on failure.
	 * @since 1.0.4
	 */
	private function create_action_callbacks_table(): bool {
		$table_name = $this->wpdb->prefix . 'lbaic_action_callbacks';

		// Check if table already exists
		if ( $this->table_exists( $table_name ) ) {
			$this->log( "Table {$table_name} already exists, skipping creation" );

			return true;
		}

		$collate = $this->wpdb->get_charset_collate();

		$sql = "CREATE TABLE `{$table_name}` (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			action_id BIGINT UNSIGNED NOT NULL,
			name VARCHAR(255) NOT NULL,
			title VARCHAR(255) NOT NULL,
			description TEXT NULL,
			type VARCHAR(50) NOT NULL,
			config LONGTEXT NOT NULL,
			`order` INT NOT NULL DEFAULT 1,
			is_required TINYINT(1) DEFAULT 1 NOT NULL,
			status TINYINT(1) DEFAULT 1 NOT NULL,
			PRIMARY KEY (id),
			UNIQUE KEY name_action_unique (name, action_id),
			KEY action_id (action_id),
			KEY type (type),
			KEY `order` (`order`),
			KEY status (status)
		) {$collate};";

		$results = $this->db_delta( $sql );

		// Verify table was created
		if ( ! $this->table_exists( $table_name ) ) {
			$this->log( "Failed to create table {$table_name}", 'error' );

			return false;
		}

		$this->log( "Successfully created table {$table_name}" );

		return true;
	}
}

