<?php

namespace FleekDash\Controllers\Posts;

/**
 * Helper for post image URL resolution in Posts Actions.
 * Extracts logic to reduce cognitive complexity.
 *
 * @package FleekDash\Controllers\Posts
 */
class PostsActionsImageHelper
{
    private const FALLBACK_SIZES = ['thumbnail', 'medium', 'medium_large', 'large'];

    /**
     * Get the smallest available image URL for an attachment
     *
     * @param int $attachmentId Attachment ID
     * @return string Image URL or empty string
     */
    public static function getSmallestAvailableImageUrl(int $attachmentId): string
    {
        $result = '';
        if ($attachmentId) {
            $result = wp_get_attachment_image_url($attachmentId, 'fleekdash-thumbnail')
                ?: self::tryFromMetadataSizes($attachmentId)
                ?: self::tryFallbackSizes($attachmentId)
                ?: (\wp_get_attachment_url($attachmentId) ?: '');
        }

        return $result;
    }

    /**
     * Try to get URL from attachment metadata sizes (smallest first)
     */
    private static function tryFromMetadataSizes(int $attachmentId): string
    {
        $meta = \wp_get_attachment_metadata($attachmentId);
        if (empty($meta['sizes']) || !\is_array($meta['sizes'])) {
            return '';
        }

        $sizeNames = self::getSizeNamesSortedByArea($meta['sizes']);

        return self::findFirstAvailableSizeUrl($attachmentId, $sizeNames);
    }

    /**
     * Get size names sorted by area (smallest first)
     *
     * @param array<string, array> $sizes
     * @return array<int, string>
     */
    private static function getSizeNamesSortedByArea(array $sizes): array
    {
        $sizeToArea = [];
        foreach ($sizes as $sizeName => $info) {
            if (isset($info['width'], $info['height'])) {
                $sizeToArea[$sizeName] = (int) $info['width'] * (int) $info['height'];
            }
        }
        if (empty($sizeToArea)) {
            return [];
        }
        asort($sizeToArea);

        return array_keys($sizeToArea);
    }

    /**
     * Find first available image URL for given size names
     *
     * @param int $attachmentId
     * @param array<int, string> $sizeNames
     * @return string
     */
    private static function findFirstAvailableSizeUrl(int $attachmentId, array $sizeNames): string
    {
        foreach ($sizeNames as $sizeName) {
            $candidate = wp_get_attachment_image_url($attachmentId, $sizeName);
            if ($candidate) {
                return $candidate;
            }
        }

        return '';
    }

    /**
     * Try standard WordPress image sizes
     */
    private static function tryFallbackSizes(int $attachmentId): string
    {
        foreach (self::FALLBACK_SIZES as $fallbackSize) {
            $candidate = wp_get_attachment_image_url($attachmentId, $fallbackSize);
            if ($candidate) {
                return $candidate;
            }
        }

        return '';
    }

    /**
     * Get post image data with proper priority order (logo > featured > attached)
     *
     * @param int $postId The post ID
     * @return array{url: string, type: string}
     */
    public static function getPostImageData(int $postId): array
    {
        $result = self::tryLogoImage($postId);
        if ($result['type'] !== 'none') {
            return $result;
        }

        $result = self::tryFeaturedImage($postId);
        if ($result['type'] !== 'none') {
            return $result;
        }

        return self::tryAttachedImage($postId);
    }

    private static function tryLogoImage(int $postId): array
    {
        $logoId = (int) \get_post_meta($postId, 'logo', true);
        if (!$logoId) {
            return ['url' => '', 'type' => 'none'];
        }

        $logoUrl = self::getSmallestAvailableImageUrl($logoId);
        return $logoUrl
            ? ['url' => $logoUrl, 'type' => 'logo']
            : ['url' => '', 'type' => 'none'];
    }

    private static function tryFeaturedImage(int $postId): array
    {
        if (!has_post_thumbnail($postId)) {
            return ['url' => '', 'type' => 'none'];
        }

        $thumbnailId = get_post_thumbnail_id($postId);
        if (!$thumbnailId) {
            return ['url' => '', 'type' => 'none'];
        }

        $thumbnailUrl = self::getSmallestAvailableImageUrl((int) $thumbnailId);
        return $thumbnailUrl
            ? ['url' => $thumbnailUrl, 'type' => 'featured']
            : ['url' => '', 'type' => 'none'];
    }

    private static function tryAttachedImage(int $postId): array
    {
        $attachedImages = get_attached_media('image', $postId);
        if (empty($attachedImages)) {
            return ['url' => '', 'type' => 'none'];
        }

        $firstImage = reset($attachedImages);
        $imageUrl = self::getSmallestAvailableImageUrl((int) $firstImage->ID);
        return $imageUrl
            ? ['url' => $imageUrl, 'type' => 'attached']
            : ['url' => '', 'type' => 'none'];
    }
}
