GNU/_PAGE/data/upbit/whale/total_table_chart.php
<?php require_once '/home/www/GNU/_PAGE/head.php'; ?>

<?php
require_once '/home/www/DB/db_upbit.php';
$db_upbit = $pdo;

// 1. 파라미터 수신 (기본값 설정)
$target_market = isset($_GET['market']) ? $_GET['market'] : 'KRW-BTC';
$target_table = isset($_GET['table']) ? $_GET['table'] : 'daemon_upbit_coin_1m'; 

// 2. 가용한 테이블 리스트
$table_list = [
    'daemon_upbit_coin_1s',
    'daemon_upbit_Ticker',
    'daemon_upbit_coin_1m',
    'daemon_upbit_coin_3m',
    'daemon_upbit_coin_5m',
    'daemon_upbit_coin_15m',
    'daemon_upbit_coin_30m',
    'daemon_upbit_coin_1h',
    'daemon_upbit_coin_4h',
    'daemon_upbit_coin_24h'
];

// 컬럼별 설명 정의 (풍선 도움말용)
$descriptions = [
    'market' => '업비트 마켓 종목 코드 (예: KRW-BTC)',
    'trade_date' => '최근 체결 일자 (UTC 기준)',
    'trade_time' => '최근 체결 시각 (UTC 기준)',
    'trade_date_kst' => '최근 체결 일자 (KST 기준)',
    'trade_time_kst' => '최근 체결 시각 (KST 기준)',
    'opening_price' => '금일 시가 (09시 기준)',
    'high_price' => '금일 고가',
    'low_price' => '금일 저가',
    'trade_price' => '현재 시장 체결 가격',
    'prev_closing_price' => '전일 종가 (09시 기준)',
    'change' => '전일 대비 상태 (RISE:상승, EVEN:보합, FALL:하락)',
    'change_price' => '전일 대비 변화 금액',
    'change_rate' => '전일 대비 변화율 (부호 없음)',
    'signed_change_price' => '부호가 포함된 변화 금액',
    'signed_change_rate' => '부호가 포함된 변화율',
    'trade_volume' => '최근 체결량',
    'acc_trade_volume' => '금일 누적 체결량 (09시 기준)',
    'acc_trade_volume_24h' => '최근 24시간 누적 체결량',
    'acc_trade_price' => '금일 누적 거래대금',
    'acc_trade_price_24h' => '최근 24시간 누적 거래대금',
    'highest_52_week_price' => '52주 최고가',
    'highest_52_week_date' => '52주 최고가 달성일',
    'lowest_52_week_price' => '52주 최저가',
    'lowest_52_week_date' => '52주 최저가 달성일',
    'collected_at' => '서버에 데이터가 기록된 시각',
    'collected_ms' => '데이터 수집 시점의 밀리초 타임스탬프',
    'timestamp' => '업비트 서버에서 제공한 타임스탬프',
    'ob_units' => '현재 호가창의 최상단 매수/매도 잔량 정보',
    'daemon_id' => '데이터를 수집한 데몬 프로세스 고유 식별자',
    'daemon_pid' => '데이터 수집 당시 프로세스 ID',
    'daemon_heartbeat' => '데몬의 생존 신호 타임스탬프',
    'avg_buy_price' => '현재 보유 중인 자산의 평균 매수가',
    'balance' => '현재 보유 수량',
    'locked' => '미체결 주문으로 묶여 있는 수량'
];

// 3. 선택된 테이블 내 실제 수집 중인 코인 리스트 호출
try {
    $list_sql = "SELECT DISTINCT market FROM {$target_table} ORDER BY market ASC";
    $list_stmt = $db_upbit->prepare($list_sql);
    $list_stmt->execute();
    $market_list = $list_stmt->fetchAll(PDO::FETCH_COLUMN);
} catch (Exception $e) {
    $market_list = [$target_market];
}

// 4. 최종 데이터 호출
try {
    $sql = "SELECT * FROM {$target_table} 
            WHERE market = :market 
            ORDER BY id DESC LIMIT 1";
    $stmt = $db_upbit->prepare($sql);
    $stmt->bindParam(':market', $target_market);
    $stmt->execute();
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
    $row = null;
}
?>

<!-- 웹 폰트 및 아이콘 로드 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">

<style>
    #ASSET_TERMINAL {
        background-color: #050505;
        color: #e5e7eb;
        font-family: 'Pretendard', sans-serif;
        padding: 40px;
        min-height: 100vh;
        position: relative;
    }

    @keyframes fadeInUp {
        from { opacity: 0; transform: translateY(20px); }
        to { opacity: 1; transform: translateY(0); }
    }

    .glass-card { 
        background: rgba(20, 20, 20, 0.6); 
        backdrop-filter: blur(10px);
        border: 1px solid rgba(255, 255, 255, 0.05); 
        padding: 20px; 
        border-radius: 12px; 
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        animation: fadeInUp 0.5s ease backwards;
        position: relative;
    }

    .glass-card:hover { 
        border-color: #38bdf8; 
        background: rgba(30, 30, 30, 0.8);
        transform: translateY(-5px);
        box-shadow: 0 10px 20px rgba(0, 0, 0, 0.5);
    }

    /* 풍선 도움말(Tooltip) 커스텀 디자인 */
    .glass-card::after {
        content: attr(data-help);
        position: absolute;
        bottom: 110%;
        left: 50%;
        transform: translateX(-50%);
        background: #38bdf8;
        color: #000;
        padding: 8px 12px;
        border-radius: 6px;
        font-size: 11px;
        font-weight: 700;
        white-space: nowrap;
        opacity: 0;
        visibility: hidden;
        transition: all 0.2s ease;
        z-index: 100;
        box-shadow: 0 5px 15px rgba(0,0,0,0.5);
    }
    
    .glass-card:hover::after {
        opacity: 1;
        visibility: visible;
        bottom: 100%;
    }

    .label { 
        font-family: 'Orbitron', sans-serif;
        font-size: 10px; 
        color: #38bdf8; 
        text-transform: uppercase; 
        letter-spacing: 1.5px; 
        margin-bottom: 10px;
        display: flex;
        align-items: center;
        gap: 6px;
    }

    .value { 
        font-family: 'JetBrains Mono', monospace;
        font-size: 17px; 
        color: #ffffff; 
        font-weight: 700; 
    }

    select { 
        background: #111; color: #fff; border: 1px solid #333; 
        padding: 10px 15px; border-radius: 8px; outline: none; cursor: pointer; font-size: 13px;
    }

    .btn-refresh {
        background: linear-gradient(135deg, #38bdf8, #0ea5e9); 
        color: #000; border: none; padding: 10px 20px; border-radius: 8px; 
        font-weight: 800; cursor: pointer; text-decoration: none; font-size: 13px;
        display: inline-flex; align-items: center; gap: 8px; font-family: 'Orbitron', sans-serif;
    }

    /* 그리드 지연 애니메이션 */
    <?php for($i=1; $i<=100; $i++): ?>
        .grid-item:nth-child(<?= $i ?>) { animation-delay: <?= 0.1 + ($i * 0.02) ?>s; }
    <?php endfor; ?>
</style>

<div id="ASSET_TERMINAL">
    
    <div class="title-area" style="display:flex; justify-content:space-between; align-items:flex-end; margin-bottom:50px; border-bottom:1px solid #1a1a1a; padding-bottom:30px;">
        <div>
            <h2 style="margin:0 0 12px 0; color:#fff; font-size:32px; font-weight:900; letter-spacing:-1.5px; font-family:'Orbitron', sans-serif;">
                <i class="fa-solid fa-microchip" style="color:#38bdf8; margin-right:10px;"></i><?= $target_market ?> <span style="color:#38bdf8; font-weight:400;">CORE</span>
            </h2>
            <div style="display:flex; gap:20px; align-items:center;">
                <span style="font-size:11px; color:#555; font-family:'Orbitron';">DATA_SOURCE:</span>
                <span style="font-size:12px; color:#38bdf8; font-family:'JetBrains Mono'; font-weight:bold;"><?= $target_table ?></span>
            </div>
        </div>

        <div>
            <form method="GET" style="margin:0; display:flex; gap:12px;">
                <select name="table" onchange="this.form.submit()">
                    <?php foreach ($table_list as $t): ?>
                        <option value="<?= $t ?>" <?= $target_table == $t ? 'selected' : '' ?>><?= $t ?></option>
                    <?php endforeach; ?>
                </select>

                <select name="market" onchange="this.form.submit()">
                    <?php foreach ($market_list as $m): ?>
                        <option value="<?= $m ?>" <?= $target_market == $m ? 'selected' : '' ?>><?= $m ?></option>
                    <?php endforeach; ?>
                </select>

                <button type="submit" class="btn-refresh"><i class="fa-solid fa-sync-alt"></i> ANALYZE</button>
            </form>
        </div>
    </div>

    <?php if (!$row): ?>
        <div style="padding:100px; text-align:center; color:#444; border:1px dashed #222; border-radius:20px; font-family:'Orbitron';">
            NO DATA DETECTED IN [<?= $target_table ?>]
        </div>
    <?php else: ?>
        
        <div style="margin-bottom:35px; padding-left:10px; border-left:4px solid #38bdf8; animation: fadeInUp 0.8s ease;">
            <div style="font-size:11px; color:#555; font-family:'Orbitron'; letter-spacing:2px;">LAST_HEARTBEAT_SIGNAL</div>
            <div style="font-size:22px; font-weight:bold; font-family:'JetBrains Mono'; color:#fff;"><?= $row['collected_at'] ?></div>
        </div>

        <div style="display:grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap:16px;">
            <?php 
            foreach ($row as $key => $value): 
                if ($key === 'id' || $key === 'korean_name') continue; 

                // 도움말 텍스트 가져오기
                $help_text = isset($descriptions[$key]) ? $descriptions[$key] : '상세 정보가 정의되지 않은 항목입니다.';

                $icon_class = "fa-solid fa-database";
                if(strpos($key, 'price') !== false) $icon_class = "fa-solid fa-tag";
                if(strpos($key, 'volume') !== false) $icon_class = "fa-solid fa-chart-simple";
                if(strpos($key, 'at') !== false || strpos($key, 'time') !== false) $icon_class = "fa-regular fa-clock";

                if ($key === 'ob_units' && !empty($value)) {
                    $units = json_decode($value, true);
                    $display_value = isset($units[0]) ? "B: ".number_format($units[0]['bid_price'])." / A: ".number_format($units[0]['ask_price']) : "Empty";
                } 
                else if (is_numeric($value)) {
                    if (strpos($key, 'rate') !== false || (abs($value) < 1 && $value != 0)) {
                        $display_value = number_format($value, 4);
                    } else {
                        $display_value = number_format($value);
                    }
                } 
                else {
                    $display_value = $value;
                }
            ?>
                <!-- data-help 속성을 통해 풍선 도움말 텍스트 전달 -->
                <div class="glass-card grid-item" data-help="<?= $help_text ?>">
                    <div class="label">
                        <i class="<?= $icon_class ?>"></i>
                        <?= str_replace('_', ' ', $key) ?>
                    </div>
                    <div class="value"><?= $display_value ?></div>
                </div>
            <?php endforeach; ?>
        </div>
    <?php endif; ?>

</div>

<?php require_once '/home/www/GNU/_PAGE/tail.php'; ?>