<?php
/**
 * DZQCOD SalesBoost — Upsell, Order Bump, Abandoned Cart, Loyalty, Referral
 */
namespace DZQCOD;
defined('ABSPATH') || exit;

class SalesBoost {
    public function __construct() {
        // Upsell / Cross-sell in form
        add_action('wp_ajax_dzqcod_get_upsells', [$this, 'get_upsells']);
        add_action('wp_ajax_nopriv_dzqcod_get_upsells', [$this, 'get_upsells']);
        add_action('wp_ajax_dzqcod_save_upsell_config', [$this, 'save_upsell_config']);
        // Abandoned cart
        add_action('wp_ajax_dzqcod_track_abandoned', [$this, 'track_abandoned']);
        add_action('wp_ajax_nopriv_dzqcod_track_abandoned', [$this, 'track_abandoned']);
        add_action('dzqcod_cron_abandoned', [$this, 'process_abandoned_carts']);
        if (!wp_next_scheduled('dzqcod_cron_abandoned')) wp_schedule_event(time(), 'hourly', 'dzqcod_cron_abandoned');
        // Loyalty
        add_action('woocommerce_order_status_changed', [$this, 'loyalty_on_delivered'], 10, 4);
        add_action('wp_ajax_dzqcod_loyalty_check', [$this, 'loyalty_check']);
        add_action('wp_ajax_nopriv_dzqcod_loyalty_check', [$this, 'loyalty_check']);
        add_action('wp_ajax_dzqcod_save_loyalty_config', [$this, 'save_loyalty_config']);
        // Referral
        add_action('init', [$this, 'track_referral_visit']);
        add_action('dzqcod_order_created', [$this, 'referral_on_order'], 20, 2);
        add_action('wp_ajax_dzqcod_get_referral_link', [$this, 'get_referral_link']);
        add_action('wp_ajax_dzqcod_save_referral_config', [$this, 'save_referral_config']);
        // Order Bump
        add_action('wp_ajax_dzqcod_order_bump_products', [$this, 'order_bump_products']);
        add_action('wp_ajax_nopriv_dzqcod_order_bump_products', [$this, 'order_bump_products']);
        add_action('wp_ajax_dzqcod_save_order_bump', [$this, 'save_order_bump']);
    }

    // ═══════════════════════════════════════════════
    //  UPSELL / CROSS-SELL / ORDER BUMP
    // ═══════════════════════════════════════════════
    public function get_upsells(): void {
        $pid = absint($_POST['product_id'] ?? 0);
        $product = wc_get_product($pid);
        if (!$product) wp_send_json_error();

        $upsells = [];
        // 1. Manual upsells from WooCommerce
        foreach ($product->get_upsell_ids() as $uid) {
            $up = wc_get_product($uid);
            if ($up && $up->is_in_stock()) {
                $upsells[] = ['id' => $uid, 'name' => $up->get_name(), 'price' => (float)$up->get_price(),
                    'image' => wp_get_attachment_url($up->get_image_id()) ?: '', 'type' => 'upsell'];
            }
        }
        // 2. Cross-sells
        foreach ($product->get_cross_sell_ids() as $cid) {
            $cp = wc_get_product($cid);
            if ($cp && $cp->is_in_stock()) {
                $upsells[] = ['id' => $cid, 'name' => $cp->get_name(), 'price' => (float)$cp->get_price(),
                    'image' => wp_get_attachment_url($cp->get_image_id()) ?: '', 'type' => 'cross'];
            }
        }
        // 3. Auto order bump: same category, cheaper
        if (empty($upsells)) {
            $cats = wp_get_post_terms($pid, 'product_cat', ['fields' => 'ids']);
            if ($cats) {
                $bumps = wc_get_products(['category' => [get_term($cats[0])->slug], 'exclude' => [$pid],
                    'limit' => 3, 'orderby' => 'rand', 'status' => 'publish', 'stock_status' => 'instock']);
                foreach ($bumps as $bp) {
                    $upsells[] = ['id' => $bp->get_id(), 'name' => $bp->get_name(), 'price' => (float)$bp->get_price(),
                        'image' => wp_get_attachment_url($bp->get_image_id()) ?: '', 'type' => 'bump'];
                }
            }
        }
        // Apply bump discount
        $bump_discount = (float)Core::opt('bump_discount', '10');
        foreach ($upsells as &$u) {
            if ($u['type'] === 'bump') {
                $u['bump_price'] = round($u['price'] * (1 - $bump_discount / 100));
                $u['discount'] = $bump_discount;
            }
        }
        wp_send_json_success(['items' => array_slice($upsells, 0, 3)]);
    }

    public function save_upsell_config(): void {
        check_ajax_referer('dzqcod_admin', 'nonce');
        if(!current_user_can('manage_woocommerce'))wp_send_json_error();
        foreach (['bump_discount', 'upsell_title', 'bump_title', 'upsell_enabled'] as $k)
            if (isset($_POST[$k])) update_option('dzqcod_' . $k, sanitize_text_field($_POST[$k]), false);
        wp_send_json_success(['message' => 'تم الحفظ']);
    }

    // ═══════════════════════════════════════════════
    //  ABANDONED CART RECOVERY
    // ═══════════════════════════════════════════════
    public function track_abandoned(): void {
        $phone = sanitize_text_field($_POST['phone'] ?? '');
        $name = sanitize_text_field($_POST['name'] ?? '');
        $pid = absint($_POST['product_id'] ?? 0);
        if (!$phone || !$pid) wp_send_json_error();

        global $wpdb;
        $t = $wpdb->prefix . \DZQCOD_DB . 'abandoned_carts';
        // Check if table exists, create if not
        $wpdb->query("CREATE TABLE IF NOT EXISTS {$t} (
            id BIGINT AUTO_INCREMENT PRIMARY KEY, phone VARCHAR(20), name VARCHAR(100),
            product_id BIGINT, product_name VARCHAR(255), price DECIMAL(10,2),
            wilaya VARCHAR(50), recovery_status ENUM('pending','sent','recovered','expired') DEFAULT 'pending',
            attempt INT DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            recovered_at DATETIME NULL, INDEX(phone), INDEX(recovery_status)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

        $product = wc_get_product($pid);
        // Don't track if already ordered recently
        $exists = $wpdb->get_var($wpdb->prepare("SELECT id FROM {$t} WHERE phone=%s AND product_id=%d AND created_at>DATE_SUB(NOW(),INTERVAL 1 HOUR)", $phone, $pid));
        if ($exists) { wp_send_json_success(); return; }

        $wpdb->insert($t, [
            'phone' => $phone, 'name' => $name, 'product_id' => $pid,
            'product_name' => $product ? $product->get_name() : '', 'price' => $product ? $product->get_price() : 0,
            'wilaya' => sanitize_text_field($_POST['wilaya'] ?? ''),
        ]);
        wp_send_json_success();
    }

    public function process_abandoned_carts(): void {
        if (Core::opt('abandoned_enabled', '') !== 'yes') return;
        global $wpdb;
        $t = $wpdb->prefix . \DZQCOD_DB . 'abandoned_carts';
        if (!$wpdb->get_var("SHOW TABLES LIKE '{$t}'")) return;

        // Get carts abandoned 1h+ ago, not yet sent, max 3 attempts
        $delays = [1, 24, 72]; // hours
        $carts = $wpdb->get_results("SELECT * FROM {$t} WHERE recovery_status='pending' AND attempt<3 ORDER BY created_at ASC LIMIT 50");

        foreach ($carts as $cart) {
            $hours_ago = (time() - strtotime($cart->created_at)) / 3600;
            $required_delay = $delays[$cart->attempt] ?? 1;
            if ($hours_ago < $required_delay) continue;

            // Check if they already ordered
            $ordered = wc_get_orders(['billing_phone' => $cart->phone, 'date_created' => '>' . $cart->created_at, 'limit' => 1]);
            if (!empty($ordered)) {
                $wpdb->update($t, ['recovery_status' => 'recovered', 'recovered_at' => current_time('mysql')], ['id' => $cart->id]);
                continue;
            }

            $templates = [
                Core::opt('abandoned_tpl_1', '👋 {name}، لاحظنا أنك لم تكمل طلبك لـ {product}. أكمل طلبك الآن! {link}'),
                Core::opt('abandoned_tpl_2', '🔥 {name}، {product} لا يزال متاحاً! لا تفوّت الفرصة. {link}'),
                Core::opt('abandoned_tpl_3', '⏰ آخر فرصة {name}! {product} بسعر {price} دج فقط. اطلب الآن: {link}'),
            ];

            $tpl = $templates[$cart->attempt] ?? $templates[0];
            $product = wc_get_product($cart->product_id);
            $link = $product ? get_permalink($cart->product_id) : home_url();
            $msg = str_replace(['{name}', '{product}', '{price}', '{link}'],
                [$cart->name ?: 'عزيزي العميل', $cart->product_name, number_format((float)$cart->price, 0), $link], $tpl);

            // Send via WhatsApp API
            $phone = preg_replace('/^0/', '213', $cart->phone);
            $api = Core::opt('wa_api_url', '');
            $token = Core::opt('wa_api_token', '');
            if ($api && $token) {
                wp_remote_post($api, ['headers' => ['Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json'],
                    'body' => wp_json_encode(['phone' => $phone, 'message' => $msg]), 'timeout' => 10]);
            }

            $wpdb->update($t, ['attempt' => $cart->attempt + 1, 'recovery_status' => $cart->attempt >= 2 ? 'expired' : 'pending'], ['id' => $cart->id]);

            // Log
            $wpdb->insert($wpdb->prefix . \DZQCOD_DB . 'message_logs', ['order_id' => 0, 'channel' => 'whatsapp', 'phone' => $phone,
                'body' => $msg, 'status' => ($api && $token) ? 'sent' : 'logged', 'template' => 'abandoned_' . ($cart->attempt + 1)]);
        }
    }

    // ═══════════════════════════════════════════════
    //  LOYALTY POINTS
    // ═══════════════════════════════════════════════
    public function loyalty_on_delivered(int $oid, string $from, string $to, $order): void {
        if ($to !== 'wc-delivered') return;
        if (Core::opt('loyalty_enabled', '') !== 'yes') return;

        $phone = $order->get_billing_phone();
        if (!$phone) return;

        $points_per_1000 = (int)Core::opt('loyalty_points_per_1000', '10');
        $earned = max(1, floor((float)$order->get_total() / 1000) * $points_per_1000);

        global $wpdb;
        $t = $wpdb->prefix . \DZQCOD_DB . 'loyalty';
        $wpdb->query("CREATE TABLE IF NOT EXISTS {$t} (
            id BIGINT AUTO_INCREMENT PRIMARY KEY, phone VARCHAR(20) UNIQUE, name VARCHAR(100),
            points INT DEFAULT 0, total_earned INT DEFAULT 0, total_redeemed INT DEFAULT 0,
            orders_count INT DEFAULT 0, tier ENUM('bronze','silver','gold','vip') DEFAULT 'bronze',
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            INDEX(phone), INDEX(tier)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

        $exists = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$t} WHERE phone=%s", $phone));
        if ($exists) {
            $new_points = $exists->points + $earned;
            $new_total = $exists->total_earned + $earned;
            $new_orders = $exists->orders_count + 1;
            $tier = $new_orders >= 20 ? 'vip' : ($new_orders >= 10 ? 'gold' : ($new_orders >= 5 ? 'silver' : 'bronze'));
            $wpdb->update($t, ['points' => $new_points, 'total_earned' => $new_total, 'orders_count' => $new_orders,
                'name' => $order->get_billing_first_name(), 'tier' => $tier], ['phone' => $phone]);
        } else {
            $wpdb->insert($t, ['phone' => $phone, 'name' => $order->get_billing_first_name(),
                'points' => $earned, 'total_earned' => $earned, 'orders_count' => 1, 'tier' => 'bronze']);
        }
        $order->add_order_note(sprintf('🏆 +%d نقطة ولاء (المجموع: %d)', $earned, ($exists ? $exists->points : 0) + $earned));
    }

    public function loyalty_check(): void {
        $phone = sanitize_text_field($_POST['phone'] ?? '');
        if (!$phone) wp_send_json_error();
        global $wpdb;
        $t = $wpdb->prefix . \DZQCOD_DB . 'loyalty';
        $row = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$t} WHERE phone=%s", $phone));
        if (!$row) wp_send_json_success(['found' => false]);

        $tiers = ['bronze' => '🥉', 'silver' => '🥈', 'gold' => '🥇', 'vip' => '💎'];
        $redeem_rate = (int)Core::opt('loyalty_redeem_rate', '100'); // 100 points = 100 DZD
        wp_send_json_success(['found' => true, 'points' => (int)$row->points, 'tier' => $row->tier,
            'tier_icon' => $tiers[$row->tier] ?? '🥉', 'orders' => (int)$row->orders_count,
            'discount_available' => floor($row->points / $redeem_rate) * $redeem_rate]);
    }

    public function save_loyalty_config(): void {
        check_ajax_referer('dzqcod_admin', 'nonce');
        if(!current_user_can('manage_woocommerce'))wp_send_json_error();
        foreach (['loyalty_enabled', 'loyalty_points_per_1000', 'loyalty_redeem_rate'] as $k)
            if (isset($_POST[$k])) update_option('dzqcod_' . $k, sanitize_text_field($_POST[$k]), false);
        wp_send_json_success();
    }

    // ═══════════════════════════════════════════════
    //  REFERRAL SYSTEM
    // ═══════════════════════════════════════════════
    public function track_referral_visit(): void {
        if (!isset($_GET['ref'])) return;
        $ref = sanitize_text_field($_GET['ref']);
        if (!$ref) return;
        setcookie('dzqcod_ref', $ref, time() + (30 * 86400), '/');
    }

    public function referral_on_order(int $oid, $order): void {
        if (Core::opt('referral_enabled', '') !== 'yes') return;
        $ref = $_COOKIE['dzqcod_ref'] ?? '';
        if (!$ref) return;

        global $wpdb;
        $t = $wpdb->prefix . \DZQCOD_DB . 'referrals';
        $wpdb->query("CREATE TABLE IF NOT EXISTS {$t} (
            id BIGINT AUTO_INCREMENT PRIMARY KEY, referrer_phone VARCHAR(20), referee_phone VARCHAR(20),
            order_id BIGINT, order_total DECIMAL(10,2), commission DECIMAL(10,2) DEFAULT 0,
            status ENUM('pending','approved','paid') DEFAULT 'pending',
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX(referrer_phone)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

        $referee_phone = $order->get_billing_phone();
        if ($ref === $referee_phone) return; // No self-referral

        $commission_pct = (float)Core::opt('referral_commission', '5');
        $commission = round((float)$order->get_total() * $commission_pct / 100);

        $wpdb->insert($t, ['referrer_phone' => $ref, 'referee_phone' => $referee_phone,
            'order_id' => $oid, 'order_total' => $order->get_total(), 'commission' => $commission]);

        $order->add_order_note(sprintf('🤝 طلب عبر إحالة من %s — عمولة: %s دج', substr($ref, 0, 4) . '****', number_format($commission, 0)));

        // Add points to referrer loyalty
        if (Core::opt('loyalty_enabled', '') === 'yes') {
            $bonus = (int)Core::opt('referral_loyalty_bonus', '50');
            $lt = $wpdb->prefix . \DZQCOD_DB . 'loyalty';
            $wpdb->query($wpdb->prepare("UPDATE {$lt} SET points=points+%d, total_earned=total_earned+%d WHERE phone=%s", $bonus, $bonus, $ref));
        }
    }

    public function get_referral_link(): void {
        $phone = sanitize_text_field($_POST['phone'] ?? '');
        if (!$phone) wp_send_json_error();
        $link = add_query_arg('ref', $phone, home_url());

        global $wpdb;
        $t = $wpdb->prefix . \DZQCOD_DB . 'referrals';
        $stats = $wpdb->get_row($wpdb->prepare("SELECT COUNT(*) as total, SUM(commission) as earned FROM {$t} WHERE referrer_phone=%s", $phone));

        wp_send_json_success(['link' => $link, 'referrals' => (int)($stats->total ?? 0), 'earned' => (float)($stats->earned ?? 0)]);
    }

    public function save_referral_config(): void {
        check_ajax_referer('dzqcod_admin', 'nonce');
        if(!current_user_can('manage_woocommerce'))wp_send_json_error();
        foreach (['referral_enabled', 'referral_commission', 'referral_loyalty_bonus'] as $k)
            if (isset($_POST[$k])) update_option('dzqcod_' . $k, sanitize_text_field($_POST[$k]), false);
        wp_send_json_success();
    }

    // ═══════════════════════════════════════════════
    //  ORDER BUMP — Add extra product at checkout
    // ═══════════════════════════════════════════════
    public function order_bump_products(): void {
        check_ajax_referer('dzqcod_admin','nonce');if(!current_user_can('manage_woocommerce'))wp_send_json_error();
        $pid = absint($_POST['product_id'] ?? 0);
        if (!$pid) wp_send_json_error();

        // Get configured bump products or auto-detect
        $bump_ids = get_post_meta($pid, '_dzqcod_bump_products', true);
        $bumps = [];

        if ($bump_ids && is_array($bump_ids)) {
            foreach ($bump_ids as $bid) {
                $bp = wc_get_product($bid);
                if ($bp && $bp->is_in_stock()) {
                    $bumps[] = ['id' => $bid, 'name' => $bp->get_name(), 'price' => (float)$bp->get_price(),
                        'image' => wp_get_attachment_url($bp->get_image_id()) ?: '', 'type' => 'bump',
                        'discount' => (float)get_post_meta($bid, '_dzqcod_bump_discount', true)];
                }
            }
        }

        // Auto-detect: cheap accessories from same category
        if (empty($bumps)) {
            $main = wc_get_product($pid);
            if ($main) {
                $cats = wp_get_post_terms($pid, 'product_cat', ['fields' => 'ids']);
                $max_price = (float)$main->get_price() * 0.4; // Bump should be ≤40% of main
                if (!empty($cats)) {
                    $auto = wc_get_products(['category' => [get_term($cats[0])->slug], 'exclude' => [$pid],
                        'limit' => 3, 'orderby' => 'price', 'order' => 'ASC', 'stock_status' => 'instock',
                        'price' => '0..' . $max_price]);
                    foreach ($auto as $bp) {
                        $bumps[] = ['id' => $bp->get_id(), 'name' => $bp->get_name(), 'price' => (float)$bp->get_price(),
                            'image' => wp_get_attachment_url($bp->get_image_id()) ?: '', 'type' => 'auto_bump', 'discount' => 0];
                    }
                }
            }
        }

        wp_send_json_success(['bumps' => $bumps]);
    }

    public function save_order_bump(): void {
        check_ajax_referer('dzqcod_admin', 'nonce');
        if(!current_user_can('manage_woocommerce'))wp_send_json_error();
        $pid = absint($_POST['product_id'] ?? 0);
        $bump_ids = array_map('absint', (array)($_POST['bump_ids'] ?? []));
        if ($pid) update_post_meta($pid, '_dzqcod_bump_products', $bump_ids);
        wp_send_json_success(['message' => 'تم حفظ Order Bump']);
    }

    // HTML for order bump in form (called from Core render)
    public static function render_bump_html(): string {
        return '<div id="dzqcod-bump-container" style="display:none;margin:10px 0;border:2px dashed #667eea;border-radius:12px;padding:12px;background:#f8f7ff">
<div style="font-weight:700;font-size:14px;margin-bottom:8px;color:#667eea">🎁 أضف لطلبك بسعر خاص!</div>
<div id="dzqcod-bump-items"></div></div>
<script>
(function(){
    var pid=document.querySelector("[name=product_id]");
    if(!pid)return;
    fetch(dza_front.ajax+"?action=dzqcod_order_bump_products&product_id="+pid.value)
    .then(r=>r.json()).then(function(r){
        if(!r.success||!r.data.bumps.length)return;
        var c=document.getElementById("dzqcod-bump-container"),items=document.getElementById("dzqcod-bump-items");
        c.style.display="block";
        r.data.bumps.forEach(function(b){
            var d=document.createElement("label");
            d.style.cssText="display:flex;align-items:center;gap:8px;padding:6px;cursor:pointer;border-radius:8px;margin-bottom:4px;background:#fff";
            d.innerHTML=\'<input type="checkbox" name="dzqcod_bumps[]" value="\'+b.id+\'" style="width:18px;height:18px">\'
                +(b.image?\'<img src="\'+b.image+\'" style="width:40px;height:40px;border-radius:6px;object-fit:cover">\':\'<span style="width:40px;height:40px;background:#eee;border-radius:6px;display:flex;align-items:center;justify-content:center">🎁</span>\')
                +\'<div><div style="font-weight:600;font-size:12px">\'+b.name+\'</div><div style="color:#667eea;font-weight:700">\'+b.price.toLocaleString()+\' دج</div></div>\';
            items.appendChild(d);
        });
    });
})();
</script>';
    }
}
