<?php

namespace Fotogenic_AI;

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

final class Generate_Image_Builder {
	private const MAX_PRODUCT_IMAGES = 10;

    /** @return array|\WP_Error */
    public function build_for_generate_start(
        int $product_id,
        ProductImageSourceAdapter $image_source_adapter,
        ?array $selected_gallery_ids,
        int $subject_image_id,
        int $inspiration_image_id,
        int $environment_image_id = 0,
        string $run_target = 'product',
        bool $exclude_featured = false
    ) {
        $image_data = $image_source_adapter->get_image_ids_for_product( $product_id );
        if ( is_wp_error( $image_data ) ) {
            return $image_data;
        }
        $featured_id = (int) ( $image_data['featured'] ?? 0 );
        $product_image_ids = $this->build_product_image_ids(
            $image_data,
            $selected_gallery_ids,
            [ $subject_image_id, $environment_image_id ],
            $exclude_featured
        );

        $subject_image = $this->resolve_image( $subject_image_id );
        if ( is_wp_error( $subject_image ) ) {
            return $subject_image;
        }

        $environment_image = $this->resolve_image( $environment_image_id );
        if ( is_wp_error( $environment_image ) ) {
            return $environment_image;
        }

        $product_image_ids = $this->apply_product_limits(
            $product_image_ids,
			$featured_id
        );

        $product_images = Image_Source_Resolver::instance()->get_image_files_for_attachments( $product_image_ids );
        if ( is_wp_error( $product_images ) ) {
            return $product_images;
        }

        $inspiration_image = $this->resolve_image( $inspiration_image_id );
        if ( is_wp_error( $inspiration_image ) ) {
            return $inspiration_image;
        }

        return [
            'product_images'    => $product_images,
            'subject_image'     => $subject_image,
            'environment_image' => $environment_image,
            'inspiration_image' => $inspiration_image,
        ];
    }

    /**
     * @param array{featured: int, gallery: int[]} $image_data From ProductImageSourceAdapter::get_image_ids_for_product().
     */
    private function build_product_image_ids( array $image_data, ?array $selected_gallery_ids, array $excluded_ids, bool $exclude_featured = false ): array {
        $featured_id = (int) ( $image_data['featured'] ?? 0 );
        $gallery_ids = is_array( $selected_gallery_ids )
            ? array_values( array_unique( array_filter( array_map( 'absint', $selected_gallery_ids ) ) ) )
            : array_map( 'absint', (array) ( $image_data['gallery'] ?? [] ) );

        $excluded_ids = array_values( array_unique( array_filter( array_map( 'absint', $excluded_ids ) ) ) );
        $image_ids = [];

        if ( ! $exclude_featured && $featured_id > 0 && ! in_array( $featured_id, $excluded_ids, true ) ) {
            $image_ids[] = $featured_id;
        }
        foreach ( $gallery_ids as $gallery_id ) {
            $gallery_id = (int) $gallery_id;
            if ( $gallery_id <= 0 ) {
                continue;
            }
            if ( $gallery_id === $featured_id ) {
                continue;
            }
            if ( in_array( $gallery_id, $excluded_ids, true ) ) {
                continue;
            }
            $image_ids[] = $gallery_id;
        }

        return array_values( array_unique( array_filter( $image_ids ) ) );
    }

    private function apply_product_limits(
        array $image_ids,
		int $featured_id
    ): array {
        $image_ids = array_values( array_unique( array_filter( $image_ids ) ) );
		if ( count( $image_ids ) <= self::MAX_PRODUCT_IMAGES ) {
            return $image_ids;
        }
		$sliced = array_slice( $image_ids, 0, self::MAX_PRODUCT_IMAGES );
        if ( $featured_id > 0 && in_array( $featured_id, $image_ids, true ) && ! in_array( $featured_id, $sliced, true ) ) {
			$sliced[ self::MAX_PRODUCT_IMAGES - 1 ] = $featured_id;
        }
        return array_values( array_unique( $sliced ) );
    }

    /** @return array|string|\WP_Error */
    private function resolve_image( int $attachment_id ) {
        if ( $attachment_id <= 0 ) {
            return '';
        }
        return Image_Source_Resolver::instance()->get_image_file_for_attachment( $attachment_id );
    }
    /**
     * Log image_build_counts for a request from the actual payload (e.g. media paths or when not using the full builder).
     * subject_included must reflect whether a subject image was included in the request payload, not personPresence.
     * total_count must match request_meta.images_count_input for the same request.
     *
     * @param string $context              Log context (e.g. 'generate_configuration', 'generate_start').
     * @param string $run_target          Run target (e.g. 'product', 'media').
     * @param int    $total_count          Total input images count (must match images_count_input in request_meta).
     * @param bool   $subject_included     Whether a subject image was included in the payload.
     * @param bool   $environment_included Whether an environment image was included in the payload.
     * @param int    $primary_images_count Count of primary input images in the payload.
     * @param bool   $primary_included     Whether the primary/source image is included.
     * @param bool   $inspiration_included Whether an inspiration image was included (if applicable).
     */
    public function log_counts_for_request(
        string $context,
        string $run_target,
        int $total_count,
        bool $subject_included,
        bool $environment_included,
        int $primary_images_count,
        bool $primary_included,
        bool $inspiration_included = false
    ): void {
        $logger = Logger::instance();
        if ( ! $logger->enabled() ) {
            return;
        }
        $counts = [
            'run_target'           => $run_target,
            'primary_included'     => $primary_included,
            'primary_images_count' => $primary_images_count,
            'subject_included'     => $subject_included,
            'environment_included' => $environment_included,
            'total_count'          => $total_count,
        ];
        if ( $inspiration_included ) {
            $counts['inspiration_included'] = true;
        }
        $logger->info( 'image_build_counts', array_merge( [ 'context' => $context ], $counts ) );
    }
}
