<?php

/**
 * DRBU_Shortcode — renderer buy box-a.
 *
 * Registruje isključivo prefiksovani shortcode [drbu_tiered_buy_box] (plugin
 * još nema objavljene korisnike sa starim generičkim tagovima, pa nema
 * backward-compat razloga da se oni zadrže — WordPress.org zahteva jedinstven
 * prefiks bez izuzetka).
 * HTML se iscrtava preko template-a (templates/tiered-buy-box.php) uz podršku
 * za override iz teme (woocommerce/tiered-buy-box.php).
 *
 * @package discount-rules-box-upsell
 */
defined( 'ABSPATH' ) || exit;
class DRBU_Shortcode {
    /**
     * Singleton instanca.
     *
     * @var DRBU_Shortcode|null
     */
    private static $instance = null;

    /**
     * ID-jevi proizvoda koji su već iscrtani na trenutnoj stranici
     * (sprečava dupliranje box-a kada su uključeni i shortcode i auto-insert).
     *
     * @var array
     */
    private $rendered = array();

    /**
     * Vraća jedinu instancu.
     *
     * @return DRBU_Shortcode
     */
    public static function instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Privatan konstruktor.
     */
    private function __construct() {
        add_shortcode( 'drbu_tiered_buy_box', array($this, 'shortcode') );
    }

    /**
     * Shortcode: [drbu_tiered_buy_box id="123"].
     *
     * @param array|string $atts Atributi.
     * @return string
     */
    public function shortcode( $atts ) {
        $atts = shortcode_atts( array(
            'id' => 0,
        ), $atts, 'drbu_tiered_buy_box' );
        $product_id = (int) $atts['id'];
        if ( empty( $product_id ) ) {
            $product_id = $this->current_product_id();
        }
        return $this->render( $product_id, array() );
    }

    /**
     * ID trenutnog proizvoda (ako smo na single product strani).
     *
     * @return int
     */
    private function current_product_id() {
        if ( function_exists( 'is_product' ) && is_product() ) {
            return (int) get_queried_object_id();
        }
        return 0;
    }

    /**
     * Proverava da li je box već iscrtan za dati proizvod na ovoj stranici.
     *
     * @param int $product_id ID proizvoda.
     * @return bool
     */
    public function is_rendered( $product_id ) {
        return isset( $this->rendered[$product_id] );
    }

    /**
     * Glavni renderer. Vraća HTML box-a ili prazan string.
     *
     * @param int   $product_id ID proizvoda.
     * @param array $overrides  Privremena podešavanja (backward-compat).
     * @return string
     */
    public function render( $product_id, array $overrides = array() ) {
        $product_id = (int) $product_id;
        if ( $product_id <= 0 || $this->is_rendered( $product_id ) ) {
            return '';
        }
        $product = wc_get_product( $product_id );
        if ( !$product || !$product->is_purchasable() || !$product->is_type( 'simple' ) ) {
            return '';
        }
        $settings = DRBU_Settings::instance();
        $all = $settings->all();
        if ( !empty( $overrides ) ) {
            // Duboko spajanje za ugnježdene nizove (numeric keys moraju ostati na svojim pozicijama).
            if ( isset( $overrides['drbu_tiers'] ) && is_array( $overrides['drbu_tiers'] ) ) {
                $all['drbu_tiers'] = array_replace( $all['drbu_tiers'], $overrides['drbu_tiers'] );
            }
            if ( isset( $overrides['drbu_strings'] ) && is_array( $overrides['drbu_strings'] ) ) {
                $all['drbu_strings'] = array_replace( $all['drbu_strings'], $overrides['drbu_strings'] );
            }
            foreach ( $overrides as $key => $value ) {
                if ( 'drbu_tiers' === $key || 'drbu_strings' === $key ) {
                    continue;
                }
                $all[$key] = $value;
            }
        }
        $this->rendered[$product_id] = true;
        $base = (float) $product->get_price();
        // 3-ći nivo je Pro funkcija — podrazumevano ostaje na 2; samo
        // drbu_fs()->is__premium_only() grana (izbačena iz Free ZIP-a od
        // strane Freemius Deployment-a) sme da pročita realnu vrednost.
        $tier_count = 2;
        if ( function_exists( 'drbu_fs' ) && drbu_fs() && drbu_fs()->is__premium_only() ) {
            $tier_count = $this->resolve_tier_count__premium_only( $all );
        }
        $tiers = ( is_array( $all['drbu_tiers'] ) ? $all['drbu_tiers'] : array() );
        $discount_type = $all['drbu_discount_type'];
        $strings = ( is_array( $all['drbu_strings'] ) ? $all['drbu_strings'] : array() );
        $engine = DRBU_Pricing_Engine::instance();
        $cart_url = wc_get_cart_url();
        $pricing_model = ( isset( $all['drbu_pricing_model'] ) ? $all['drbu_pricing_model'] : 'model_a' );
        $prices = array();
        $links = array();
        foreach ( array_slice(
            $tiers,
            0,
            $tier_count,
            true
        ) as $i => $tier ) {
            $qty = ( isset( $tier['qty'] ) ? max( 1, (int) $tier['qty'] ) : $i + 1 );
            $total = $engine->tier_total(
                $base,
                $qty,
                $tiers,
                $discount_type,
                $i,
                $pricing_model
            );
            $unit = $engine->unit_price(
                $base,
                $qty,
                $tiers,
                $discount_type,
                $i,
                $pricing_model
            );
            $save = $engine->savings(
                $base,
                $qty,
                $tiers,
                $discount_type,
                $i,
                $pricing_model
            );
            $prices[$i] = array(
                'qty'              => $qty,
                'total'            => $total,
                'unit'             => $unit,
                'save'             => $save,
                'total_html'       => $engine->format_price( $total, $all ),
                'unit_html'        => $engine->format_price( $unit, $all ),
                'save_html'        => $engine->format_price( $save, $all ),
                'was_html'         => $engine->format_price( $base * $qty, $all ),
                'base_html'        => $engine->format_price( $base, $all ),
                'discount_display' => ( 'model_c' === $pricing_model ? $engine->format_price( $total, $all ) : (( 'model_d' === $pricing_model ? sprintf( '%s / unit', $engine->format_price( $unit, $all ) ) : $engine->format_discount_value( ( isset( $tier['discount'] ) ? $tier['discount'] : 0 ), $discount_type, $all ) )) ),
            );
            $links[$i] = add_query_arg( array(
                'add-to-cart' => $product_id,
                'quantity'    => $qty,
                'drbu_pack'   => $i + 1,
                'drbu_pm'     => $pricing_model,
            ), $cart_url );
        }
        $threshold = (float) $all['drbu_free_ship_threshold'];
        $ship_free = ( isset( $strings['ship_free_text'] ) ? $strings['ship_free_text'] : '' );
        $ship_paid = ( isset( $strings['ship_paid_prefix'] ) ? $strings['ship_paid_prefix'] : '' );
        $ship_paid_text = sprintf( '%s %s', $ship_paid, wc_price( $threshold ) );
        foreach ( $prices as $i => &$price ) {
            $free = $threshold > 0 && $price['total'] >= $threshold;
            $price['ship_free'] = $free;
            $price['ship_text'] = ( $free ? $ship_free : $ship_paid_text );
            $price['ship_flag_text'] = ( isset( $strings['free_ship_flag'] ) ? $strings['free_ship_flag'] : '' );
        }
        unset($price);
        $best_index = max( 0, min( $tier_count - 1, (int) $all['drbu_best_value_index'] - 1 ) );
        $sfx = 'pgp' . $product_id . '_' . substr( uniqid(), -6 );
        $radio_ids = array();
        for ($i = 1; $i <= $tier_count; $i++) {
            $radio_ids[] = $sfx . '-' . $i;
        }
        $box = array(
            'product_id'    => $product_id,
            'product'       => $product,
            'base'          => $base,
            'settings'      => $all,
            'tiers'         => $tiers,
            'discount_type' => $discount_type,
            'strings'       => $strings,
            'prices'        => $prices,
            'links'         => $links,
            'sfx'           => $sfx,
            'radio_ids'     => $radio_ids,
            'best_index'    => $best_index,
            'tier_count'    => $tier_count,
            'enabled'       => array(
                'free_shipping' => 'yes' === ($all['drbu_enable_free_shipping'] ?? 'yes'),
                'footer_badges' => 'yes' === ($all['drbu_enable_footer_badges'] ?? 'yes'),
                'savings'       => 'yes' === ($all['drbu_enable_savings'] ?? 'yes'),
                'best_value'    => 'yes' === ($all['drbu_enable_best_value'] ?? 'yes'),
                'per_unit'      => 'yes' === ($all['drbu_enable_per_unit'] ?? 'yes'),
                'was_price'     => 'yes' === ($all['drbu_enable_was_price'] ?? 'yes'),
            ),
        );
        ob_start();
        wc_get_template(
            'tiered-buy-box.php',
            array(
                'box' => $box,
            ),
            'woocommerce',
            DRBU_PLUGIN_DIR . 'templates/'
        );
        return ob_get_clean();
    }

}
