<?php
/**
 * Sifency AI Module — Main Entry Point.
 *
 * @package Sifency_Addons
 * @since   1.0.5
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class Sifency_Addons_AI_Module {

	private static ?self $instance = null;

	public static function instance(): self {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/** Absolute path to the uploads sub-folder where AI files live. */
	public static function base_dir(): string {
		$upload = wp_upload_dir();
		return trailingslashit( $upload['basedir'] ) . 'sifency-ai/';
	}

	public static function base_url(): string {
		$upload = wp_upload_dir();
		return trailingslashit( $upload['baseurl'] ) . 'sifency-ai/';
	}

	private function __construct() {
		$this->load_dependencies();
		$this->ensure_directories();
		$this->register_hooks();
	}

	private function load_dependencies(): void {
		$dir = __DIR__ . '/';
		require_once $dir . 'class-ai-generator-trait.php';
		require_once $dir . 'class-ai-api.php';
		require_once $dir . 'class-ai-file-writer.php';
		require_once $dir . 'class-ai-prompt-engine.php';
		require_once $dir . 'class-ai-widget-generator.php';
		require_once $dir . 'class-ai-cpt-generator.php';
		require_once $dir . 'class-ai-metabox-generator.php';
		require_once $dir . 'class-ai-builder-item-generator.php';
		require_once $dir . 'class-ai-loader.php';
	}

	/** Create upload sub-folders on first load (never inside plugin dir). */
	private function ensure_directories(): void {
		$dirs = array( 'widgets', 'cpts', 'builder-items', 'menus', 'pages', 'metaboxes' );
		foreach ( $dirs as $sub ) {
			$path = self::base_dir() . $sub;
			if ( ! is_dir( $path ) ) {
				wp_mkdir_p( $path );
				// Drop an index.php so directory listing is blocked.
				file_put_contents( $path . '/index.php', '<?php // Silence is golden.' ); // phpcs:ignore
			}
		}
	}

	private function register_hooks(): void {
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );

		add_filter( 'sifency_addons_admin_module_files', array( $this, 'register_module_file' ) );

		$ajax_actions = array(
			'sifency_ai_generate_widget',
			'sifency_ai_generate_cpt',
			'sifency_ai_generate_builder_item',
			'sifency_ai_generate_metabox',
			'sifency_ai_toggle_item',
			'sifency_ai_delete_item',
			'sifency_ai_list_items',
			'sifency_ai_save_settings',
			'sifency_ai_get_settings',
		);
		foreach ( $ajax_actions as $action ) {
			add_action( 'wp_ajax_' . $action, array( $this, 'handle_ajax' ) );
		}
	}


	public function register_module_file( array $files ): array {
		$files['sifency-ai'] = __FILE__;
		return $files;
	}

	public function render_admin_page(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Access denied.', 'sifency-addons' ) );
		}

		if ( function_exists( 'sifency_addons_admin_render_layout' ) ) {
			sifency_addons_admin_render_layout(
				'sifency-ai',
				static function () {
					echo '<div id="sifency-ai-root" class="sifency-ai-root-mount"></div>';
				}
			);
		} else {
			echo '<div id="sifency-ai-root" class="sifency-ai-root-mount"></div>';
		}
	}

	public function enqueue_assets( string $hook ): void {
		if ( false === strpos( $hook, 'sifency-ai' ) ) {
			return;
		}

		$url     = plugin_dir_url( __FILE__ ) . 'assets/';
		$dir     = plugin_dir_path( __FILE__ ) . 'assets/';
		$css_ver = file_exists( $dir . 'ai-panel.css' ) ? filemtime( $dir . 'ai-panel.css' ) : SIFENCY_ADDONS_VERSION;
		$js_ver  = file_exists( $dir . 'ai-panel.js' ) ? filemtime( $dir . 'ai-panel.js' ) : SIFENCY_ADDONS_VERSION;

		wp_enqueue_style(
			'sifency-ai-panel',
			$url . 'ai-panel.css',
			array(),
			$css_ver
		);

		wp_enqueue_script(
			'sifency-ai-panel',
			$url . 'ai-panel.js',
			array(),
			$js_ver,
			true
		);

		$raw_key    = (string) get_option( 'sifency_ai_api_key', '' );
		$masked_key = $raw_key ? str_repeat( '•', max( 0, strlen( $raw_key ) - 4 ) ) . substr( $raw_key, -4 ) : '';

		wp_localize_script(
			'sifency-ai-panel',
			'SifencyAI',
			array(
				'nonce'    => wp_create_nonce( 'sifency_ai_nonce' ),
				'ajax_url' => admin_url( 'admin-ajax.php' ),
				'base_url' => self::base_url(),
				'settings' => array(
					'provider' => get_option( 'sifency_ai_provider', 'openai' ),
					'model'    => get_option( 'sifency_ai_model', '' ),
					'api_key'  => $masked_key,
					'has_key'  => ! empty( $raw_key ),
				),
				'counts'   => $this->get_item_counts(),
				'types'    => self::get_generator_types(),
				'i18n'     => array(
					'generate'   => __( 'Generate', 'sifency-addons' ),
					'generating' => __( 'Generating…', 'sifency-addons' ),
					'delete'     => __( 'Delete', 'sifency-addons' ),
					'enable'     => __( 'Enable', 'sifency-addons' ),
					'disable'    => __( 'Disable', 'sifency-addons' ),
					'save'       => __( 'Save Settings', 'sifency-addons' ),
				),
			)
		);
	}

	/**
	 * Returns the list of all supported generator types for the UI.
	 *
	 * @return array<string, array{label:string, icon:string, description:string, folder:string}>
	 */
	public static function get_generator_types(): array {
		return array(
			'widget'       => array(
				'label'       => __( 'Elementor Widget', 'sifency-addons' ),
				'icon'        => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="24" height="24"><path d="M11.75 5.5H8a3 3 0 0 0-3 3v3.75a2.25 2.25 0 0 1 0 4.5V20.5h3.75a2.25 2.25 0 0 1 4.5 0H17a3 3 0 0 0 3-3v-3.75a2.25 2.25 0 0 1 0-4.5V8.5a3 3 0 0 0-3-3h-3.75a2.25 2.25 0 0 1-1.5-3v0a2.25 2.25 0 0 1 0 3Z"/></svg>',
				'description' => __( 'Generate a custom Elementor widget with controls, style options and a render template.', 'sifency-addons' ),
				'folder'      => 'widgets',
				'ajax_action' => 'sifency_ai_generate_widget',
			),
			'cpt'          => array(
				'label'       => __( 'Custom Post Type', 'sifency-addons' ),
				'icon'        => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="24" height="24"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><line x1="9" x2="15" y1="9" y2="9"/><line x1="9" x2="15" y1="13" y2="13"/><line x1="9" x2="13" y1="17" y2="17"/></svg>',
				'description' => __( 'Generate a WordPress Custom Post Type with labels, supports, and optional taxonomy.', 'sifency-addons' ),
				'folder'      => 'cpts',
				'ajax_action' => 'sifency_ai_generate_cpt',
			),
			'builder-item' => array(
				'label'       => __( 'Theme Builder Item', 'sifency-addons' ),
				'icon'        => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="24" height="24"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><line x1="3" x2="21" y1="9" y2="9"/><line x1="9" x2="9" y1="21" y2="9"/></svg>',
				'description' => __( 'Generate a Theme Builder item (header, footer, popup) with display conditions.', 'sifency-addons' ),
				'folder'      => 'builder-items',
				'ajax_action' => 'sifency_ai_generate_builder_item',
			),
			'metabox'      => array(
				'label'       => __( 'Meta Box', 'sifency-addons' ),
				'icon'        => '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="24" height="24"><path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/></svg>',
				'description' => __( 'Generate a custom meta box with fields, nonce verification, and sanitized saving.', 'sifency-addons' ),
				'folder'      => 'metaboxes',
				'ajax_action' => 'sifency_ai_generate_metabox',
			),
		);
	}

	public function handle_ajax(): void {
		check_ajax_referer( 'sifency_ai_nonce', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied.', 'sifency-addons' ) ), 403 );
		}

		$action = sanitize_key( $_POST['action'] ?? '' );

		switch ( $action ) {
			case 'sifency_ai_generate_widget':
				$this->ajax_generate_widget();
				break;

			case 'sifency_ai_generate_cpt':
				$this->ajax_generate_cpt();
				break;

			case 'sifency_ai_generate_builder_item':
				$this->ajax_generate_builder_item();
				break;

			case 'sifency_ai_generate_metabox':
				$this->ajax_generate_metabox();
				break;

			case 'sifency_ai_toggle_item':
				$this->ajax_toggle_item();
				break;

			case 'sifency_ai_delete_item':
				$this->ajax_delete_item();
				break;

			case 'sifency_ai_list_items':
				$this->ajax_list_items();
				break;

			case 'sifency_ai_save_settings':
				$this->ajax_save_settings();
				break;

			case 'sifency_ai_get_settings':
				$this->ajax_get_settings();
				break;

			default:
				wp_send_json_error( array( 'message' => __( 'Unknown action.', 'sifency-addons' ) ), 400 );
		}
	}

	private function ajax_generate_widget(): void {
		$prompt = sanitize_textarea_field( wp_unslash( $_POST['prompt'] ?? '' ) );

		if ( empty( $prompt ) ) {
			wp_send_json_error( array( 'message' => __( 'Prompt is required.', 'sifency-addons' ) ) );
		}

		$generator = new Sifency_Addons_AI_Widget_Generator();
		$result    = $generator->generate( $prompt );

		if ( is_wp_error( $result ) ) {
			wp_send_json_error( array( 'message' => $result->get_error_message() ) );
		}

		wp_send_json_success( $result );
	}

	private function ajax_generate_cpt(): void {
		$prompt = sanitize_textarea_field( wp_unslash( $_POST['prompt'] ?? '' ) );

		if ( empty( $prompt ) ) {
			wp_send_json_error( array( 'message' => __( 'Prompt is required.', 'sifency-addons' ) ) );
		}

		$generator = new Sifency_Addons_AI_CPT_Generator();
		$result    = $generator->generate( $prompt );

		if ( is_wp_error( $result ) ) {
			wp_send_json_error( array( 'message' => $result->get_error_message() ) );
		}

		wp_send_json_success( $result );
	}

	private function ajax_generate_builder_item(): void {
		$prompt = sanitize_textarea_field( wp_unslash( $_POST['prompt'] ?? '' ) );

		if ( empty( $prompt ) ) {
			wp_send_json_error( array( 'message' => __( 'Prompt is required.', 'sifency-addons' ) ) );
		}

		if ( ! class_exists( 'Sifency_Addons_AI_Builder_Item_Generator' ) ) {
			require_once __DIR__ . '/class-ai-builder-item-generator.php';
		}
		$generator = new Sifency_Addons_AI_Builder_Item_Generator();
		$result    = $generator->generate( $prompt );

		if ( is_wp_error( $result ) ) {
			wp_send_json_error( array( 'message' => $result->get_error_message() ) );
		}

		wp_send_json_success( $result );
	}

	private function ajax_generate_metabox(): void {
		$prompt = sanitize_textarea_field( wp_unslash( $_POST['prompt'] ?? '' ) );

		if ( empty( $prompt ) ) {
			wp_send_json_error( array( 'message' => __( 'Prompt is required.', 'sifency-addons' ) ) );
		}

		if ( ! class_exists( 'Sifency_Addons_AI_Metabox_Generator' ) ) {
			require_once __DIR__ . '/class-ai-metabox-generator.php';
		}
		$generator = new Sifency_Addons_AI_Metabox_Generator();
		$result    = $generator->generate( $prompt );

		if ( is_wp_error( $result ) ) {
			wp_send_json_error( array( 'message' => $result->get_error_message() ) );
		}

		wp_send_json_success( $result );
	}

	private function ajax_toggle_item(): void {
		$type     = sanitize_key( $_POST['item_type'] ?? '' );
		$filename = sanitize_file_name( $_POST['filename'] ?? '' );
		$enabled  = filter_var( $_POST['enabled'] ?? false, FILTER_VALIDATE_BOOLEAN );

		if ( ! $type || ! $filename ) {
			wp_send_json_error( array( 'message' => __( 'Missing parameters.', 'sifency-addons' ) ) );
		}

		$writer = new Sifency_Addons_AI_File_Writer();
		$ok     = $writer->set_enabled( $type, $filename, $enabled );

		$ok
			? wp_send_json_success( array( 'enabled' => $enabled ) )
			: wp_send_json_error( array( 'message' => __( 'Could not update status.', 'sifency-addons' ) ) );
	}

	private function ajax_delete_item(): void {
		$type     = sanitize_key( $_POST['item_type'] ?? '' );
		$filename = sanitize_file_name( $_POST['filename'] ?? '' );

		if ( ! $type || ! $filename ) {
			wp_send_json_error( array( 'message' => __( 'Missing parameters.', 'sifency-addons' ) ) );
		}

		$writer = new Sifency_Addons_AI_File_Writer();
		$ok     = $writer->delete( $type, $filename );

		$ok
			? wp_send_json_success()
			: wp_send_json_error( array( 'message' => __( 'Could not delete file.', 'sifency-addons' ) ) );
	}


	private function ajax_list_items(): void {
		$type = sanitize_key( $_POST['item_type'] ?? 'all' );

		if ( 'all' === $type ) {
			$result = array();
			foreach ( self::get_generator_types() as $key => $meta ) {
				$result[ $key ] = Sifency_Addons_AI_File_Writer::list_items( $meta['folder'] );
			}
			wp_send_json_success( $result );
		} else {
			$types  = self::get_generator_types();
			$folder = isset( $types[ $type ] ) ? $types[ $type ]['folder'] : $type;
			wp_send_json_success( Sifency_Addons_AI_File_Writer::list_items( $folder ) );
		}
	}

	private function ajax_save_settings(): void {
		$provider = sanitize_key( $_POST['provider'] ?? 'openai' );
		$api_key  = sanitize_text_field( wp_unslash( $_POST['api_key'] ?? '' ) );
		$model    = sanitize_text_field( wp_unslash( $_POST['model'] ?? '' ) );

		// Validate credentials before saving.
		// If the user didn't enter a new key, we need to verify against the stored key.
		$key_to_verify = $api_key;
		if ( empty( $key_to_verify ) || false !== strpos( $key_to_verify, '•' ) ) {
			$key_to_verify = get_option( 'sifency_ai_api_key', '' );
		}

		$verification = Sifency_Addons_AI_API::verify_credentials( $provider, $key_to_verify, $model );

		if ( is_wp_error( $verification ) ) {
			wp_send_json_error( array( 'message' => $verification->get_error_message() ) );
		}

		update_option( 'sifency_ai_provider', $provider );
		update_option( 'sifency_ai_model', $model );

		// Only update API key if a real one (not masked) is submitted.
		if ( ! empty( $api_key ) && false === strpos( $api_key, '•' ) ) {
			update_option( 'sifency_ai_api_key', $api_key );
		}

		wp_send_json_success( array( 'message' => __( 'Settings saved.', 'sifency-addons' ) ) );
	}

	private function ajax_get_settings(): void {
		$raw_key    = (string) get_option( 'sifency_ai_api_key', '' );
		$masked_key = $raw_key ? str_repeat( '•', max( 0, strlen( $raw_key ) - 4 ) ) . substr( $raw_key, -4 ) : '';

		wp_send_json_success(
			array(
				'provider' => get_option( 'sifency_ai_provider', 'openai' ),
				'model'    => get_option( 'sifency_ai_model', '' ),
				'api_key'  => $masked_key,
				'has_key'  => ! empty( $raw_key ),
			)
		);
	}

	/**
	 * Return counts of generated items per type.
	 */
	private function get_item_counts(): array {
		$counts = array();
		foreach ( self::get_generator_types() as $key => $meta ) {
			$items          = Sifency_Addons_AI_File_Writer::list_items( $meta['folder'] );
			$counts[ $key ] = array(
				'total'   => count( $items ),
				'enabled' => count( array_filter( $items, fn( $i ) => $i['enabled'] ) ),
			);
		}
		return $counts;
	}
}
