<?php
require_once __DIR__ . '/../../includes/auth.php';
require_once __DIR__ . '/../../includes/square.php';

header('Content-Type: application/json');

if (!isLoggedIn()) { echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
if ($_SERVER['REQUEST_METHOD'] !== 'POST') { echo json_encode(['success'=>false,'error'=>'Method not allowed']); exit; }

$data       = json_decode(file_get_contents('php://input'), true);
$sourceId   = trim($data['source_id']   ?? '');
$tokens     = (int)($data['tokens']     ?? 0);
$priceCents = (int)($data['price_cents'] ?? 0);
$method     = trim($data['method']      ?? 'card');
$platformId = trim($data['platform_id'] ?? '');
$gameAlias  = trim($data['game_alias']  ?? '');
$playerName = trim($data['player_name'] ?? '');
$isCustom   = (bool)($data['is_custom'] ?? false);
$billing    = $data['billing'] ?? [];
$userId     = $_SESSION['user_id'];

// ─── Validate ─────────────────────────────────────────────
if ($tokens < 1 || $priceCents < 100) {
    echo json_encode(['success'=>false,'error'=>'Minimum purchase is $1 (1 token).']); exit;
}

// Validate preset packages (custom bypasses preset check)
if (!$isCustom) {
    $packages = json_decode(TOKEN_PACKAGES, true);
    $validPkg = false;
    foreach ($packages as $pkg) {
        if ($pkg['tokens'] === $tokens && ($pkg['price'] * 100) === $priceCents) { $validPkg = true; break; }
    }
    if (!$validPkg) {
        echo json_encode(['success'=>false,'error'=>'Invalid token package.']); exit;
    }
} else {
    // Custom: tokens must equal dollars (1:1 ratio), cap at $500
    if ($tokens !== ($priceCents / 100) || $tokens > 500) {
        echo json_encode(['success'=>false,'error'=>'Invalid custom amount.']); exit;
    }
}

// Sanitize billing fields
$billingFirst   = substr(trim($billing['first_name'] ?? ''), 0, 80);
$billingLast    = substr(trim($billing['last_name']  ?? ''), 0, 80);
$billingAddress = substr(trim($billing['address']    ?? ''), 0, 200);
$billingCity    = substr(trim($billing['city']       ?? ''), 0, 80);
$billingState   = strtoupper(substr(trim($billing['state'] ?? ''), 0, 2));
$billingZip     = substr(trim($billing['zip']        ?? ''), 0, 10);
$billingEmail   = substr(strtolower(trim($billing['email'] ?? '')), 0, 150);
$cardholderName = trim("$billingFirst $billingLast");

$isManual = in_array($method, ['venmo','chime','cashapp','zelle']);

// ─── Manual payment ────────────────────────────────────────
if ($isManual) {
    $stmt = db()->prepare("
        INSERT INTO token_purchases
            (user_id, tokens, amount_cents, payment_method, platform_id, game_alias,
             player_name, billing_name, billing_email, is_custom, status)
        VALUES (?,?,?,?,?,?,?,?,?,?,'pending')
    ");
    $stmt->execute([
        $userId, $tokens, $priceCents, $method, $platformId, $gameAlias,
        $playerName, $cardholderName, $billingEmail, $isCustom ? 1 : 0
    ]);
    $pid = db()->lastInsertId();
    logActivity('manual_payment_pending', $userId, null, 'purchase', 0, "Manual payment pending: {$method} \$" . number_format($priceCents / 100, 2));
echo json_encode(['success'=>true,'manual'=>true,'purchase_id'=>$pid,
        'message'=>"Request #{$pid} submitted! Tokens credited after payment verification."]);
    exit;
}

// ─── Card payment via Square ───────────────────────────────
if (empty($sourceId)) { echo json_encode(['success'=>false,'error'=>'Card payment token required.']); exit; }

$square = new SquarePayment();
$note   = "TomGames {$tokens}tok | {$platformId} | {$gameAlias} | user#{$userId}" . ($isCustom ? ' [CUSTOM]' : '');

// Build buyer info for Square
$buyerInfo = [];
if ($cardholderName) $buyerInfo['buyer_email_address'] = $billingEmail ?: null;
$billingAddr = [];
if ($billingAddress) $billingAddr['address_line_1'] = $billingAddress;
if ($billingCity)    $billingAddr['locality']        = $billingCity;
if ($billingState)   $billingAddr['administrative_district_level_1'] = $billingState;
if ($billingZip)     $billingAddr['postal_code']     = $billingZip;
$billingAddr['country'] = 'US';

$result = $square->charge($sourceId, $priceCents, $note, $cardholderName, $billingAddr, $billingEmail);

if (!$result['success']) {
    // Log failed attempt
    db()->prepare("INSERT INTO token_purchases (user_id,tokens,amount_cents,payment_method,platform_id,game_alias,player_name,billing_name,billing_email,is_custom,status,failure_reason) VALUES (?,?,?,'card',?,?,?,?,?,?,'failed',?)")
       ->execute([$userId,$tokens,$priceCents,$platformId,$gameAlias,$playerName,$cardholderName,$billingEmail,$isCustom?1:0,$result['error']]);
    echo json_encode(['success'=>false,'error'=>$result['error']]); exit;
}

// ─── Credit tokens ─────────────────────────────────────────
db()->beginTransaction();
try {
    db()->prepare("UPDATE users SET tokens=tokens+? WHERE id=?")->execute([$tokens,$userId]);
    $cardBrand = $result['card_brand'] ?? null;
    $cardLast4 = $result['last_4']     ?? null;
    $receiptUrl= $result['receipt_url'] ?? null;

    db()->prepare("
        INSERT INTO token_purchases
            (user_id, tokens, amount_cents, payment_method, square_payment_id,
             platform_id, game_alias, player_name, billing_name, billing_address,
             billing_city, billing_state, billing_zip, billing_email,
             is_custom, card_brand, card_last4, receipt_url, status)
        VALUES (?,?,?,'card',?,?,?,?,?,?,?,?,?,?,?,?,?,?,'completed')
    ")->execute([
        $userId, $tokens, $priceCents, $result['payment_id'],
        $platformId, $gameAlias, $playerName,
        $cardholderName, $billingAddress, $billingCity, $billingState, $billingZip, $billingEmail,
        $isCustom ? 1 : 0, $cardBrand, $cardLast4, $receiptUrl
    ]);

    db()->commit();
} catch (Exception $e) {
    db()->rollBack();
    echo json_encode(['success'=>false,'error'=>'Token credit failed. Payment ID: '.$result['payment_id']]); exit;
}

// ─── Update saved billing (separate try — must NOT roll back token credit) ──
try {
    db()->prepare("
        INSERT INTO saved_billing (user_id,first_name,last_name,email,address,city,state,zip,card_brand,card_last4)
        VALUES (?,?,?,?,?,?,?,?,?,?)
        ON DUPLICATE KEY UPDATE
            card_brand=VALUES(card_brand), card_last4=VALUES(card_last4),
            first_name=COALESCE(NULLIF(VALUES(first_name),''),first_name),
            last_name=COALESCE(NULLIF(VALUES(last_name),''),last_name),
            email=COALESCE(NULLIF(VALUES(email),''),email),
            address=COALESCE(NULLIF(VALUES(address),''),address),
            city=COALESCE(NULLIF(VALUES(city),''),city),
            state=COALESCE(NULLIF(VALUES(state),''),state),
            zip=COALESCE(NULLIF(VALUES(zip),''),zip)
    ")->execute([
        $userId, $billingFirst, $billingLast, $billingEmail,
        $billingAddress, $billingCity, $billingState, $billingZip,
        $cardBrand, $cardLast4
    ]);
} catch (Exception $e) { /* non-critical — tokens already credited */ }

$bal = db()->prepare("SELECT tokens FROM users WHERE id=?");
$bal->execute([$userId]);
$newBal = (float)$bal->fetchColumn();
logActivity('token_purchase', $userId, null, 'purchase', (int)db()->lastInsertId(),
    "Bought {$tokens} tokens via {$method} for \$" . number_format($priceCents / 100, 2));
echo json_encode([
    'success'      => true,
    'manual'       => false,
    'tokens_added' => (int)$tokens,
    'new_balance'  => $newBal,
    'payment_id'   => $result['payment_id'],
    'card_brand'   => $cardBrand,
    'card_last4'   => $cardLast4,
    'receipt_url'  => $receiptUrl,
]);
