<?php

namespace Limb_Chatbot\Includes\Migrations;

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

/**
 * Migration for version 1.0.16
 *
 * Alters lbaic_user_metas.meta_value from varchar(512) to longtext so that
 * larger values (e.g. device_info JSON) can be stored without database errors.
 *
 * @since 1.0.16
 */
class Migration_1_0_16 extends Abstract_Migration {

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

	/**
	 * Get migration description.
	 *
	 * @return string
	 * @since 1.0.16
	 */
	public function get_description(): string {
		return 'Alter lbaic_user_metas.meta_value to longtext and rename vector index meta host to host_1536';
	}

	/**
	 * Execute the migration.
	 *
	 * Alters meta_value column from varchar(512) to longtext so device_info
	 * and other large meta values can be stored without "value too long" errors.
	 * Also renames 'host' meta key to 'host_1536' in vector index metas.
	 *
	 * @return bool True on success, false on failure.
	 * @since 1.0.16
	 */
	public function up(): bool {

		// 1. Rename vector index meta
		$vector_table_name = $this->wpdb->prefix . 'lbaic_vector_index_metas';

		if ( $this->table_exists( $vector_table_name ) ) {
			$this->wpdb->update(
				$vector_table_name,
				array( 'meta_key' => 'host_1536' ),
				array( 'meta_key' => 'host' )
			);
			$this->log( "Renamed 'host' to 'host_1536' in {$vector_table_name}" );
		}

		$this->log( 'Migration 1.0.16 completed successfully - meta_value is now longtext and host renamed' );

		if ( ! $this->seed_open_router_models() ) {
			$this->log( 'Failed to seed Open router models', 'error' );

			return false;
		}

		if ( ! $this->seed_provider_settings() ) {
			$this->log( 'Failed to seed provider settings', 'error' );

			return false;
		}

		return true;
	}

	public function seed_open_router_models(){
		try {
			$this->log( 'Seeding Open Router AI models' );

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

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

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

			return false;
		}
	}
	/**
	 * Seed the Openrouter 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 Open Router settings
			// This is called after models are seeded, so defaults that depend on models will work
			$provider_rules = [];
			foreach (
				[
					new Open_Router(),
				] 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;
		}
	}
}
