<?php
/**
 * API Proxy System - GSPay Integration
 * Maintain Original Response Structure for Client Compatibility
 */

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

require_once '../secret/config.php';
require_once 'class.gspay.php';
require_once '../vendor/autoload.php'; 

use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;

/**
 * Log Helper - Mencatat detail per case
 */
function write_case_log($case, $message, $data = null) {
    $log_path = __DIR__ . '/../logs/';
    if (!is_dir($log_path)) mkdir($log_path, 0777, true);
    
    $filename = $log_path . date('Y-m-d') . ".log";
    $timestamp = date('H:i:s');
    $log_content = "[{$timestamp}][{$case}] {$message}\n";
    if ($data) $log_content .= "Payload: " . json_encode($data, JSON_UNESCAPED_SLASHES) . "\n";
    $log_content .= "--------------------------------------------------\n";
    file_put_contents($filename, $log_content, FILE_APPEND);
}

$gspay = new GSPay();

$inputRaw = file_get_contents("php://input");
$input = json_decode($inputRaw, true) ?: $_POST;

$user = $input['username'] ?? '';
$key  = $input['key']      ?? '';
$action = $_GET['action'] ?? $input['action'] ?? null;

// Validasi Awal & Log Request Masuk
if (empty($user) || empty($key)) {
    write_case_log("AUTH_ERROR", "Missing credentials", $input);
    echo json_encode(["success" => false, "message" => "Authentication required"]);
    exit;
}

$stmt = $pdo->prepare("SELECT id, username, balance FROM agent_api WHERE username = ? AND api_key = ? AND status = 'active'");
$stmt->execute([$user, $key]);
$agent = $stmt->fetch();

if (!$agent) {
    write_case_log("AUTH_ERROR", "Invalid agent: " . $user);
    echo json_encode(["success" => false, "message" => "Invalid credentials"]);
    exit;
}

$final_response = ["success" => false, "message" => "Invalid Action"];

try {
    switch ($action) {
        case 'generate':
            write_case_log("case_qris", "Processing generate payment", $input);
            
            if (!isset($input['amount'], $input['player_username'])) {
                throw new Exception("Missing required fields: amount, player_username");
            }
            
            $raw_tx_id = 'TX' . time() . rand(10,99);
            $channel = strtoupper($input['channel'] ?? "QRIS");
            
            $prefix = ($channel === 'DANA') ? 'DN-' : 'QR-';
            $random_str = substr(str_shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"), 0, 9);
            $check_id = $prefix . $random_str;
            
            $raw_result = $gspay->generatePaymentIDR($raw_tx_id, $input['player_username'], $input['amount'], $input['channel'] ?? null);
            write_case_log("case_qris", "Provider Response", $raw_result);

            if (isset($raw_result['code']) && $raw_result['code'] == 200) {
                $gspay_data = json_decode($raw_result['data'], true)[0];
                
                $date = new DateTime($gspay_data['expire_date'], new DateTimeZone('UTC'));
                $date->setTimezone(new DateTimeZone('Asia/Jakarta'));
                $expired_at_wib = $date->format('Y-m-d H:i:s');

                // STRUCTURE TETAP SEPERTI ASLINYA
                $clean_data = [
                    "type"           => $channel,
                    "currency"       => "IDR",
                    "username"       => $input['player_username'],
                    "transaction_id" => $check_id,
                    "amount"         => (string)number_format($gspay_data['amount'], 0, '', ''),
                    "expired_at"     => $expired_at_wib
                ];

                $qris_img_url = null;
                if (!empty($gspay_data['qr'])) {
                    $local_file_path = $_SERVER['DOCUMENT_ROOT'] . '/qris/' . $check_id . '.png';
                    if (!is_dir($_SERVER['DOCUMENT_ROOT'] . '/qris/')) mkdir($_SERVER['DOCUMENT_ROOT'] . '/qris/', 0777, true);

                    $options = new QROptions([
                        'version'      => QRCode::VERSION_AUTO,
                        'outputType'   => QRCode::OUTPUT_IMAGE_PNG,
                        'eccLevel'     => QRCode::ECC_L,
                        'scale'        => 10,
                        'addQuietzone' => true,
                    ]);

                    (new QRCode($options))->render($gspay_data['qr'], $local_file_path);
                    
                    $source = imagecreatefrompng($local_file_path);
                    $dest = imagecreatetruecolor(250, 250);
                    imagecopyresampled($dest, $source, 0, 0, 0, 0, 250, 250, imagesx($source), imagesy($source));
                    imagepng($dest, $local_file_path);
                    imagedestroy($source); imagedestroy($dest);

                    $qris_img_url = "https://" . $_SERVER['HTTP_HOST'] . "/qris/" . $check_id . '.png';
                    $clean_data["qris_image"] = $qris_img_url;
                    $clean_data["qris_data"]  = $gspay_data['qr'];
                } else {
                    $clean_data["payment_url"] = $gspay_data['payment_url'];
                }

                $stmt_log = $pdo->prepare("INSERT INTO trx_agent (agent, check_id, player, amount, type, transaction_id, qris_image, status, expired_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
                $stmt_log->execute([$user, $check_id, $input['player_username'], $input['amount'], $channel, $raw_tx_id, $qris_img_url, 'pending', $expired_at_wib]);

                $final_response = ["success" => true, "data" => $clean_data];
            } else {
                $final_response = ["success" => false, "message" => $raw_result['message'] ?? "GSPay Error"];
            }
            break;

        case 'status':
            write_case_log("case_status", "Checking transaction status", $input);
            $search_id = $input['transaction_id'] ?? ''; 
            if (empty($search_id)) throw new Exception("Missing transaction_id");
            
            $stmt_find = $pdo->prepare("SELECT transaction_id, type, qris_image, player FROM trx_agent WHERE check_id = ?");
            $stmt_find->execute([$search_id]);
            $local_info = $stmt_find->fetch();

            if (!$local_info) throw new Exception("Transaction not found locally");

            $raw_result = $gspay->getPaymentStatus($local_info['transaction_id']);
            write_case_log("case_status", "Sync Response", $raw_result);
            
            if (isset($raw_result['code']) && $raw_result['code'] == 200) {
                $status_data = json_decode($raw_result['data'], true);
                $status_map = [0 => 'pending', 1 => 'success', 2 => 'failed'];
                $status_text = $status_map[$status_data['status']] ?? 'pending';

                $upd = $pdo->prepare("UPDATE trx_agent SET status = ? WHERE check_id = ?");
                $upd->execute([$status_text, $search_id]);

                $final_response = [
                    "success" => true,
                    "data" => [
                        "type"           => $local_info['type'],
                        "currency"       => "IDR",
                        "username"       => $status_data['player_username'] ?? $local_info['player'],
                        "transaction_id" => $search_id,
                        "amount"         => (string)number_format($status_data['amount'], 0, '', ''),
                        "remark"         => $status_data['remark'] ?? "Transaction " . $status_text,
                        "status"         => $status_text
                    ]
                ];
                if ($local_info['type'] === 'QRIS') {
                    $final_response['data']['qris_image'] = $local_info['qris_image'];
                }
            } else {
                $final_response = ["success" => false, "message" => "GSPay synchronization failed"];
            }
            break;

        case 'payout':
            write_case_log("case_payout", "Processing payout/withdraw", $input);
            if (!isset($input['amount'], $input['account_number'], $input['bank_target'], $input['player_username'], $input['account_name'])) {
                throw new Exception("Lengkapi data penarikan: amount, account_number, bank_target, player_username, account_name");
            }

            $stmt_conf = $pdo->query("SELECT wd_fee_percent, wd_fee_flat, min_withdraw FROM sys_config LIMIT 1");
            $config = $stmt_conf->fetch();

            $amount_req = (float)$input['amount'];
            if ($amount_req < $config['min_withdraw']) {
                throw new Exception("Minimal penarikan adalah Rp " . number_format($config['min_withdraw'], 0, ',', '.'));
            }

            $fee_admin       = $amount_req * $config['wd_fee_percent']; 
            $fee_transfer    = $config['wd_fee_flat'];
            $total_deduction = $amount_req + $fee_admin + $fee_transfer;

            if ($agent['balance'] < $total_deduction) {
                throw new Exception("Saldo tidak mencukupi. Butuh: Rp " . number_format($total_deduction, 0, ',', '.'));
            }

            $tx_id = $input['transaction_id'] ?? 'WD' . time();
            $result = $gspay->makePayout($tx_id, $input['player_username'], $input['account_name'], $input['account_number'], $input['amount'], $input['bank_target'], $input['description'] ?? "");
            write_case_log("case_payout", "Provider Response", $result);

            if (isset($result['code']) && $result['code'] == 200) {
                $pdo->prepare("UPDATE agent_api SET balance = balance - ? WHERE id = ?")->execute([$total_deduction, $agent['id']]);

                $stmt_wd = $pdo->prepare("INSERT INTO trx_withdraw (agent_id, username, bank_target, account_number, account_name, amount, fee_admin, fee_transfer, total_deduction, transaction_id, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
                $stmt_wd->execute([$agent['id'], $input['player_username'], $input['bank_target'], $input['account_number'], $input['account_name'], $amount_req, $fee_admin, $fee_transfer, $total_deduction, $tx_id, 'success']);

                $final_response = [
                    "success" => true,
                    "data" => [
                        "type"           => "WITHDRAW",
                        "transaction_id" => $tx_id,
                        "amount"         => (string)$amount_req,
                        "fee_service"    => (string)$fee_admin,
                        "fee_admin"      => (string)$fee_transfer,
                        "total_deduction"=> (string)$total_deduction,
                        "status"         => "success",
                        "remaining_balance" => (string)($agent['balance'] - $total_deduction)
                    ]
                ];
            } else {
                $final_response = ["success" => false, "message" => $result['message'] ?? "Provider Payout Error"];
            }
            break;

        default:
            $final_response = ["success" => false, "message" => "Endpoint not found"];
    }
} catch (Exception $e) {
    write_case_log("EXCEPTION_ERROR", $e->getMessage());
    $final_response = ["success" => false, "message" => $e->getMessage()];
}

echo json_encode($final_response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);