<?php
/**
 * Offer Data Extractor
 *
 * Provides a single source of truth for extracting offer data from API responses.
 * Uses OffersV2 exclusively - V1 has been deprecated.
 */

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

require_once __DIR__ . '/traits/trait-response-normalizer.php';

class PSFA_Offer_Data_Extractor {

    use PSFA_Response_Normalizer;

    /**
     * Singleton instance
     *
     * @var PSFA_Offer_Data_Extractor|null
     */
    private static $instance = null;

    /**
     * Get singleton instance
     *
     * @return PSFA_Offer_Data_Extractor
     */
    public static function get_instance(): PSFA_Offer_Data_Extractor {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Extract all offer data from an item (V2 only)
     *
     * @param array $item API item
     * @return array Normalized offer data
     */
    public function extract_offer_data(array $item): array {
        return [
            // Price data
            'price_amount' => $this->get_price_amount($item),
            'price_display' => $this->get_price_display($item),
            'savings_percent' => $this->get_savings_percent($item),
            'savings_display' => $this->get_savings_display($item),
            'original_price_display' => $this->get_original_price_display($item),
            // Condition & availability
            'condition' => $this->get_condition($item),
            'sub_condition' => $this->get_sub_condition($item),
            'availability_message' => $this->get_availability_message($item),
            'availability_type' => $this->get_availability_type($item),
            'is_stock_scarce' => $this->is_stock_scarce($item),
            'merchant_name' => $this->get_merchant_name($item),
            // V2 Premium Features
            'is_buybox_winner' => $this->get_is_buybox_winner($item),
            'deal_badge' => $this->get_deal_badge($item),
            'deal_countdown' => $this->get_deal_countdown($item),
            'is_prime_exclusive' => $this->is_prime_exclusive_deal($item),
            'has_deal' => $this->has_deal($item),
            'used_offer' => $this->get_used_offer($item),
        ];
    }

    /**
     * Check if item has any active deal
     *
     * @param array $item API item
     * @return bool
     */
    public function has_deal(array $item): bool {
        $deal = $this->get_deal_details($item);
        return !empty($deal);
    }

    /**
     * Get deal badge text if available
     * Filters out Prime-related badges since we show blue circle for Prime Exclusive
     *
     * @param array $item API item
     * @return string|null Deal badge text or null
     */
    public function get_deal_badge(array $item): ?string {
        $deal = $this->get_deal_details($item);
        $badge = $deal['Badge'] ?? null;
        
        if (!$badge) {
            return null;
        }
        
        // Filter out redundant badges - Prime (we show blue circle) and ENDS IN (we show countdown)
        $filter_keywords = ['PRIME', 'WITH PRIME', 'PRIME EXCLUSIVE', 'PRIME EARLY ACCESS', 'ENDS IN'];
        $badge_upper = strtoupper(trim($badge));
        foreach ($filter_keywords as $keyword) {
            if (strpos($badge_upper, $keyword) !== false) {
                return null;
            }
        }
        
        return $badge;
    }

    /**
     * Get deal countdown info if available
     *
     * @param array $item API item
     * @return array|null [end_time, time_left_seconds] or null
     */
    public function get_deal_countdown(array $item): ?array {
        $deal = $this->get_deal_details($item);
        if (!isset($deal['EndTime'])) {
            return null;
        }

        $end_time = strtotime($deal['EndTime']);
        $now = time();
        $time_left = $end_time - $now;

        if ($time_left <= 0) {
            return null;
        }

        return [
            'end_time' => $deal['EndTime'],
            'time_left_seconds' => $time_left,
            'time_left_display' => $this->format_time_left($time_left),
        ];
    }

    /**
     * Format time left as human readable string
     *
     * @param int $seconds Seconds remaining
     * @return string Formatted time
     */
    private function format_time_left(int $seconds): string {
        $days = floor($seconds / 86400);
        $hours = floor(($seconds % 86400) / 3600);
        $mins = floor(($seconds % 3600) / 60);
        $secs = $seconds % 60;

        if ($days > 0) {
            return sprintf('DEAL ENDS IN <span class="psfa-time-value">%dD %dH %dM %ds</span>', $days, $hours, $mins, $secs);
        } elseif ($hours > 0) {
            return sprintf('DEAL ENDS IN <span class="psfa-time-value">%dH %dM %ds</span>', $hours, $mins, $secs);
        } else {
            return sprintf('DEAL ENDS IN <span class="psfa-time-value">%dM %ds</span>', $mins, $secs);
        }
    }

    /**
     * Check if deal is Prime exclusive
     *
     * @param array $item API item
     * @return bool
     */
    public function is_prime_exclusive_deal(array $item): bool {
        $deal = $this->get_deal_details($item);
        if (!$deal) {
            return false;
        }
        $access_type = $deal['AccessType'] ?? '';
        return in_array($access_type, ['PRIME_EXCLUSIVE', 'PRIME_EARLY_ACCESS'], true);
    }

    /**
     * Get used/alternative offer if available (V2 only)
     *
     * @param array $item API item
     * @return array|null Used offer data or null
     */
    public function get_used_offer(array $item): ?array {
        $listings = $this->get_all_listings($item);
        
        foreach ($listings as $listing) {
            $condition = $listing['Condition']['Value'] ?? '';
            if ($condition === 'Used') {
                // V2 structure
                if (isset($listing['Price']['Money'])) {
                    return [
                        'price_display' => $listing['Price']['Money']['DisplayAmount'] ?? '',
                        'price_amount' => $listing['Price']['Money']['Amount'] ?? 0,
                        'condition' => $condition,
                        'sub_condition' => $listing['Condition']['SubCondition'] ?? '',
                        'merchant' => $listing['MerchantInfo']['Name'] ?? '',
                    ];
                }
            }
        }
        
        return null;
    }
}

/**
 * Helper function to get the extractor instance
 *
 * @return PSFA_Offer_Data_Extractor
 */
function psfa_get_offer_extractor(): PSFA_Offer_Data_Extractor {
    return PSFA_Offer_Data_Extractor::get_instance();
}
