<?php
/**
 * Context Helper for AI Alt Text
 *
 * Fetches WooCommerce product context, SEO keyphrases, and translation language.
 *
 * @package AIAltTextGenerator
 * @since 1.2.0
 */

namespace AIAltTextGenerator;

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

/**
 * Context Helper Class
 *
 * @since 1.2.0
 */
class ContextHelper {

	/**
	 * Get context for an attachment (product title, SEO keyphrase, language).
	 *
	 * @param int $attachment_id Attachment ID.
	 * @return array{product_title: string, keyphrase: string, language: string, product_category: string, product_short_description: string, variation_attributes: string}
	 */
	public static function getContext( int $attachment_id ): array {
		$product_id = self::getProductIdForAttachment( $attachment_id );

		return [
			'product_title'             => self::getProductTitle( $attachment_id ),
			'keyphrase'                 => self::getEffectiveKeyphrase( $attachment_id ),
			'language'                  => self::getPostLanguage( $attachment_id ),
			'product_category'          => $product_id ? self::getProductCategories( $product_id ) : '',
			'product_short_description' => $product_id ? self::getProductShortDescription( $product_id ) : '',
			'variation_attributes'      => self::getVariationAttributes( $attachment_id ),
		];
	}

	/**
	 * Resolve WooCommerce product ID for an attachment.
	 */
	public static function getProductIdForAttachment( int $attachment_id ): int {
		if ( ! class_exists( 'WooCommerce' ) ) {
			return 0;
		}

		global $wpdb;

		$product_id = (int) $wpdb->get_var(
			$wpdb->prepare(
				"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_thumbnail_id' AND meta_value = %s LIMIT 1",
				$attachment_id
			)
		);
		if ( $product_id > 0 ) {
			$post = get_post( $product_id );
			if ( $post && $post->post_type === 'product_variation' ) {
				return (int) $post->post_parent;
			}
			if ( $post && $post->post_type === 'product' ) {
				return $product_id;
			}
		}

		$products = $wpdb->get_col(
			$wpdb->prepare(
				"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_product_image_gallery' AND meta_value LIKE %s LIMIT 1",
				'%' . $wpdb->esc_like( (string) $attachment_id ) . '%'
			)
		);
		if ( ! empty( $products ) ) {
			return (int) $products[0];
		}

		$post = get_post( $attachment_id );
		if ( $post && $post->post_parent > 0 ) {
			$parent = get_post( $post->post_parent );
			if ( $parent && $parent->post_type === 'product' ) {
				return (int) $parent->ID;
			}
		}

		return 0;
	}

	private static function getProductCategories( int $product_id ): string {
		$terms = get_the_terms( $product_id, 'product_cat' );
		if ( ! is_array( $terms ) ) {
			return '';
		}

		$names = array_map(
			static function ( $term ) {
				return $term instanceof \WP_Term ? $term->name : '';
			},
			$terms
		);

		return implode( ', ', array_filter( $names ) );
	}

	private static function getProductShortDescription( int $product_id ): string {
		$post = get_post( $product_id );
		if ( ! $post ) {
			return '';
		}

		return trim( wp_strip_all_tags( (string) $post->post_excerpt ) );
	}

	private static function getVariationAttributes( int $attachment_id ): string {
		if ( ! function_exists( 'wc_get_product' ) ) {
			return '';
		}

		global $wpdb;
		$variation_id = (int) $wpdb->get_var(
			$wpdb->prepare(
				"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_thumbnail_id' AND meta_value = %s LIMIT 1",
				$attachment_id
			)
		);

		if ( $variation_id <= 0 ) {
			return '';
		}

		$variation = wc_get_product( $variation_id );
		if ( ! $variation || ! $variation->is_type( 'variation' ) ) {
			return '';
		}

		$attrs = $variation->get_variation_attributes();
		if ( ! is_array( $attrs ) || $attrs === [] ) {
			return '';
		}

		$parts = [];
		foreach ( $attrs as $key => $value ) {
			if ( $value !== '' ) {
				$parts[] = ucwords( str_replace( [ 'attribute_', '-' ], [ '', ' ' ], (string) $key ) ) . ': ' . $value;
			}
		}

		return implode( ', ', $parts );
	}

	/**
	 * Get product title if attachment is a WooCommerce product image.
	 *
	 * @param int $attachment_id Attachment ID.
	 * @return string
	 */
	public static function getProductTitle( int $attachment_id ): string {
		if ( ! class_exists( 'WooCommerce' ) ) {
			return '';
		}

		$settings = Settings::get();
		if ( ! empty( $settings['woo_use_image_title'] ) ) {
			$post = get_post( $attachment_id );
			if ( $post && trim( (string) $post->post_title ) !== '' ) {
				return trim( (string) $post->post_title );
			}
		}

		$product_id = self::getProductIdForAttachment( $attachment_id );
		if ( $product_id <= 0 ) {
			return '';
		}

		$title = get_the_title( $product_id );
		$title = is_string( $title ) ? $title : '';

		$variation_attrs = self::getVariationAttributes( $attachment_id );
		if ( $variation_attrs !== '' ) {
			return trim( $title . ' — ' . $variation_attrs );
		}

		return $title;
	}

	/**
	 * Get focus keyphrase from SEO plugins (parent post).
	 *
	 * @param int $attachment_id Attachment ID.
	 * @return string
	 */
	public static function getSeoKeyphrase( int $attachment_id ): string {
		$post_id = self::getParentPostId( $attachment_id );
		if ( ! $post_id ) {
			$post_id = self::getProductIdForAttachment( $attachment_id );
		}
		if ( ! $post_id ) {
			return '';
		}

		// Yoast SEO
		$kw = get_post_meta( $post_id, '_yoast_wpseo_focuskw', true );
		if ( is_string( $kw ) && trim( $kw ) !== '' ) {
			return trim( $kw );
		}

		// Rank Math
		$kw = get_post_meta( $post_id, 'rank_math_focus_keyword', true );
		if ( is_string( $kw ) && trim( $kw ) !== '' ) {
			return trim( $kw );
		}

		// All in One SEO
		$kw = get_post_meta( $post_id, '_aioseo_focus_keyphrase', true );
		if ( is_string( $kw ) && trim( $kw ) !== '' ) {
			return trim( $kw );
		}

		// SEOPress
		$kw = get_post_meta( $post_id, '_seopress_focus_kw', true );
		if ( is_string( $kw ) && trim( $kw ) !== '' ) {
			return trim( $kw );
		}

		// The SEO Framework
		$kw = get_post_meta( $post_id, '_genesis_focus_keyword', true );
		if ( is_string( $kw ) && trim( $kw ) !== '' ) {
			return trim( $kw );
		}

		// SmartCrawl
		$meta = get_post_meta( $post_id, '_wds_metabox', true );
		if ( is_array( $meta ) && ! empty( $meta['focus_keyword'] ) ) {
			return trim( (string) $meta['focus_keyword'] );
		}

		// Squirrly SEO — modern snippet keywords (comma-separated).
		$kw = get_post_meta( $post_id, '_sq_keywords', true );
		if ( is_string( $kw ) && trim( $kw ) !== '' ) {
			$parts = array_values(
				array_filter(
					array_map( 'trim', explode( ',', $kw ) )
				)
			);
			if ( $parts !== [] ) {
				return $parts[0];
			}
		}

		// Squirrly SEO — focus keyword JSON blob.
		$sq_json = get_post_meta( $post_id, '_sq_post_keyword', true );
		if ( is_string( $sq_json ) && $sq_json !== '' ) {
			$decoded = json_decode( $sq_json );
			if ( is_object( $decoded ) && ! empty( $decoded->keyword ) && is_string( $decoded->keyword ) ) {
				$focus = trim( $decoded->keyword );
				if ( $focus !== '' ) {
					return $focus;
				}
			}
		}

		// Legacy / alternate Squirrly key.
		$kw = get_post_meta( $post_id, '_sq_keyword', true );
		if ( is_string( $kw ) && trim( $kw ) !== '' ) {
			return trim( $kw );
		}

		return '';
	}

	/**
	 * SEO focus keyphrase, falling back to parent post title when configured.
	 */
	public static function getEffectiveKeyphrase( int $attachment_id, ?array $settings = null ): string {
		$settings = $settings ?? Settings::get();
		if ( empty( $settings['use_seo_keyphrase'] ) && empty( $settings['use_post_title_keywords'] ) ) {
			return '';
		}

		$keyphrase = '';
		if ( ! empty( $settings['use_seo_keyphrase'] ) ) {
			$keyphrase = self::getSeoKeyphrase( $attachment_id );
		}
		if ( $keyphrase !== '' ) {
			return $keyphrase;
		}

		if ( empty( $settings['use_post_title_keywords'] ) ) {
			return '';
		}

		$post_id = self::getParentPostId( $attachment_id );
		if ( $post_id <= 0 ) {
			$post_id = self::getProductIdForAttachment( $attachment_id );
		}
		if ( $post_id <= 0 ) {
			return '';
		}

		$title = get_the_title( $post_id );

		return is_string( $title ) ? trim( $title ) : '';
	}

	/**
	 * Get post language for WPML/Polylang.
	 *
	 * @param int $attachment_id Attachment ID.
	 * @return string Language code or name.
	 */
	public static function getPostLanguage( int $attachment_id ): string {
		$post_id = self::getParentPostId( $attachment_id );
		if ( ! $post_id ) {
			$post_id = $attachment_id;
		}

		// WPML
		if ( defined( 'ICL_SITEPRESS_VERSION' ) && function_exists( 'apply_filters' ) ) {
			$lang = apply_filters( 'wpml_element_language_code', null, [ 'element_id' => $post_id, 'element_type' => 'post_' . get_post_type( $post_id ) ] );
			if ( is_string( $lang ) && $lang !== '' ) {
				$lang_names = apply_filters( 'wpml_active_languages', [] );
				return $lang_names[ $lang ]['native_name'] ?? $lang;
			}
		}

		// Polylang
		if ( function_exists( 'pll_get_post_language' ) ) {
			$lang = pll_get_post_language( $post_id, 'name' );
			if ( is_string( $lang ) && $lang !== '' ) {
				return $lang;
			}
		}

		return '';
	}

	/**
	 * Get parent post ID for an attachment.
	 *
	 * @param int $attachment_id Attachment ID.
	 * @return int
	 */
	private static function getParentPostId( int $attachment_id ): int {
		$post = get_post( $attachment_id );
		if ( ! $post || $post->post_parent <= 0 ) {
			return 0;
		}
		return (int) $post->post_parent;
	}

	/**
	 * Lightweight attachment metadata hints for the vision prompt.
	 *
	 * Filenames are lowest priority and must never override visible content.
	 *
	 * @return array<string, string>
	 */
	public static function getAttachmentHints( int $attachment_id ): array {
		$post = get_post( $attachment_id );
		if ( ! $post instanceof \WP_Post ) {
			return [];
		}

		$hints = [];

		$title = trim( (string) $post->post_title );
		if ( $title !== '' && ! self::looksLikeFilename( $title ) ) {
			$hints['attachment_title'] = Text::slice( $title, 0, 120 );
		}

		$caption = trim( wp_strip_all_tags( (string) $post->post_excerpt ) );
		if ( $caption !== '' ) {
			$hints['caption'] = Text::slice( $caption, 0, 160 );
		}

		$description = trim( wp_strip_all_tags( (string) $post->post_content ) );
		if ( $description !== '' ) {
			$hints['description'] = Text::slice( $description, 0, 200 );
		}

		$parent_id = (int) $post->post_parent;
		if ( $parent_id > 0 ) {
			$parent_title = get_the_title( $parent_id );
			if ( is_string( $parent_title ) && trim( $parent_title ) !== '' ) {
				$hints['parent_title'] = Text::slice( trim( $parent_title ), 0, 120 );
			}
		}

		$file = get_attached_file( $attachment_id, true );
		if ( is_string( $file ) && $file !== '' ) {
			$basename = pathinfo( $file, PATHINFO_FILENAME );
			$cleaned  = self::humanizeFilename( (string) $basename );
			if ( $cleaned !== '' ) {
				$hints['filename_hint'] = Text::slice( $cleaned, 0, 80 );
			}
		}

		return $hints;
	}

	private static function looksLikeFilename( string $value ): bool {
		return (bool) preg_match( '/\.(jpe?g|png|gif|webp|avif|bmp|tiff?|svg)$/i', $value )
			|| (bool) preg_match( '/^[a-f0-9-]{16,}$/i', $value );
	}

	private static function humanizeFilename( string $basename ): string {
		$basename = preg_replace( '/[-_]+/', ' ', $basename ) ?? $basename;
		$basename = preg_replace( '/\b(\d{3,}|img|image|photo|dsc|screenshot)\b/i', ' ', $basename ) ?? $basename;
		$basename = trim( preg_replace( '/\s+/', ' ', $basename ) ?? '' );

		if ( $basename === '' || Text::length( $basename ) < 3 ) {
			return '';
		}

		return $basename;
	}

	/**
	 * Get image stats (total supported, without alt).
	 *
	 * @return array{total: int, without_alt: int}
	 */
	public static function getImageStats(): array {
		$summary = Scanner::getSummary();

		return [
			'total'       => (int) ( $summary['total'] ?? 0 ),
			'without_alt' => (int) ( $summary['missing'] ?? 0 ),
		];
	}
}
