<?php
/**
 * classes/Auction.php
 * Classe central do Leilão de Centavos
 */
class Auction extends DBConnection
{
    private $settings;

    public function __construct() {
        global $_settings;
        $this->settings = $_settings;
        parent::__construct();
    }

    // ─── Dar um lance ──────────────────────────────────────
    public function place_bid($auction_id, $customer_id) {
        $aid = (int) $auction_id;
        $cid = (int) $customer_id;

        require_once BASE_APP . 'includes/wallet-functions.php';

        $this->conn->begin_transaction();
        try {
            // 1. Trava o leilão para atualização atômica
            $auction = $this->conn->query(
                "SELECT * FROM auction_list WHERE id = $aid AND status = 2 FOR UPDATE"
            )->fetch_assoc();

            if (!$auction) throw new Exception('Leilão não está ativo.');

            // 2. Fase 2 real: verifica se timer zerou
            if ($auction['phase'] == 2 && $auction['timer_reset_at']) {
                $elapsed      = time() - strtotime($auction['timer_reset_at']);
                $seconds_left = $auction['timer_seconds'] - $elapsed;
                if ($seconds_left <= 0) {
                    // Encerra de verdade
                    $this->conn->query("UPDATE auction_list SET status=3,
                        winner_id={$auction['last_bidder_id']}
                        WHERE id=$aid");
                    $this->conn->commit();
                    throw new Exception('O leilão encerrou! Outro usuário venceu.');
                }
            }

            // 3. Verifica créditos disponíveis
            $credit_cost = (int) $auction['bid_credit_cost'];
            $credits_row = $this->conn->query(
                "SELECT credits FROM bid_credits WHERE customer_id = $cid FOR UPDATE"
            )->fetch_assoc();

            if (!$credits_row || (int)$credits_row['credits'] < $credit_cost) {
                $this->conn->rollback();
                return json_encode(['status' => 'no_credits',
                                    'msg'    => 'Créditos insuficientes. Compre mais créditos!']);
            }

            // 4. Deduz créditos
            $this->conn->query(
                "UPDATE bid_credits SET credits = credits - $credit_cost
                 WHERE customer_id = $cid"
            );

            // 5. Calcula novo preço e receita
            $new_price   = round((float)$auction['current_price'] + (float)$auction['bid_increment'], 2);
            $timer_from  = date('Y-m-d H:i:s');
            $bid_revenue = round($credit_cost * 0.49, 2); // Receita por lance

            // 6. Verifica se deve ativar Fase 2
            $new_total_revenue = (float)$auction['total_revenue'] + $bid_revenue;
            $new_phase = $auction['phase'];
            if ($auction['phase'] == 1 && $auction['phase2_trigger'] &&
                $new_total_revenue >= (float)$auction['phase2_trigger']) {
                $new_phase = 2;
            }

            // 7. Atualiza leilão
            $this->conn->query("UPDATE auction_list SET
                current_price  = $new_price,
                timer_reset_at = '$timer_from',
                last_bidder_id = $cid,
                total_bids     = total_bids + 1,
                total_revenue  = $new_total_revenue,
                phase          = $new_phase
                WHERE id = $aid");

            // 8. Registra o lance
            $this->conn->query("INSERT INTO auction_bids
                SET auction_id = $aid,
                    customer_id = $cid,
                    price_at_bid = $new_price,
                    is_simulated = 0");

            $this->conn->commit();

            // 9. Notificação WhatsApp quando está liderando
            if ($new_phase == 2) {
                // Avisa o anterior que perdeu a liderança
                if ($auction['last_bidder_id'] && $auction['last_bidder_id'] != $cid) {
                    enqueue_whatsapp($auction['last_bidder_id'], 'auction_leading',
                                     (int)$auction['timer_seconds']);
                }
            }

            return json_encode([
                'status'      => 'success',
                'new_price'   => 'R$ ' . number_format($new_price, 2, ',', '.'),
                'new_phase'   => $new_phase,
                'phase_changed' => ($new_phase != $auction['phase']),
                'credits_left'  => max(0, (int)$credits_row['credits'] - $credit_cost),
                'timer_reset'   => $timer_from,
                'timer_seconds' => (int)$auction['timer_seconds'],
            ]);

        } catch (Exception $e) {
            $this->conn->rollback();
            return json_encode(['status' => 'failed', 'msg' => $e->getMessage()]);
        }
    }

    // ─── Status em tempo real para AJAX ────────────────────
    public function get_status($auction_id) {
        $aid = (int) $auction_id;
        $a   = $this->conn->query(
            "SELECT a.*, c.firstname as last_bidder_name
             FROM auction_list a
             LEFT JOIN customer_list c ON a.last_bidder_id = c.id
             WHERE a.id = $aid"
        )->fetch_assoc();

        if (!$a) return json_encode(['error' => 'Not found']);

        $elapsed      = $a['timer_reset_at'] ? time() - strtotime($a['timer_reset_at']) : 0;
        $seconds_left = ($a['phase'] == 2) ? max(0, (int)$a['timer_seconds'] - $elapsed)
                                            : (int)$a['timer_seconds'];

        // Encerrar automaticamente se timer zerou na Fase 2
        if ($a['phase'] == 2 && $seconds_left <= 0 && $a['status'] == 2) {
            $this->conn->query("UPDATE auction_list SET status=3,
                winner_id={$a['last_bidder_id']}
                WHERE id=$aid AND status=2");
            $a['status'] = 3;

            // Notifica vencedor
            if ($a['last_bidder_id']) {
                enqueue_whatsapp($a['last_bidder_id'], 'auction_won', $a['current_price']);
            }
        }

        // Últimos 10 lances
        $bids_q = $this->conn->query(
            "SELECT b.price_at_bid, b.created_at, b.is_simulated, c.firstname
             FROM auction_bids b
             LEFT JOIN customer_list c ON b.customer_id = c.id
             WHERE b.auction_id = $aid
             ORDER BY b.created_at DESC LIMIT 10"
        );
        $bids = [];
        while ($r = $bids_q->fetch_assoc()) {
            $bids[] = [
                'name'  => $r['is_simulated']
                           ? $this->random_fake_name()
                           : ($r['firstname'] ? $r['firstname'][0] . '***' : 'Anônimo'),
                'price' => 'R$ ' . number_format($r['price_at_bid'], 2, ',', '.'),
                'time'  => date('H:i:s', strtotime($r['created_at'])),
                'fake'  => (bool)$r['is_simulated'],
            ];
        }

        return json_encode([
            'current_price'    => number_format($a['current_price'], 2, ',', '.'),
            'current_price_fmt'=> 'R$ ' . number_format($a['current_price'], 2, ',', '.'),
            'seconds_left'     => $seconds_left,
            'phase'            => (int)$a['phase'],
            'status'           => (int)$a['status'],
            'total_bids'       => number_format($a['total_bids']),
            'last_bidder_name' => $a['last_bidder_name'] ? $a['last_bidder_name'][0] . '***' : '-',
            'total_revenue'    => 'R$ ' . number_format($a['total_revenue'], 2, ',', '.'),
            'recent_bids'      => $bids,
        ]);
    }

    // ─── Lance simulado (prova social — Fase 1) ────────────
    public function simulate_bid($auction_id) {
        $aid = (int) $auction_id;
        $a   = $this->conn->query(
            "SELECT * FROM auction_list WHERE id = $aid AND status=2 AND phase=1"
        )->fetch_assoc();
        if (!$a) return;

        $new_price  = round((float)$a['current_price'] + (float)$a['bid_increment'], 2);
        $timer_from = date('Y-m-d H:i:s');

        $this->conn->query("UPDATE auction_list SET
            current_price  = $new_price,
            timer_reset_at = '$timer_from',
            total_bids     = total_bids + 1,
            total_revenue  = total_revenue + 0.49
            WHERE id = $aid");

        $this->conn->query("INSERT INTO auction_bids
            SET auction_id=$aid, customer_id=NULL, price_at_bid=$new_price, is_simulated=1");
    }

    private function random_fake_name() {
        $r = $this->conn->query(
            "SELECT name FROM social_proof_names ORDER BY RAND() LIMIT 1"
        )->fetch_assoc();
        return $r ? $r['name'] : 'Usuário ***';
    }

    // ─── CRUD Admin ─────────────────────────────────────────
    public function save_auction() {
        $id          = (int)($_POST['id'] ?? 0);
        $name        = $this->conn->real_escape_string($_POST['name']);
        $description = $this->conn->real_escape_string($_POST['description'] ?? '');
        $real_value  = (float) str_replace(['.', ','], ['', '.'], $_POST['real_value']);
        $start_price = (float) str_replace(['.', ','], ['', '.'], ($_POST['start_price'] ?? '0.01'));
        $bid_incr    = (float) str_replace(['.', ','], ['', '.'], ($_POST['bid_increment'] ?? '0.01'));
        $bid_cost    = (int)($_POST['bid_credit_cost'] ?? 1);
        $timer       = (int)($_POST['timer_seconds'] ?? 30);
        $phase2_trig = (float) str_replace(['.', ','], ['', '.'], ($_POST['phase2_trigger'] ?? '0'));
        $status      = (int)($_POST['status'] ?? 1);
        $featured    = isset($_POST['featured']) ? 1 : 0;
        $slug        = slugify($name);

        if (empty($id)) {
            $sql = "INSERT INTO auction_list SET
                name='$name', description='$description', real_value=$real_value,
                start_price=$start_price, current_price=$start_price,
                bid_increment=$bid_incr, bid_credit_cost=$bid_cost,
                timer_seconds=$timer, phase2_trigger=" . ($phase2_trig > 0 ? $phase2_trig : 'NULL') . ",
                status=$status, featured=$featured, slug='$slug'";
        } else {
            $sql = "UPDATE auction_list SET
                name='$name', description='$description', real_value=$real_value,
                bid_increment=$bid_incr, bid_credit_cost=$bid_cost,
                timer_seconds=$timer, phase2_trigger=" . ($phase2_trig > 0 ? $phase2_trig : 'NULL') . ",
                status=$status, featured=$featured
                WHERE id=$id";
        }

        $save = $this->conn->query($sql);

        if ($save) {
            $pid = $id ?: $this->conn->insert_id;

            // Upload da imagem
            if (!empty($_FILES['img']['tmp_name'])) {
                $img_path = 'uploads/leiloes';
                if (!is_dir(BASE_APP . $img_path)) mkdir(BASE_APP . $img_path, 0755, true);
                $accept = ['image/jpeg', 'image/png', 'image/webp'];
                if (in_array($_FILES['img']['type'], $accept)) {
                    $ext   = pathinfo($_FILES['img']['name'], PATHINFO_EXTENSION);
                    $spath = $img_path . '/leilao_' . $pid . '.' . $ext;
                    move_uploaded_file($_FILES['img']['tmp_name'], BASE_APP . $spath);
                    $ts = time();
                    $this->conn->query("UPDATE auction_list SET image_path='$spath?v=$ts' WHERE id=$pid");
                }
            }

            $resp = ['status' => 'success', 'pid' => $pid, 'msg' => 'Leilão salvo com sucesso!'];
        } else {
            $resp = ['status' => 'failed', 'msg' => $this->conn->error];
        }
        return json_encode($resp);
    }
}

// ─── Roteador de ações ──────────────────────────────────────
require_once '../settings.php';
$auction = new Auction();
$action  = strtolower($_GET['f'] ?? '');

switch ($action) {
    case 'place_bid':
        header('Content-Type: application/json');
        $cid = (int)($_settings->userdata('id') ?? 0);
        if (!$cid) { echo json_encode(['status'=>'failed','msg'=>'Faça login para dar lance.']); exit(); }
        echo $auction->place_bid((int)($_POST['auction_id'] ?? 0), $cid);
        break;

    case 'get_status':
        header('Content-Type: application/json');
        echo $auction->get_status((int)($_GET['id'] ?? 0));
        break;

    case 'simulate_bid':
        // Chamado pelo cron para prova social
        $secret = $_GET['secret'] ?? '';
        if ($secret === $_settings->info('cron_secret')) {
            $auction->simulate_bid((int)($_GET['id'] ?? 0));
            echo 'ok';
        }
        break;

    case 'save':
        echo $auction->save_auction();
        break;

    default:
        break;
}
