<?php
/**
 * GGM Commerce Variation Attributes Management
 *
 * Handles variation attribute groups, attribute definitions, and product variation config.
 * Provides a familiar interface similar to Custom Attributes with groups and suggestions.
 *
 * @package GGM_Commerce
 */

defined( 'ABSPATH' ) || exit;

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching
// phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter

/**
 * Class GGM_Commerce_Variation_Attributes
 *
 * Manages variation attributes with group templates for quick product setup.
 */
class GGM_Commerce_Variation_Attributes {

	/**
	 * Singleton instance.
	 *
	 * @var GGM_Commerce_Variation_Attributes|null
	 */
	private static $instance = null;

	/**
	 * Get singleton instance.
	 *
	 * @return GGM_Commerce_Variation_Attributes
	 */
	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Constructor.
	 */
	private function __construct() {
		// AJAX handlers for variation attribute groups.
		add_action( 'wp_ajax_ggmc_create_variation_attribute_group', array( $this, 'ajax_create_group' ) );
		add_action( 'wp_ajax_ggmc_update_variation_attribute_group', array( $this, 'ajax_update_group' ) );
		add_action( 'wp_ajax_ggmc_delete_variation_attribute_group', array( $this, 'ajax_delete_group' ) );
		add_action( 'wp_ajax_ggmc_get_variation_attribute_group', array( $this, 'ajax_get_group' ) );

		// AJAX handlers for variation attributes.
		add_action( 'wp_ajax_ggmc_create_variation_attribute', array( $this, 'ajax_create_attribute' ) );
		add_action( 'wp_ajax_ggmc_update_variation_attribute', array( $this, 'ajax_update_attribute' ) );
		add_action( 'wp_ajax_ggmc_delete_variation_attribute', array( $this, 'ajax_delete_attribute' ) );

		// AJAX handlers for group membership.
		add_action( 'wp_ajax_ggmc_add_variation_attribute_to_group', array( $this, 'ajax_add_attribute_to_group' ) );
		add_action( 'wp_ajax_ggmc_remove_variation_attribute_from_group', array( $this, 'ajax_remove_attribute_from_group' ) );
		add_action( 'wp_ajax_ggmc_set_group_variation_attributes', array( $this, 'ajax_set_group_attributes' ) );

		// AJAX handlers for suggestions.
		add_action( 'wp_ajax_ggmc_install_variation_suggestion', array( $this, 'ajax_install_suggestion' ) );
		add_action( 'wp_ajax_ggmc_get_variation_suggestions', array( $this, 'ajax_get_suggestions' ) );

		// AJAX handlers for product variation config.
		add_action( 'wp_ajax_ggmc_add_variation_attributes_from_group', array( $this, 'ajax_add_attributes_from_group' ) );
	}

	// =========================================================================
	// VARIATION ATTRIBUTE GROUPS CRUD
	// =========================================================================

	/**
	 * Get all variation attribute groups.
	 *
	 * @param array $args Query arguments.
	 * @return array
	 */
	public function get_groups( $args = array() ) {
		global $wpdb;

		$defaults = array(
			'status'        => 'active',
			'is_suggestion' => null,
			'orderby'       => 'display_order',
			'order'         => 'ASC',
		);

		$args = wp_parse_args( $args, $defaults );

		$where  = array( '1=1' );
		$values = array();

		if ( ! empty( $args['status'] ) && 'all' !== $args['status'] ) {
			$where[]  = 'status = %s';
			$values[] = $args['status'];
		}

		if ( null !== $args['is_suggestion'] ) {
			$where[]  = 'is_suggestion = %d';
			$values[] = $args['is_suggestion'] ? 1 : 0;
		}

		$where_clause = implode( ' AND ', $where );
		$orderby      = sanitize_sql_orderby( $args['orderby'] . ' ' . $args['order'] ) ?: 'display_order ASC';

		$sql = "SELECT * FROM {$wpdb->prefix}ggmc_variation_type_groups WHERE {$where_clause} ORDER BY {$orderby}";

		if ( ! empty( $values ) ) {
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
			$results = $wpdb->get_results( $wpdb->prepare( $sql, ...$values ) );
		} else {
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
			$results = $wpdb->get_results( $sql );
		}

		return $results ?: array();
	}

	/**
	 * Get a single group by ID.
	 *
	 * @param int $group_id Group ID.
	 * @return object|null
	 */
	public function get_group( $group_id ) {
		global $wpdb;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		return $wpdb->get_row(
			$wpdb->prepare(
				"SELECT * FROM {$wpdb->prefix}ggmc_variation_type_groups WHERE id = %d",
				$group_id
			)
		);
	}

	/**
	 * Get a group by slug.
	 *
	 * @param string $slug Group slug.
	 * @return object|null
	 */
	public function get_group_by_slug( $slug ) {
		global $wpdb;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		return $wpdb->get_row(
			$wpdb->prepare(
				"SELECT * FROM {$wpdb->prefix}ggmc_variation_type_groups WHERE slug = %s",
				$slug
			)
		);
	}

	/**
	 * Create a variation attribute group.
	 *
	 * @param array $data Group data.
	 * @return int|WP_Error New group ID or error.
	 */
	public function create_group( $data ) {
		global $wpdb;

		if ( empty( $data['name'] ) ) {
			return new WP_Error( 'missing_name', __( 'Group name is required', 'ggm-commerce' ) );
		}

		// Generate unique slug.
		$slug = ! empty( $data['slug'] ) ? sanitize_title( $data['slug'] ) : sanitize_title( $data['name'] );
		$slug = $this->ensure_unique_group_slug( $slug );

		$insert_data = array(
			'name'          => sanitize_text_field( $data['name'] ),
			'slug'          => $slug,
			'description'   => sanitize_textarea_field( $data['description'] ?? '' ),
			'is_suggestion' => ! empty( $data['is_suggestion'] ) ? 1 : 0,
			'display_order' => intval( $data['display_order'] ?? 0 ),
			'status'        => sanitize_text_field( $data['status'] ?? 'active' ),
			'created_at'    => current_time( 'mysql' ),
			'updated_at'    => current_time( 'mysql' ),
		);

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$inserted = $wpdb->insert( "{$wpdb->prefix}ggmc_variation_type_groups", $insert_data );

		if ( $inserted ) {
			return $wpdb->insert_id;
		}

		return new WP_Error( 'insert_failed', __( 'Failed to create group', 'ggm-commerce' ) );
	}

	/**
	 * Update a variation attribute group.
	 *
	 * @param int   $group_id Group ID.
	 * @param array $data     Group data.
	 * @return bool|WP_Error
	 */
	public function update_group( $group_id, $data ) {
		global $wpdb;

		$group = $this->get_group( $group_id );
		if ( ! $group ) {
			return new WP_Error( 'not_found', __( 'Group not found', 'ggm-commerce' ) );
		}

		$update_data = array(
			'updated_at' => current_time( 'mysql' ),
		);

		if ( isset( $data['name'] ) ) {
			$update_data['name'] = sanitize_text_field( $data['name'] );
		}
		if ( isset( $data['description'] ) ) {
			$update_data['description'] = sanitize_textarea_field( $data['description'] );
		}
		if ( isset( $data['display_order'] ) ) {
			$update_data['display_order'] = intval( $data['display_order'] );
		}
		if ( isset( $data['status'] ) ) {
			$update_data['status'] = sanitize_text_field( $data['status'] );
		}

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$updated = $wpdb->update(
			"{$wpdb->prefix}ggmc_variation_type_groups",
			$update_data,
			array( 'id' => $group_id ),
			null,
			array( '%d' )
		);

		return false !== $updated;
	}

	/**
	 * Delete a variation attribute group.
	 *
	 * @param int $group_id Group ID.
	 * @return bool|WP_Error
	 */
	public function delete_group( $group_id ) {
		global $wpdb;

		$group = $this->get_group( $group_id );
		if ( ! $group ) {
			return new WP_Error( 'not_found', __( 'Group not found', 'ggm-commerce' ) );
		}

		// Delete group memberships first.
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->delete(
			"{$wpdb->prefix}ggmc_variation_type_group_members",
			array( 'group_id' => $group_id ),
			array( '%d' )
		);

		// Delete the group.
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$deleted = $wpdb->delete(
			"{$wpdb->prefix}ggmc_variation_type_groups",
			array( 'id' => $group_id ),
			array( '%d' )
		);

		return false !== $deleted;
	}

	/**
	 * Ensure unique group slug.
	 *
	 * @param string $slug     Base slug.
	 * @param int    $group_id Optional group ID to exclude.
	 * @return string Unique slug.
	 */
	private function ensure_unique_group_slug( $slug, $group_id = 0 ) {
		global $wpdb;

		$original_slug = $slug;
		$counter       = 1;

		while ( true ) {
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			$existing = $wpdb->get_var(
				$wpdb->prepare(
					"SELECT id FROM {$wpdb->prefix}ggmc_variation_type_groups WHERE slug = %s AND id != %d",
					$slug,
					$group_id
				)
			);

			if ( ! $existing ) {
				break;
			}

			$slug = $original_slug . '-' . $counter;
			$counter++;
		}

		return $slug;
	}

	// =========================================================================
	// GROUP MEMBERSHIP (MANY-TO-MANY)
	// =========================================================================

	/**
	 * Get attributes in a group.
	 *
	 * @param int $group_id Group ID.
	 * @return array
	 */
	public function get_group_attributes( $group_id ) {
		global $wpdb;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$results = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT a.*, m.display_order as group_order
				FROM {$wpdb->prefix}ggmc_variation_types a
				INNER JOIN {$wpdb->prefix}ggmc_variation_type_group_members m ON a.id = m.variation_type_id
				WHERE m.group_id = %d AND a.status = 'active'
				ORDER BY m.display_order ASC",
				$group_id
			),
			ARRAY_A
		);

		// Decode options JSON.
		if ( $results ) {
			foreach ( $results as &$attr ) {
				$attr['options'] = ! empty( $attr['options'] ) ? json_decode( $attr['options'], true ) : array();
			}
		}

		return $results ?: array();
	}

	/**
	 * Add an attribute to a group.
	 *
	 * @param int $group_id     Group ID.
	 * @param int $attribute_id Attribute ID.
	 * @return bool|WP_Error
	 */
	public function add_attribute_to_group( $group_id, $attribute_id ) {
		global $wpdb;

		// Get max display_order in group.
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$max_order = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT MAX(display_order) FROM {$wpdb->prefix}ggmc_variation_type_group_members WHERE group_id = %d",
				$group_id
			)
		);

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$inserted = $wpdb->insert(
			"{$wpdb->prefix}ggmc_variation_type_group_members",
			array(
				'group_id'          => $group_id,
				'variation_type_id' => $attribute_id,
				'display_order'     => ( $max_order ?? -1 ) + 1,
				'created_at'        => current_time( 'mysql' ),
			),
			array( '%d', '%d', '%d', '%s' )
		);

		return false !== $inserted;
	}

	/**
	 * Remove an attribute from a group.
	 *
	 * @param int $group_id     Group ID.
	 * @param int $attribute_id Attribute ID.
	 * @return bool
	 */
	public function remove_attribute_from_group( $group_id, $attribute_id ) {
		global $wpdb;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$deleted = $wpdb->delete(
			"{$wpdb->prefix}ggmc_variation_type_group_members",
			array(
				'group_id'          => $group_id,
				'variation_type_id' => $attribute_id,
			),
			array( '%d', '%d' )
		);

		return false !== $deleted;
	}

	/**
	 * Set all attributes for a group (replace existing).
	 *
	 * @param int   $group_id      Group ID.
	 * @param array $attribute_ids Array of attribute IDs.
	 * @return bool
	 */
	public function set_group_attributes( $group_id, $attribute_ids ) {
		global $wpdb;

		// Delete existing memberships.
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->delete(
			"{$wpdb->prefix}ggmc_variation_type_group_members",
			array( 'group_id' => $group_id ),
			array( '%d' )
		);

		// Add new memberships.
		$order = 0;
		foreach ( $attribute_ids as $attribute_id ) {
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			$wpdb->insert(
				"{$wpdb->prefix}ggmc_variation_type_group_members",
				array(
					'group_id'          => $group_id,
					'variation_type_id' => intval( $attribute_id ),
					'display_order'     => $order++,
					'created_at'        => current_time( 'mysql' ),
				),
				array( '%d', '%d', '%d', '%s' )
			);
		}

		return true;
	}

	/**
	 * Get groups an attribute belongs to.
	 *
	 * @param int $attribute_id Attribute ID.
	 * @return array
	 */
	public function get_attribute_groups( $attribute_id ) {
		global $wpdb;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		return $wpdb->get_results(
			$wpdb->prepare(
				"SELECT g.*
				FROM {$wpdb->prefix}ggmc_variation_type_groups g
				INNER JOIN {$wpdb->prefix}ggmc_variation_type_group_members m ON g.id = m.group_id
				WHERE m.variation_type_id = %d AND g.status = 'active'
				ORDER BY g.display_order ASC",
				$attribute_id
			)
		) ?: array();
	}

	// =========================================================================
	// VARIATION ATTRIBUTES CRUD (DELEGATED)
	// =========================================================================

	/**
	 * Get all variation types.
	 *
	 * Delegates to the existing GGM_Commerce_Variations class.
	 *
	 * @param array $args Query arguments.
	 * @return array
	 */
	public function get_attributes( $args = array() ) {
		$variations = GGM_Commerce_Variations::instance();
		return $variations->get_variation_types( $args );
	}

	/**
	 * Get a single variation type.
	 *
	 * @param int $attribute_id Variation type ID.
	 * @return array|null
	 */
	public function get_attribute( $attribute_id ) {
		$variations = GGM_Commerce_Variations::instance();
		return $variations->get_variation_type( $attribute_id );
	}

	/**
	 * Create a variation type.
	 *
	 * @param array $data Variation type data.
	 * @return int|false
	 */
	public function create_attribute( $data ) {
		$variations = GGM_Commerce_Variations::instance();
		return $variations->create_variation_type( $data );
	}

	/**
	 * Update a variation type.
	 *
	 * @param int   $attribute_id Variation type ID.
	 * @param array $data         Variation type data.
	 * @return bool
	 */
	public function update_attribute( $attribute_id, $data ) {
		$variations = GGM_Commerce_Variations::instance();
		return $variations->update_variation_type( $attribute_id, $data );
	}

	/**
	 * Delete a variation type.
	 *
	 * @param int $attribute_id Variation type ID.
	 * @return bool
	 */
	public function delete_attribute( $attribute_id ) {
		global $wpdb;

		// First remove from all groups.
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->delete(
			"{$wpdb->prefix}ggmc_variation_type_group_members",
			array( 'variation_type_id' => $attribute_id ),
			array( '%d' )
		);

		// Then delete the variation type.
		$variations = GGM_Commerce_Variations::instance();
		return $variations->delete_variation_type( $attribute_id );
	}

	// =========================================================================
	// PRODUCT VARIATION CONFIG HELPERS
	// =========================================================================

	/**
	 * Add all attributes from a group to a product's variation config.
	 *
	 * @param int $product_id Product ID.
	 * @param int $group_id   Group ID.
	 * @return array Array of added attribute IDs.
	 */
	public function add_attributes_from_group( $product_id, $group_id ) {
		$variations = GGM_Commerce_Variations::instance();

		// Get current config.
		$current_config = $variations->get_product_variation_config( $product_id );
		$current_ids    = array_map( function( $attr ) {
			return $attr['id'];
		}, $current_config );

		// Get group attributes.
		$group_attributes = $this->get_group_attributes( $group_id );

		$added = array();
		foreach ( $group_attributes as $attr ) {
			if ( ! in_array( $attr['id'], $current_ids, true ) ) {
				// Add to product config.
				$current_ids[] = $attr['id'];
				$added[]       = $attr['id'];
			}
		}

		// Update product config.
		if ( ! empty( $added ) ) {
			$variations->set_product_variation_config( $product_id, $current_ids );
		}

		return $added;
	}

	/**
	 * Get group-to-attributes map for JavaScript.
	 *
	 * @return array
	 */
	public function get_group_attributes_map() {
		$groups = $this->get_groups( array( 'is_suggestion' => false ) );
		$map    = array();

		foreach ( $groups as $group ) {
			$attributes        = $this->get_group_attributes( $group->id );
			$map[ $group->id ] = array(
				'name'       => $group->name,
				'attributes' => array_map( function( $attr ) {
					return array(
						'id'      => $attr['id'],
						'name'    => $attr['name'],
						'slug'    => $attr['slug'],
						'options' => $attr['options'],
					);
				}, $attributes ),
			);
		}

		return $map;
	}

	// =========================================================================
	// SUGGESTIONS SYSTEM
	// =========================================================================

	/**
	 * Get pre-defined variation attribute suggestions.
	 *
	 * @return array
	 */
	public function get_suggestions() {
		return array(
			'clothing-sizes' => array(
				'name'        => __( 'Clothing Sizes', 'ggm-commerce' ),
				'description' => __( 'Standard clothing sizes (XS, S, M, L, XL, XXL, XXXL)', 'ggm-commerce' ),
				'category'    => 'clothing',
				'attributes'  => array(
					array(
						'name'    => __( 'Size', 'ggm-commerce' ),
						'slug'    => 'size',
						'options' => array(
							array( 'value' => 'XS' ),
							array( 'value' => 'S' ),
							array( 'value' => 'M' ),
							array( 'value' => 'L' ),
							array( 'value' => 'XL' ),
							array( 'value' => 'XXL' ),
							array( 'value' => 'XXXL' ),
						),
					),
				),
			),
			'shoe-sizes-uk' => array(
				'name'        => __( 'Shoe Sizes (UK)', 'ggm-commerce' ),
				'description' => __( 'UK shoe sizes from 3 to 13', 'ggm-commerce' ),
				'category'    => 'clothing',
				'attributes'  => array(
					array(
						'name'    => __( 'UK Size', 'ggm-commerce' ),
						'slug'    => 'uk-size',
						'options' => array(
							array( 'value' => '3' ),
							array( 'value' => '4' ),
							array( 'value' => '5' ),
							array( 'value' => '6' ),
							array( 'value' => '7' ),
							array( 'value' => '8' ),
							array( 'value' => '9' ),
							array( 'value' => '10' ),
							array( 'value' => '11' ),
							array( 'value' => '12' ),
							array( 'value' => '13' ),
						),
					),
				),
			),
			'basic-colors' => array(
				'name'        => __( 'Basic Colors', 'ggm-commerce' ),
				'description' => __( 'Common product colors (Black, White, Red, Blue, Green, etc.)', 'ggm-commerce' ),
				'category'    => 'general',
				'attributes'  => array(
					array(
						'name'    => __( 'Color', 'ggm-commerce' ),
						'slug'    => 'color',
						'options' => array(
							array( 'value' => 'Black' ),
							array( 'value' => 'White' ),
							array( 'value' => 'Red' ),
							array( 'value' => 'Blue' ),
							array( 'value' => 'Green' ),
							array( 'value' => 'Yellow' ),
							array( 'value' => 'Orange' ),
							array( 'value' => 'Purple' ),
							array( 'value' => 'Pink' ),
							array( 'value' => 'Grey' ),
							array( 'value' => 'Brown' ),
							array( 'value' => 'Navy' ),
						),
					),
				),
			),
			'materials' => array(
				'name'        => __( 'Materials', 'ggm-commerce' ),
				'description' => __( 'Common product materials (Cotton, Polyester, Leather, etc.)', 'ggm-commerce' ),
				'category'    => 'general',
				'attributes'  => array(
					array(
						'name'    => __( 'Material', 'ggm-commerce' ),
						'slug'    => 'material',
						'options' => array(
							array( 'value' => 'Cotton' ),
							array( 'value' => 'Polyester' ),
							array( 'value' => 'Leather' ),
							array( 'value' => 'Wool' ),
							array( 'value' => 'Silk' ),
							array( 'value' => 'Linen' ),
							array( 'value' => 'Denim' ),
							array( 'value' => 'Nylon' ),
							array( 'value' => 'Velvet' ),
							array( 'value' => 'Canvas' ),
						),
					),
				),
			),
			'storage-capacity' => array(
				'name'        => __( 'Storage Capacity', 'ggm-commerce' ),
				'description' => __( 'Digital storage sizes for electronics (64GB, 128GB, 256GB, etc.)', 'ggm-commerce' ),
				'category'    => 'electronics',
				'attributes'  => array(
					array(
						'name'    => __( 'Storage', 'ggm-commerce' ),
						'slug'    => 'storage',
						'options' => array(
							array( 'value' => '32GB' ),
							array( 'value' => '64GB' ),
							array( 'value' => '128GB' ),
							array( 'value' => '256GB' ),
							array( 'value' => '512GB' ),
							array( 'value' => '1TB' ),
							array( 'value' => '2TB' ),
							array( 'value' => '4TB' ),
						),
					),
				),
			),
			'computer-memory' => array(
				'name'        => __( 'Computer Memory (RAM)', 'ggm-commerce' ),
				'description' => __( 'RAM sizes for computers (4GB, 8GB, 16GB, 32GB, 64GB)', 'ggm-commerce' ),
				'category'    => 'electronics',
				'attributes'  => array(
					array(
						'name'    => __( 'RAM', 'ggm-commerce' ),
						'slug'    => 'ram',
						'options' => array(
							array( 'value' => '4GB' ),
							array( 'value' => '8GB' ),
							array( 'value' => '16GB' ),
							array( 'value' => '32GB' ),
							array( 'value' => '64GB' ),
							array( 'value' => '128GB' ),
						),
					),
				),
			),
			'processor-specs' => array(
				'name'        => __( 'Processor Specifications', 'ggm-commerce' ),
				'description' => __( 'CPU options for computers (Intel Core i5, i7, i9, AMD Ryzen)', 'ggm-commerce' ),
				'category'    => 'electronics',
				'attributes'  => array(
					array(
						'name'    => __( 'Processor', 'ggm-commerce' ),
						'slug'    => 'processor',
						'options' => array(
							array( 'value' => 'Intel Core i3' ),
							array( 'value' => 'Intel Core i5' ),
							array( 'value' => 'Intel Core i7' ),
							array( 'value' => 'Intel Core i9' ),
							array( 'value' => 'AMD Ryzen 3' ),
							array( 'value' => 'AMD Ryzen 5' ),
							array( 'value' => 'AMD Ryzen 7' ),
							array( 'value' => 'AMD Ryzen 9' ),
							array( 'value' => 'Apple M1' ),
							array( 'value' => 'Apple M2' ),
							array( 'value' => 'Apple M3' ),
						),
					),
				),
			),
			'vehicle-engine' => array(
				'name'        => __( 'Vehicle Engine Size', 'ggm-commerce' ),
				'description' => __( 'Engine displacement options (1.0L, 1.6L, 2.0L, 3.0L, etc.)', 'ggm-commerce' ),
				'category'    => 'automotive',
				'attributes'  => array(
					array(
						'name'    => __( 'Engine Size', 'ggm-commerce' ),
						'slug'    => 'engine-size',
						'options' => array(
							array( 'value' => '1.0L' ),
							array( 'value' => '1.2L' ),
							array( 'value' => '1.4L' ),
							array( 'value' => '1.6L' ),
							array( 'value' => '1.8L' ),
							array( 'value' => '2.0L' ),
							array( 'value' => '2.5L' ),
							array( 'value' => '3.0L' ),
							array( 'value' => '3.5L' ),
							array( 'value' => '4.0L' ),
							array( 'value' => '5.0L' ),
							array( 'value' => 'Electric' ),
							array( 'value' => 'Hybrid' ),
						),
					),
				),
			),
			'vehicle-transmission' => array(
				'name'        => __( 'Vehicle Transmission', 'ggm-commerce' ),
				'description' => __( 'Gearbox options (Manual, Automatic, CVT, etc.)', 'ggm-commerce' ),
				'category'    => 'automotive',
				'attributes'  => array(
					array(
						'name'    => __( 'Transmission', 'ggm-commerce' ),
						'slug'    => 'transmission',
						'options' => array(
							array( 'value' => 'Manual 5-Speed' ),
							array( 'value' => 'Manual 6-Speed' ),
							array( 'value' => 'Automatic' ),
							array( 'value' => 'CVT' ),
							array( 'value' => 'Dual-Clutch (DCT)' ),
							array( 'value' => 'Semi-Automatic' ),
							array( 'value' => 'Single-Speed (Electric)' ),
						),
					),
				),
			),
			'screen-sizes' => array(
				'name'        => __( 'Screen Sizes', 'ggm-commerce' ),
				'description' => __( 'Display sizes for monitors, TVs, laptops (13", 15", 27", etc.)', 'ggm-commerce' ),
				'category'    => 'electronics',
				'attributes'  => array(
					array(
						'name'    => __( 'Screen Size', 'ggm-commerce' ),
						'slug'    => 'screen-size',
						'options' => array(
							array( 'value' => '13"' ),
							array( 'value' => '14"' ),
							array( 'value' => '15.6"' ),
							array( 'value' => '17"' ),
							array( 'value' => '21.5"' ),
							array( 'value' => '24"' ),
							array( 'value' => '27"' ),
							array( 'value' => '32"' ),
							array( 'value' => '43"' ),
							array( 'value' => '50"' ),
							array( 'value' => '55"' ),
							array( 'value' => '65"' ),
							array( 'value' => '75"' ),
						),
					),
				),
			),
		);
	}

	/**
	 * Check if a suggestion is already installed.
	 *
	 * @param string $suggestion_key Suggestion key.
	 * @return bool
	 */
	public function is_suggestion_installed( $suggestion_key ) {
		$group = $this->get_group_by_slug( $suggestion_key );
		return null !== $group;
	}

	/**
	 * Install a suggestion (create group and attributes).
	 *
	 * @param string $suggestion_key Suggestion key.
	 * @return int|WP_Error Group ID or error.
	 */
	public function install_suggestion( $suggestion_key ) {
		$suggestions = $this->get_suggestions();

		if ( ! isset( $suggestions[ $suggestion_key ] ) ) {
			return new WP_Error( 'invalid_suggestion', __( 'Invalid suggestion key', 'ggm-commerce' ) );
		}

		if ( $this->is_suggestion_installed( $suggestion_key ) ) {
			return new WP_Error( 'already_installed', __( 'This suggestion is already installed', 'ggm-commerce' ) );
		}

		$suggestion = $suggestions[ $suggestion_key ];

		// Create the group.
		$group_id = $this->create_group( array(
			'name'          => $suggestion['name'],
			'slug'          => $suggestion_key,
			'description'   => $suggestion['description'],
			'is_suggestion' => 1,
		) );

		if ( is_wp_error( $group_id ) ) {
			return $group_id;
		}

		// Create the variation types and add to group.
		foreach ( $suggestion['attributes'] as $attr_data ) {
			// Check if variation type with this slug already exists.
			$existing = GGM_Commerce_Variations::instance()->get_variation_type_by_slug( $attr_data['slug'] );

			if ( $existing ) {
				// Use existing attribute.
				$attribute_id = $existing['id'];
			} else {
				// Create new attribute.
				$attribute_id = $this->create_attribute( array(
					'name'    => $attr_data['name'],
					'slug'    => $attr_data['slug'],
					'options' => $attr_data['options'],
				) );
			}

			if ( $attribute_id ) {
				$this->add_attribute_to_group( $group_id, $attribute_id );
			}
		}

		return $group_id;
	}

	// =========================================================================
	// AJAX HANDLERS
	// =========================================================================

	/**
	 * AJAX: Create variation attribute group.
	 */
	public function ajax_create_group() {
		check_ajax_referer( 'ggm_commerce_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'ggm-commerce' ) ) );
		}

		$data = array(
			'name'        => sanitize_text_field( wp_unslash( $_POST['name'] ?? '' ) ),
			'description' => sanitize_textarea_field( wp_unslash( $_POST['description'] ?? '' ) ),
		);

		$result = $this->create_group( $data );

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

		wp_send_json_success( array(
			'message'  => __( 'Group created successfully', 'ggm-commerce' ),
			'group_id' => $result,
			'group'    => $this->get_group( $result ),
		) );
	}

	/**
	 * AJAX: Update variation attribute group.
	 */
	public function ajax_update_group() {
		check_ajax_referer( 'ggm_commerce_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'ggm-commerce' ) ) );
		}

		$group_id = intval( $_POST['group_id'] ?? 0 );
		if ( ! $group_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid group ID', 'ggm-commerce' ) ) );
		}

		$data = array();
		if ( isset( $_POST['name'] ) ) {
			$data['name'] = sanitize_text_field( wp_unslash( $_POST['name'] ) );
		}
		if ( isset( $_POST['description'] ) ) {
			$data['description'] = sanitize_textarea_field( wp_unslash( $_POST['description'] ) );
		}

		$result = $this->update_group( $group_id, $data );

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

		wp_send_json_success( array(
			'message' => __( 'Group updated successfully', 'ggm-commerce' ),
			'group'   => $this->get_group( $group_id ),
		) );
	}

	/**
	 * AJAX: Delete variation attribute group.
	 */
	public function ajax_delete_group() {
		check_ajax_referer( 'ggm_commerce_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'ggm-commerce' ) ) );
		}

		$group_id = intval( $_POST['group_id'] ?? 0 );
		if ( ! $group_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid group ID', 'ggm-commerce' ) ) );
		}

		$result = $this->delete_group( $group_id );

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

		wp_send_json_success( array( 'message' => __( 'Group deleted successfully', 'ggm-commerce' ) ) );
	}

	/**
	 * AJAX: Get variation attribute group with attributes.
	 */
	public function ajax_get_group() {
		check_ajax_referer( 'ggm_commerce_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'ggm-commerce' ) ) );
		}

		$group_id = intval( $_POST['group_id'] ?? 0 );
		if ( ! $group_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid group ID', 'ggm-commerce' ) ) );
		}

		$group      = $this->get_group( $group_id );
		$attributes = $this->get_group_attributes( $group_id );

		wp_send_json_success( array(
			'group'      => $group,
			'attributes' => $attributes,
		) );
	}

	/**
	 * AJAX: Create variation attribute.
	 */
	public function ajax_create_attribute() {
		check_ajax_referer( 'ggm_commerce_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'ggm-commerce' ) ) );
		}

		$data = array(
			'name'    => sanitize_text_field( wp_unslash( $_POST['name'] ?? '' ) ),
			'options' => array(),
		);

		// Parse options.
		if ( ! empty( $_POST['options'] ) ) {
			$options_raw = is_array( $_POST['options'] ) ? $_POST['options'] : explode( ',', wp_unslash( $_POST['options'] ) );
			foreach ( $options_raw as $opt ) {
				$opt = trim( sanitize_text_field( $opt ) );
				if ( ! empty( $opt ) ) {
					$data['options'][] = array( 'value' => $opt );
				}
			}
		}

		$result = $this->create_attribute( $data );

		if ( ! $result ) {
			wp_send_json_error( array( 'message' => __( 'Failed to create attribute', 'ggm-commerce' ) ) );
		}

		// Add to group if specified.
		$group_id = intval( $_POST['group_id'] ?? 0 );
		if ( $group_id ) {
			$this->add_attribute_to_group( $group_id, $result );
		}

		wp_send_json_success( array(
			'message'      => __( 'Attribute created successfully', 'ggm-commerce' ),
			'attribute_id' => $result,
			'attribute'    => $this->get_attribute( $result ),
		) );
	}

	/**
	 * AJAX: Update variation attribute.
	 */
	public function ajax_update_attribute() {
		check_ajax_referer( 'ggm_commerce_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'ggm-commerce' ) ) );
		}

		$attribute_id = intval( $_POST['attribute_id'] ?? 0 );
		if ( ! $attribute_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid attribute ID', 'ggm-commerce' ) ) );
		}

		$data = array();
		if ( isset( $_POST['name'] ) ) {
			$data['name'] = sanitize_text_field( wp_unslash( $_POST['name'] ) );
		}
		if ( isset( $_POST['options'] ) ) {
			$options_raw = is_array( $_POST['options'] ) ? $_POST['options'] : explode( ',', wp_unslash( $_POST['options'] ) );
			$data['options'] = array();
			foreach ( $options_raw as $opt ) {
				$opt = trim( sanitize_text_field( $opt ) );
				if ( ! empty( $opt ) ) {
					$data['options'][] = array( 'value' => $opt );
				}
			}
		}

		$result = $this->update_attribute( $attribute_id, $data );

		if ( ! $result ) {
			wp_send_json_error( array( 'message' => __( 'Failed to update attribute', 'ggm-commerce' ) ) );
		}

		wp_send_json_success( array(
			'message'   => __( 'Attribute updated successfully', 'ggm-commerce' ),
			'attribute' => $this->get_attribute( $attribute_id ),
		) );
	}

	/**
	 * AJAX: Delete variation attribute.
	 */
	public function ajax_delete_attribute() {
		check_ajax_referer( 'ggm_commerce_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'ggm-commerce' ) ) );
		}

		$attribute_id = intval( $_POST['attribute_id'] ?? 0 );
		if ( ! $attribute_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid attribute ID', 'ggm-commerce' ) ) );
		}

		$result = $this->delete_attribute( $attribute_id );

		if ( ! $result ) {
			wp_send_json_error( array( 'message' => __( 'Failed to delete attribute', 'ggm-commerce' ) ) );
		}

		wp_send_json_success( array( 'message' => __( 'Attribute deleted successfully', 'ggm-commerce' ) ) );
	}

	/**
	 * AJAX: Add attribute to group.
	 */
	public function ajax_add_attribute_to_group() {
		check_ajax_referer( 'ggm_commerce_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'ggm-commerce' ) ) );
		}

		$group_id     = intval( $_POST['group_id'] ?? 0 );
		$attribute_id = intval( $_POST['attribute_id'] ?? 0 );

		if ( ! $group_id || ! $attribute_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid group or attribute ID', 'ggm-commerce' ) ) );
		}

		$result = $this->add_attribute_to_group( $group_id, $attribute_id );

		if ( ! $result ) {
			wp_send_json_error( array( 'message' => __( 'Failed to add attribute to group', 'ggm-commerce' ) ) );
		}

		wp_send_json_success( array( 'message' => __( 'Attribute added to group', 'ggm-commerce' ) ) );
	}

	/**
	 * AJAX: Remove attribute from group.
	 */
	public function ajax_remove_attribute_from_group() {
		check_ajax_referer( 'ggm_commerce_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'ggm-commerce' ) ) );
		}

		$group_id     = intval( $_POST['group_id'] ?? 0 );
		$attribute_id = intval( $_POST['attribute_id'] ?? 0 );

		if ( ! $group_id || ! $attribute_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid group or attribute ID', 'ggm-commerce' ) ) );
		}

		$result = $this->remove_attribute_from_group( $group_id, $attribute_id );

		if ( ! $result ) {
			wp_send_json_error( array( 'message' => __( 'Failed to remove attribute from group', 'ggm-commerce' ) ) );
		}

		wp_send_json_success( array( 'message' => __( 'Attribute removed from group', 'ggm-commerce' ) ) );
	}

	/**
	 * AJAX: Set group attributes (replace all).
	 */
	public function ajax_set_group_attributes() {
		check_ajax_referer( 'ggm_commerce_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'ggm-commerce' ) ) );
		}

		$group_id      = intval( $_POST['group_id'] ?? 0 );
		$attribute_ids = isset( $_POST['attribute_ids'] ) ? array_map( 'intval', (array) $_POST['attribute_ids'] ) : array();

		if ( ! $group_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid group ID', 'ggm-commerce' ) ) );
		}

		$this->set_group_attributes( $group_id, $attribute_ids );

		wp_send_json_success( array(
			'message'    => __( 'Group attributes updated', 'ggm-commerce' ),
			'attributes' => $this->get_group_attributes( $group_id ),
		) );
	}

	/**
	 * AJAX: Install a suggestion.
	 */
	public function ajax_install_suggestion() {
		check_ajax_referer( 'ggm_commerce_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'ggm-commerce' ) ) );
		}

		$suggestion_key = sanitize_text_field( wp_unslash( $_POST['suggestion_key'] ?? '' ) );

		if ( empty( $suggestion_key ) ) {
			wp_send_json_error( array( 'message' => __( 'Invalid suggestion key', 'ggm-commerce' ) ) );
		}

		$result = $this->install_suggestion( $suggestion_key );

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

		wp_send_json_success( array(
			'message'  => __( 'Suggestion installed successfully', 'ggm-commerce' ),
			'group_id' => $result,
			'group'    => $this->get_group( $result ),
		) );
	}

	/**
	 * AJAX: Get all suggestions with install status.
	 */
	public function ajax_get_suggestions() {
		check_ajax_referer( 'ggm_commerce_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'ggm-commerce' ) ) );
		}

		$suggestions = $this->get_suggestions();
		$result      = array();

		foreach ( $suggestions as $key => $suggestion ) {
			$result[ $key ] = array_merge( $suggestion, array(
				'key'       => $key,
				'installed' => $this->is_suggestion_installed( $key ),
			) );
		}

		wp_send_json_success( array( 'suggestions' => $result ) );
	}

	/**
	 * AJAX: Add attributes from group to product variation config.
	 */
	public function ajax_add_attributes_from_group() {
		check_ajax_referer( 'ggm_commerce_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => __( 'Permission denied', 'ggm-commerce' ) ) );
		}

		$product_id = intval( $_POST['product_id'] ?? 0 );
		$group_id   = intval( $_POST['group_id'] ?? 0 );

		if ( ! $product_id || ! $group_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid product or group ID', 'ggm-commerce' ) ) );
		}

		$added = $this->add_attributes_from_group( $product_id, $group_id );

		$variations = GGM_Commerce_Variations::instance();
		$config     = $variations->get_product_variation_config( $product_id );

		wp_send_json_success( array(
			'message'    => sprintf(
				/* translators: %d: number of attributes added */
				_n( '%d attribute added to product', '%d attributes added to product', count( $added ), 'ggm-commerce' ),
				count( $added )
			),
			'added_ids'  => $added,
			'config'     => $config,
		) );
	}
}

/**
 * Get the variation attributes instance.
 *
 * @return GGM_Commerce_Variation_Attributes
 */
function ggm_commerce_variation_attributes() {
	return GGM_Commerce_Variation_Attributes::get_instance();
}
