<?php
/**
 * Frontend support for variation galleries imported by Niwa partner clones.
 *
 * @package Niwa_AI
 */

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

class Niwa_AI_Variation_Gallery {
	const FALLBACK_GALLERY_IMAGE_IDS_META = '_niwa_variation_gallery_image_ids';

	public function register_hooks() {
		add_filter( 'woocommerce_available_variation', array( $this, 'add_variation_gallery_payload' ), 20, 3 );
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue' ), 30 );
	}

	public function add_variation_gallery_payload( $data, $product, $variation ) {
		$variation_id = $this->variation_id( $variation );
		if ( $variation_id <= 0 ) {
			return $data;
		}

		$ids = get_post_meta( $variation_id, $this->gallery_image_ids_meta_key(), true );
		$ids = is_array( $ids ) ? array_values( array_unique( array_filter( array_map( 'intval', $ids ) ) ) ) : array();
		if ( count( $ids ) < 2 ) {
			return $data;
		}

		$images = array();
		foreach ( $ids as $attachment_id ) {
			$image = $this->attachment_payload( $attachment_id );
			if ( ! empty( $image ) ) {
				$images[] = $image;
			}
		}

		if ( count( $images ) < 2 ) {
			return $data;
		}

		$data['niwa_variation_gallery'] = array(
			'variation_id' => $variation_id,
			'image_ids'    => $ids,
			'images'       => $images,
		);
		return $data;
	}

	public function enqueue() {
		if ( ! function_exists( 'is_product' ) || ! is_product() || ! class_exists( 'WooCommerce' ) ) {
			return;
		}

		$product = wc_get_product( get_queried_object_id() );
		if ( ! $product || ! $product->is_type( 'variable' ) || ! $this->product_has_imported_variation_gallery( $product ) ) {
			return;
		}

		$deps = array( 'jquery' );
		if ( wp_script_is( 'wc-add-to-cart-variation', 'registered' ) || wp_script_is( 'wc-add-to-cart-variation', 'enqueued' ) ) {
			$deps[] = 'wc-add-to-cart-variation';
		}

		wp_enqueue_script(
			'niwa-variation-gallery',
			NIWA_AI_URL . 'assets/js/niwa-variation-gallery.js',
			$deps,
			$this->asset_version( 'assets/js/niwa-variation-gallery.js' ),
			array( 'in_footer' => true )
		);
	}

	private function product_has_imported_variation_gallery( $product ) {
		foreach ( (array) $product->get_children() as $variation_id ) {
			$ids = get_post_meta( intval( $variation_id ), $this->gallery_image_ids_meta_key(), true );
			if ( is_array( $ids ) && count( array_filter( array_map( 'intval', $ids ) ) ) >= 2 ) {
				return true;
			}
		}
		return false;
	}

	private function gallery_image_ids_meta_key() {
		if ( class_exists( 'Niwa_AI_Admin_Partner_Product_Variant_Media' ) ) {
			return Niwa_AI_Admin_Partner_Product_Variant_Media::META_GALLERY_IMAGE_IDS;
		}

		return self::FALLBACK_GALLERY_IMAGE_IDS_META;
	}

	private function variation_id( $variation ) {
		if ( is_object( $variation ) && method_exists( $variation, 'get_id' ) ) {
			return intval( $variation->get_id() );
		}
		if ( is_array( $variation ) && ! empty( $variation['variation_id'] ) ) {
			return intval( $variation['variation_id'] );
		}
		return 0;
	}

	private function attachment_payload( $attachment_id ) {
		$attachment_id = intval( $attachment_id );
		if ( $attachment_id <= 0 ) {
			return array();
		}

		$full  = wp_get_attachment_image_src( $attachment_id, 'full' );
		$thumb = wp_get_attachment_image_src( $attachment_id, 'woocommerce_thumbnail' );
		if ( empty( $full[0] ) ) {
			return array();
		}

		$alt   = get_post_meta( $attachment_id, '_wp_attachment_image_alt', true );
		$title = get_the_title( $attachment_id );
		return array(
			'id'        => $attachment_id,
			'full_src'  => esc_url_raw( $full[0] ),
			'full_w'    => isset( $full[1] ) ? intval( $full[1] ) : 0,
			'full_h'    => isset( $full[2] ) ? intval( $full[2] ) : 0,
			'thumb_src' => ! empty( $thumb[0] ) ? esc_url_raw( $thumb[0] ) : esc_url_raw( $full[0] ),
			'srcset'    => wp_get_attachment_image_srcset( $attachment_id, 'full' ),
			'sizes'     => wp_get_attachment_image_sizes( $attachment_id, 'full' ),
			'alt'       => is_string( $alt ) ? $alt : '',
			'title'     => is_string( $title ) ? $title : '',
		);
	}

	private function asset_version( $relative_path ) {
		$path = NIWA_AI_DIR . ltrim( $relative_path, '/' );
		return file_exists( $path ) ? (string) filemtime( $path ) : ( defined( 'NIWA_AI_VERSION' ) ? NIWA_AI_VERSION : '1.0.0' );
	}
}
