<?php

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

class AIEO_Option_Groups_Frontend {

	const FORM_FIELD = 'aieo_og_options'; 

	
	private static $instance = null;

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

	public function init() {
		
		add_action( 'woocommerce_before_add_to_cart_button', array( $this, 'render_picker' ), 15 );
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ) );

		
		add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'validate_add' ), 10, 3 );
		add_filter( 'woocommerce_add_cart_item_data',      array( $this, 'add_cart_item_data' ), 10, 3 );
		add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_from_session' ), 10, 2 );
		add_action( 'woocommerce_before_calculate_totals',  array( $this, 'before_calculate_totals' ), 20 );
		add_filter( 'woocommerce_get_item_data',            array( $this, 'get_item_data' ), 10, 2 );
		add_action( 'woocommerce_checkout_create_order_line_item', array( $this, 'add_order_line_meta' ), 10, 4 );

		
		
		add_action( 'wp_ajax_aieo_og_resolve',        array( $this, 'ajax_resolve' ) );
		add_action( 'wp_ajax_nopriv_aieo_og_resolve', array( $this, 'ajax_resolve' ) );
	}

	
	
	

	
	public static function config_for_product( $product_id ) {
		if ( ! class_exists( 'AIEO_Option_Groups_Store' ) ) { return null; }
		$cfg = AIEO_Option_Groups_Store::get_product_config( (int) $product_id );
		if ( empty( $cfg['groups'] ) ) { return null; }

		$groups = array();
		foreach ( $cfg['groups'] as $g ) {
			$options = array();
			foreach ( $g['options'] as $o ) {
				$options[] = array(
					'id'        => (int) $o['id'],
					'label'     => (string) $o['label'],
					'price'     => (float) $o['price_delta'],
					'premium'   => ! empty( $o['exclude_from_allowance'] ),
					'default'   => ! empty( $o['default_selected'] ),
					'available' => ! empty( $o['available'] ),
				);
			}
			$groups[] = array(
				'id'            => (int) $g['id'],
				'name'          => (string) $g['name'],
				'select_type'   => (string) $g['select_type'],
				'min'           => (int) $g['min_select'],
				'max'           => (int) $g['max_select'],
				'included_free' => (int) $g['included_free'],
				'free_policy'   => (string) $g['free_policy'],
				'description'   => (string) $g['description'],
				'assignment_id' => (int) $g['assignment_id'],
				'options'       => $options,
			);
		}

		$product   = wc_get_product( (int) $product_id );
		$base_price = $product ? (float) wc_get_price_to_display( $product, array( 'price' => $product->get_price() ) ) : 0.0;

		return array(
			'product_id' => (int) $product_id,
			'base_price' => $base_price,
			'currency'   => function_exists( 'get_woocommerce_currency_symbol' ) ? get_woocommerce_currency_symbol() : '',
			'groups'     => $groups,
			'rules'      => isset( $cfg['rules'] ) ? $cfg['rules'] : array(),
		);
	}

	
	
	

	public function enqueue_assets() {
		if ( ! function_exists( 'is_product' ) || ! is_product() ) { return; }
		global $product;
		$pid = $product instanceof WC_Product ? $product->get_id() : ( function_exists( 'get_the_ID' ) ? (int) get_the_ID() : 0 );
		if ( ! self::config_for_product( $pid ) ) { return; } 

		$base = defined( 'AIEO_DIR' ) ? AIEO_DIR : '';
		$jrel = 'assets/js/aieo-option-groups-frontend.js';
		$crel = 'assets/css/aieo-option-groups.css';
		$jver = ( $base && file_exists( $base . $jrel ) ) ? (string) filemtime( $base . $jrel ) : '1.0';
		$cver = ( $base && file_exists( $base . $crel ) ) ? (string) filemtime( $base . $crel ) : '1.0';
		wp_enqueue_style( 'aieo-option-groups', plugins_url( $crel, AIEO_FILE ), array(), $cver );
		wp_enqueue_script( 'aieo-option-groups-frontend', plugins_url( $jrel, AIEO_FILE ), array( 'jquery' ), $jver, true );
		wp_localize_script( 'aieo-option-groups-frontend', 'aieoOG', array(
			'ajaxurl'  => admin_url( 'admin-ajax.php' ),
			'i18n'     => array(
				'chooseMin' => __( 'Choose at least %1$d for “%2$s”.', 'ai-eshop-optimizer' ),
				'chooseMax' => __( 'Choose at most %1$d for “%2$s”.', 'ai-eshop-optimizer' ),
				'soldOut'   => __( 'Sold out', 'ai-eshop-optimizer' ),
				'free'      => __( 'free', 'ai-eshop-optimizer' ),
			),
		) );
	}

	public function render_picker() {
		global $product;
		$pid = $product instanceof WC_Product ? $product->get_id() : 0;
		$cfg = $pid ? self::config_for_product( $pid ) : null;
		if ( ! $cfg ) { return; }

		$cur = $cfg['currency'];
		echo '<div class="aieo-og" data-config="' . esc_attr( wp_json_encode( $cfg ) ) . '">';
		foreach ( $cfg['groups'] as $g ) {
			$type    = 'radio' === $g['select_type'] ? 'radio' : 'checkbox';
			$req     = $g['min'] > 0;
			$hint    = self::group_hint( $g );
			echo '<fieldset class="aieo-og-group" data-group="' . esc_attr( $g['id'] ) . '" data-type="' . esc_attr( $type ) . '" data-min="' . esc_attr( $g['min'] ) . '" data-max="' . esc_attr( $g['max'] ) . '">';
			echo '<legend class="aieo-og-legend">' . esc_html( $g['name'] );
			if ( $req ) { echo ' <span class="aieo-og-req">*</span>'; }
			if ( $hint !== '' ) { echo ' <span class="aieo-og-hint">' . esc_html( $hint ) . '</span>'; }
			echo '</legend>';
			if ( $g['description'] !== '' ) { echo '<p class="aieo-og-desc">' . esc_html( $g['description'] ) . '</p>'; }

			foreach ( $g['options'] as $o ) {
				$oid     = (int) $o['id'];
				$avail   = ! empty( $o['available'] );
				$priceTx = self::price_label( (float) $o['price'], $cur );
				$id_attr = 'aieo-og-o-' . $g['id'] . '-' . $oid;
				echo '<label class="aieo-og-option' . ( $avail ? '' : ' is-soldout' ) . '" for="' . esc_attr( $id_attr ) . '">';
				echo '<input type="' . esc_attr( $type ) . '" id="' . esc_attr( $id_attr ) . '" name="' . esc_attr( self::FORM_FIELD ) . '[]" value="' . esc_attr( $oid ) . '"'
					. ' data-group="' . esc_attr( $g['id'] ) . '" data-price="' . esc_attr( $o['price'] ) . '"'
					. ( $o['default'] && $avail ? ' checked' : '' )
					. ( $avail ? '' : ' disabled' ) . '>';
				echo '<span class="aieo-og-label">' . esc_html( $o['label'] ) . '</span>';
				if ( $priceTx !== '' ) { echo ' <span class="aieo-og-price">' . esc_html( $priceTx ) . '</span>'; }
				if ( ! $avail ) { echo ' <span class="aieo-og-soldout">' . esc_html__( 'Sold out', 'ai-eshop-optimizer' ) . '</span>'; }
				echo '</label>';
			}
			echo '</fieldset>';
		}
		
		echo '<div class="aieo-og-foot"><span class="aieo-og-total-label">' . esc_html__( 'Total', 'ai-eshop-optimizer' ) . '</span> '
			. '<span class="aieo-og-total" aria-live="polite"></span>'
			. '<div class="aieo-og-errors" role="alert"></div></div>';
		echo '</div>';
	}

	private static function group_hint( $g ) {
		$bits = array();
		if ( $g['min'] > 0 && $g['min'] === $g['max'] ) {
			$bits[] = sprintf( _n( 'choose %d', 'choose %d', $g['min'], 'ai-eshop-optimizer' ), $g['min'] );
		} else {
			if ( $g['min'] > 0 ) { $bits[] = sprintf( __( 'min %d', 'ai-eshop-optimizer' ), $g['min'] ); }
			if ( $g['max'] > 0 ) { $bits[] = sprintf( __( 'up to %d', 'ai-eshop-optimizer' ), $g['max'] ); }
		}
		if ( $g['included_free'] > 0 ) { $bits[] = sprintf( __( '%d free', 'ai-eshop-optimizer' ), $g['included_free'] ); }
		return $bits ? '(' . implode( ', ', $bits ) . ')' : '';
	}

	private static function price_label( $delta, $cur ) {
		if ( abs( $delta ) < 0.00001 ) { return ''; }
		$sign = $delta > 0 ? '+' : '−';
		return $sign . $cur . number_format_i18n( abs( $delta ), 2 );
	}

	
	
	

	
	private static function posted_selection() {
		if ( empty( $_POST[ self::FORM_FIELD ] ) ) { return array(); } 
		$raw = (array) wp_unslash( $_POST[ self::FORM_FIELD ] ); 
		return array_values( array_unique( array_filter( array_map( 'intval', $raw ) ) ) );
	}

	public function validate_add( $passed, $product_id, $qty ) {
		$cfg = self::config_for_product( $product_id );
		if ( ! $cfg ) { return $passed; } 
		$res = AIEO_Option_Groups_Pricing::resolve( AIEO_Option_Groups_Store::get_product_config( $product_id ), self::posted_selection() );
		if ( ! $res['valid'] ) {
			foreach ( $res['errors'] as $err ) { wc_add_notice( $err, 'error' ); }
			return false;
		}
		return $passed;
	}

	public function add_cart_item_data( $data, $product_id, $variation_id ) {
		$cfg = self::config_for_product( $product_id );
		if ( ! $cfg ) { return $data; }
		$selected = self::posted_selection();
		$store    = AIEO_Option_Groups_Store::get_product_config( $product_id );
		$res      = AIEO_Option_Groups_Pricing::resolve( $store, $selected );
		if ( ! $res['valid'] ) { return $data; } 
		$data['aieo_og'] = array(
			'options'     => $selected,
			'total_delta' => (float) $res['total_delta'],
			'lines'       => $res['lines'], 
		);
		
		
		$data['aieo_og_sig'] = md5( wp_json_encode( $selected ) );
		return $data;
	}

	public function get_cart_item_from_session( $item, $values ) {
		if ( isset( $values['aieo_og'] ) ) { $item['aieo_og'] = $values['aieo_og']; }
		return $item;
	}

	public function before_calculate_totals( $cart ) {
		if ( is_admin() && ! defined( 'DOING_AJAX' ) ) { return; }
		if ( ! $cart || ! method_exists( $cart, 'get_cart' ) ) { return; }
		foreach ( $cart->get_cart() as $item ) {
			if ( empty( $item['aieo_og'] ) || empty( $item['data'] ) ) { continue; }
			$product = $item['data'];
			$base    = (float) $product->get_price( 'edit' );
			$product->set_price( $base + (float) $item['aieo_og']['total_delta'] );
		}
	}

	public function get_item_data( $item_data, $cart_item ) {
		if ( empty( $cart_item['aieo_og']['lines'] ) ) { return $item_data; }
		$cur = function_exists( 'get_woocommerce_currency_symbol' ) ? get_woocommerce_currency_symbol() : '';
		foreach ( $cart_item['aieo_og']['lines'] as $line ) {
			$val = $line['label'];
			if ( ! empty( $line['free'] ) ) {
				$val .= ' (' . __( 'free', 'ai-eshop-optimizer' ) . ')';
			} elseif ( abs( (float) $line['charged_delta'] ) > 0.00001 ) {
				$val .= ' (+' . $cur . number_format_i18n( (float) $line['charged_delta'], 2 ) . ')';
			}
			$item_data[] = array(
				'key'     => __( 'Option', 'ai-eshop-optimizer' ),
				'value'   => $val,
				'display' => $val,
			);
		}
		return $item_data;
	}

	public function add_order_line_meta( $item, $cart_item_key, $values, $order ) {
		if ( empty( $values['aieo_og']['lines'] ) ) { return; }
		$cur = function_exists( 'get_woocommerce_currency_symbol' ) ? get_woocommerce_currency_symbol() : '';
		foreach ( $values['aieo_og']['lines'] as $line ) {
			$val = $line['label'];
			if ( empty( $line['free'] ) && abs( (float) $line['charged_delta'] ) > 0.00001 ) {
				$val .= ' (+' . $cur . number_format_i18n( (float) $line['charged_delta'], 2 ) . ')';
			} elseif ( ! empty( $line['free'] ) ) {
				$val .= ' (' . __( 'free', 'ai-eshop-optimizer' ) . ')';
			}
			$item->add_meta_data( $line['label'] , $val, false );
		}
		
		$item->add_meta_data( '_aieo_og_options', $values['aieo_og']['options'], true );
	}

	
	
	

	public function ajax_resolve() {
		$pid = isset( $_POST['product_id'] ) ? (int) $_POST['product_id'] : 0; 
		$sel = isset( $_POST['options'] ) ? array_map( 'intval', (array) wp_unslash( $_POST['options'] ) ) : array(); 
		$cfg = $pid ? self::config_for_product( $pid ) : null;
		if ( ! $cfg ) { wp_send_json_error(); }
		$res = AIEO_Option_Groups_Pricing::resolve( AIEO_Option_Groups_Store::get_product_config( $pid ), $sel );
		wp_send_json_success( array(
			'base_price'  => $cfg['base_price'],
			'total_delta' => $res['total_delta'],
			'total'       => $cfg['base_price'] + $res['total_delta'],
			'valid'       => $res['valid'],
			'errors'      => $res['errors'],
			'lines'       => $res['lines'],
		) );
	}
}
