<?php

namespace Limb_Chatbot\Includes\Migrations;

use Limb_Chatbot\Includes\AI_Providers\Grok\Grok;
use Limb_Chatbot\Includes\AI_Providers\Grok\Seeders\AI_Models_Seeder;
use Limb_Chatbot\Includes\Data_Objects\Setting;

/**
 * Migration for version 1.0.12
 *
 * Creates the action_submissions table for storing action execution data.
 *
 * @since 1.0.12
 */
class Migration_1_0_12 extends Abstract_Migration {

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

	/**
	 * Get migration description.
	 *
	 * @return string
	 * @since 1.0.12
	 */
	public function get_description(): string {
		return 'Create action_submissions table for storing action execution data';
	}

	/**
	 * Execute the migration.
	 *
	 * Creates the lbaic_action_submissions table for tracking action submissions and results.
	 *
	 * @return bool True on success, false on failure.
	 * @since 1.0.12
	 */
	public function up(): bool {
		$this->log( 'Starting migration 1.0.12 - Creating action_submissions table' );

		if ( ! $this->create_action_submissions_table() ) {
			return false;
		}

		if ( ! $this->seed_grok_models() ) {
			$this->log( 'Failed to seed Grok models', 'error' );

			return false;
		}

		// Seed provider settings if they don't exist
		if ( ! $this->seed_provider_settings() ) {
			$this->log( 'Failed to seed provider settings', 'error' );

			return false;
		}

		$this->log( 'Migration 1.0.12 completed successfully - action_submissions table created' );

		return true;
	}

	/**
	 * Create the lbaic_action_submissions table.
	 *
	 * Stores action submission data including action details, user info, and execution results.
	 *
	 * @return bool True on success, false on failure.
	 * @since 1.0.12
	 */
	private function create_action_submissions_table(): bool {
		$table_name = $this->wpdb->prefix . 'lbaic_action_submissions';

		// 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(20) unsigned NOT NULL,
			action_data longtext NULL,
			chatbot_user_id bigint(20) unsigned NULL,
			chat_uuid char(36) NULL,
			callback_results longtext NULL,
			extracted_vars longtext NULL,
			status varchar(50) DEFAULT 'pending' NOT NULL,
			error_message longtext NULL,
			created_at datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
			PRIMARY KEY (id),
			KEY action_id (action_id),
			KEY chatbot_user_id (chatbot_user_id),
			KEY chat_uuid (chat_uuid),
			KEY status (status),
			KEY created_at (created_at)
		) {$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;
	}

	/**
	 * Seed Grok AI models.
	 *
	 * Runs the Grok AI models seeder to create or update models.
	 *
	 * @return bool True on success, false on failure.
	 * @since 1.1.0
	 */
	private function seed_grok_models(): bool {
		try {
			$this->log( 'Seeding Grok AI models' );

			$seeder = new AI_Models_Seeder();
			$seeder->run();

			$this->log( 'Grok AI models seeded successfully' );

			return true;
		} catch ( \Exception $e ) {
			$this->log( sprintf( 'Error seeding Grok models: %s', $e->getMessage() ), 'error' );

			return false;
		}
	}

	/**
	 * Seed the grok default settings
	 *
	 * @return bool
	 */
	private function seed_provider_settings(): bool {
		try {
			$this->log( 'Seeding provider settings from data schemas' );

			// Get all AI provider rules which includes Grok settings
			// This is called after models are seeded, so defaults that depend on models will work
			$provider_rules = [];
			foreach (
				[
					new Grok(),
				] as $ai_provider
			) {
				$settings = "Limb_Chatbot\\Includes\\AI_Providers\\{$ai_provider::$name}\\Data_Schemas\\Setting";
				if ( class_exists( $settings ) ) {
					$provider_rules = array_merge( $provider_rules, $settings::rules() );
				}
			}

			$settings_created = 0;
			foreach ( $provider_rules as $key => $rule ) {
				// Only create settings that have defaults and don't exist
				if ( isset( $rule['default'] ) && ! Setting::exists( $key ) ) {
					$default_value = $rule['default'];

					// Default values are evaluated when the schema is loaded,
					// so they should already be the correct values after models are seeded
					if ( $default_value !== null ) {
						$this->maybe_add_setting( $key, $default_value );
						$settings_created ++;
					}
				}
			}

			if ( $settings_created > 0 ) {
				$this->log( sprintf( 'Created %d provider settings', $settings_created ) );
			} else {
				$this->log( 'All provider settings already exist' );
			}

			$this->log( 'Provider settings seeded successfully' );

			return true;
		} catch ( \Exception $e ) {
			$this->log( sprintf( 'Error seeding provider settings: %s', $e->getMessage() ), 'error' );

			return false;
		}
	}
}
