<?php

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

final class AIEO_Price_History {

    const TABLE       = 'aieo_price_history';
    const CACHE_GROUP = 'aieo_price_history';
    const WINDOW_DAYS = 30;

    private static function tbl() { global $wpdb; return $wpdb->prefix . self::TABLE; }

    public static function default_currency() {
        $c = function_exists('get_woocommerce_currency') ? (string) get_woocommerce_currency() : '';
        return $c !== '' ? $c : 'EUR';
    }

    
    
    

    
    public static function last_row($product_id, $currency) {
        global $wpdb; $t = self::tbl();
        
        return $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$t} WHERE product_id = %d AND currency = %s ORDER BY observed_at DESC, id DESC LIMIT 1",
            (int) $product_id, $currency
        ), ARRAY_A);
    }

    
    public static function record($product_id, $effective, $regular, $on_sale, $source = 'price_change_hook', $parent_id = 0, $currency = null) {
        $product_id = (int) $product_id;
        if ($product_id <= 0) { return false; }
        $effective = round((float) $effective, 4);
        if ($effective <= 0) { return false; } 

        $currency = $currency ?: self::default_currency();
        $last = self::last_row($product_id, $currency);
        if ($last && abs((float) $last['price'] - $effective) < 0.00005) {
            return false; 
        }

        global $wpdb;
        $wpdb->insert(self::tbl(), array(
            'product_id'    => $product_id,
            'parent_id'     => ((int) $parent_id) ?: null,
            'price'         => $effective,
            'regular_price' => ($regular !== null && $regular !== '') ? round((float) $regular, 4) : null,
            'on_sale'       => $on_sale ? 1 : 0,
            'currency'      => $currency,
            'observed_at'   => current_time('mysql', true), 
            'source'        => $source,
        ));
        self::bust_cache($product_id, $currency);
        return true;
    }

    
    public static function record_product($product, $source = 'price_change_hook') {
        if (!($product instanceof WC_Product)) { return false; }
        if ($product->is_type('grouped')) { return false; } 
        $eff = (float) $product->get_price(); 
        if ($eff <= 0) { return false; }
        $reg = ($product->get_regular_price() !== '') ? (float) $product->get_regular_price() : null;
        if ($reg === null && $product->is_type('variable') && method_exists($product, 'get_variation_regular_price')) {
            $vr  = (float) $product->get_variation_regular_price('min');
            $reg = $vr > 0 ? $vr : null;
        }
        
        
        
        return self::record($product->get_id(), $eff, $reg, $product->is_on_sale(), $source, $product->get_parent_id());
    }

    
    
    

    
    public static function lowest_30d($product_id, $currency = null, $asof_gmt = null) {
        $product_id = (int) $product_id;
        $currency   = $currency ?: self::default_currency();
        $asof       = $asof_gmt ?: current_time('mysql', true);
        $cacheable  = ($asof_gmt === null);

        $ck = 'low30_' . $product_id . '_' . $currency;
        if ($cacheable) {
            $hit = wp_cache_get($ck, self::CACHE_GROUP);
            if ($hit !== false) { return ($hit === 'null') ? null : (float) $hit; }
        }

        global $wpdb; $t = self::tbl();
        $window_start = gmdate('Y-m-d H:i:s', strtotime($asof . ' UTC') - self::WINDOW_DAYS * DAY_IN_SECONDS);
        
        $low = $wpdb->get_var($wpdb->prepare(
            "SELECT MIN(price) FROM (
                (SELECT price FROM {$t} WHERE product_id = %d AND currency = %s AND observed_at <= %s ORDER BY observed_at DESC, id DESC LIMIT 1)
                UNION ALL
                (SELECT price FROM {$t} WHERE product_id = %d AND currency = %s AND observed_at > %s AND observed_at <= %s)
            ) w",
            $product_id, $currency, $window_start,
            $product_id, $currency, $window_start, $asof
        ));

        $val = ($low === null) ? null : (float) $low;
        if ($cacheable) {
            wp_cache_set($ck, ($val === null) ? 'null' : $val, self::CACHE_GROUP, HOUR_IN_SECONDS);
        }
        return $val;
    }

    
    public static function is_reduction($product_id, $currency = null) {
        return self::reference($product_id, $currency) !== null;
    }

    
    public static function reference($product_id, $currency = null) {
        $currency = $currency ?: self::default_currency();
        $product  = wc_get_product((int) $product_id);
        if (!$product) { return null; }
        $current = (float) $product->get_price();
        if ($current <= 0) { return null; }

        $ref = self::lowest_30d($product_id, $currency);
        if ($ref === null || $current >= ($ref - 0.00005)) { return null; } 

        return array(
            'reference_price' => round($ref, 2),
            'current_price'   => round($current, 2),
            'discount_pct'    => (int) round(($ref - $current) / $ref * 100),
            'currency'        => $currency,
        );
    }

    
    public static function history($product_id, $currency = null, $from_gmt = null, $to_gmt = null) {
        global $wpdb; $t = self::tbl();
        $currency = $currency ?: self::default_currency();
        $where = "product_id = %d AND currency = %s";
        $args  = array((int) $product_id, $currency);
        if ($from_gmt) { $where .= " AND observed_at >= %s"; $args[] = $from_gmt; }
        if ($to_gmt)   { $where .= " AND observed_at <= %s"; $args[] = $to_gmt; }
        
        return $wpdb->get_results($wpdb->prepare(
            "SELECT observed_at, price, regular_price, on_sale, source FROM {$t} WHERE {$where} ORDER BY observed_at ASC, id ASC",
            $args
        ), ARRAY_A) ?: array();
    }

    public static function bust_cache($product_id, $currency = null) {
        $currency = $currency ?: self::default_currency();
        wp_cache_delete('low30_' . (int) $product_id . '_' . $currency, self::CACHE_GROUP);
    }

    
    public static function bust_all_cache() {
        if (function_exists('wp_cache_flush_group')) {
            wp_cache_flush_group(self::CACHE_GROUP);
        }
    }
}
