<!doctype html>
<html lang="ko">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
    <title><%= service.name %></title>
    <link rel="stylesheet" href="/css/admin.css?v=wallet-balance-20260710">
  </head>
  <body class="wallet-screen">
    <% const safeErrorCode = typeof errorCode === 'string' ? errorCode : ''; %>
    <% const safeErrorScope = typeof errorScope === 'string' ? errorScope : ''; %>
    <main class="shell explorer-shell wallet-app wallet-native" data-wallet-view="home">
      <header class="topbar wallet-topbar">
        <div>
          <p class="eyebrow"><%= service.mode %></p>
          <h1><%= service.name %></h1>
          <p class="muted">로그인 사용자: <%= walletUser.displayName || walletUser.userId %></p>
        </div>
        <div class="top-actions">
          <a class="nav-button" href="/wallet/evm">PLAIS EVM 지갑</a>
          <a class="nav-button" href="/explorer">Explorer</a>
          <% if (canAccessAdmin) { %>
            <a class="nav-button" href="/admin">Admin</a>
          <% } %>
          <a class="nav-button subtle" href="/wallet/logout">Logout</a>
          <div class="status"><span></span><%= String(testnet.config.networkId || '').replace(/^aisfor/i, 'plai') %></div>
        </div>
      </header>

      <% if (txHash) { %>
        <section class="panel wallet-alert"><strong>송금 완료</strong><a href="/explorer/tx/<%= encodeURIComponent(txHash) %>"><code><%= txHash %></code></a></section>
      <% } %>
      <% if (recoveryNotice) { %>
        <section class="panel wallet-alert"><strong>복구 금고</strong><span><%= recoveryNotice %></span></section>
      <% } %>
      <% if (recoveryExport) { %>
        <section class="panel wallet-alert wallet-recovery-export">
          <strong>복구 정보</strong>
          <p>지금 화면에서만 확인됩니다. 복구문구와 테스트 개인키를 안전한 곳에 보관하세요.</p>
          <div class="recovery-export">
            <span>복구문구</span>
            <code id="recoveryPhrase"><%= recoveryExport.recoveryPhrase %></code>
            <button class="nav-button subtle" type="button" onclick="copyById('recoveryPhrase', this)">복사</button>
          </div>
          <div class="recovery-export">
            <span>테스트 개인키</span>
            <code id="recoveryPrivateKey"><%= recoveryExport.privateKey %></code>
            <button class="nav-button subtle" type="button" onclick="copyById('recoveryPrivateKey', this)">복사</button>
          </div>
        </section>
      <% } %>

      <% if (!wallet) { %>
        <section class="panel">
          <div class="panel-title">
            <h2>내 plais 지갑 만들기</h2>
            <span>새 지갑</span>
          </div>
          <p class="muted">현재 로그인 사용자에게 연결된 지갑이 없습니다. 이름을 확인한 뒤 새 지갑을 만들어 주세요.</p>
          <form class="wallet-form compact" method="post" action="/wallet/create">
            <label>지갑 이름<input name="label" placeholder="plais User Wallet"></label>
            <label>새 PIN<input name="pin" type="password" inputmode="numeric" minlength="4" maxlength="12" placeholder="숫자 4-12자리" required></label>
            <label>PIN 확인<input name="pinConfirm" type="password" inputmode="numeric" minlength="4" maxlength="12" placeholder="다시 입력" required></label>
            <button type="submit">내 지갑 만들기</button>
          </form>
          <p class="muted">생성하면 복구문구와 테스트 개인키가 한 번 표시됩니다. 반드시 따로 보관한 뒤 복구문구 확인까지 진행하세요.</p>
        </section>
      <% } else { %>
      <nav class="wallet-sticky-actions wallet-primary-actions" aria-label="지갑 상단 메뉴">
        <button type="button" data-wallet-tab="home" class="active"><span>⌂</span><strong>홈</strong></button>
        <button type="button" data-wallet-tab="send"><span>↗</span><strong>전송</strong></button>
        <button type="button" data-wallet-tab="receive"><span>⌗</span><strong>수령</strong></button>
        <button type="button" data-wallet-tab="collateral"><span>◆</span><strong>담보</strong></button>
        <button type="button" data-wallet-tab="history"><span>↺</span><strong>내역</strong></button>
        <button type="button" data-wallet-tab="security"><span>⌁</span><strong>보안</strong></button>
      </nav>
      <section class="wallet-hero">
        <div class="panel wallet-balance-panel">
          <div class="panel-title">
            <h2><%= wallet.label %></h2>
            <span><%= wallet.status %></span>
          </div>
          <div class="wallet-balance"><%= toDisplayAmount(wallet.balance) %> <%= walletStats.coin.symbol %></div>
          <div class="wallet-subgrid">
            <div><span>사용 가능</span><strong><%= toDisplayAmount((wallet.balance || 0) - (wallet.lockedBalance || 0)) %></strong></div>
            <div><span>잠금</span><strong><%= toDisplayAmount(wallet.lockedBalance || 0) %></strong></div>
            <div><span>Nonce</span><strong><%= wallet.nonce || 0 %></strong></div>
            <div><span>PIN</span><strong><%= pinEnabled ? 'ON' : 'OFF' %></strong></div>
          </div>
          <code class="address-code" id="walletAddress"><%= wallet.address %></code>
          <div class="wallet-actions">
            <button class="nav-button" type="button" onclick="copyAddress()">주소 복사</button>
            <a class="nav-button" href="/explorer/address/<%= encodeURIComponent(wallet.address) %>">Explorer 보기</a>
          </div>
          <div class="wallet-primary-actions" aria-label="지갑 주요 기능">
            <button type="button" data-wallet-tab="home" class="active"><span>⌂</span><strong>홈</strong></button>
            <button type="button" data-wallet-tab="send"><span>↗</span><strong>전송</strong></button>
            <button type="button" data-wallet-tab="receive"><span>⌗</span><strong>수령</strong></button>
            <button type="button" data-wallet-tab="collateral"><span>◆</span><strong>담보</strong></button>
            <button type="button" data-wallet-tab="history"><span>↺</span><strong>내역</strong></button>
            <button type="button" data-wallet-tab="security"><span>⌁</span><strong>보안</strong></button>
          </div>
        </div>

        <div class="panel wallet-receive-panel wallet-view wallet-view-receive" id="receivePanel">
          <div class="panel-title"><h2>받기</h2><span><%= walletStats.coin.symbol %></span></div>
          <img class="wallet-qr" alt="Wallet QR" src="/wallet/qr/<%= encodeURIComponent(wallet.address) %>">
          <code class="address-code wallet-receive-address" id="receiveWalletAddress"><%= wallet.address %></code>
          <div class="wallet-actions wallet-receive-actions">
            <button class="nav-button" type="button" onclick="copyById('receiveWalletAddress', this)">주소 복사</button>
            <a class="nav-button subtle" href="/explorer/address/<%= encodeURIComponent(wallet.address) %>">Explorer 보기</a>
          </div>
          <p class="muted wallet-note">주소를 복사하거나 QR로 받을 수 있습니다.</p>
        </div>
      </section>

      <section class="panel wallet-collateral-panel wallet-view wallet-view-collateral" id="collateralPanel">
        <% const currentNodeCollateral = selectedNodeCollateral || null; %>
        <% const currentCollateralAccount = currentNodeCollateral ? currentNodeCollateral.account : trxCollateral; %>
        <% const currentNodeName = currentNodeCollateral ? (currentNodeCollateral.node.deviceName || currentNodeCollateral.node.serviceName || currentNodeCollateral.node.nodeId) : '내 계정'; %>
        <% const currentCapacityLabel = currentNodeCollateral ? (currentNodeCollateral.capacityLabel || (toDisplayAmount(currentNodeCollateral.capacityTb) + ' TB')) : '-'; %>
        <% const otherNodeCollateralRows = (nodeCollateralRows || []).filter(function(row) { return !currentNodeCollateral || row.node.nodeId !== currentNodeCollateral.node.nodeId; }); %>
        <div class="panel-title">
          <h2>TRX 담보</h2>
          <span><%= currentCollateralAccount.status %></span>
        </div>
        <% if (safeErrorScope === 'collateral' && error) { %>
          <p class="wallet-field-error"><%= error %></p>
        <% } %>
        <% if ((nodeCollateralRows || []).length > 0) { %>
          <label class="wallet-node-select-label">담보 대상 노드
            <select onchange="if (this.value) location.href='/wallet?address=<%= encodeURIComponent(wallet.address) %>&nodeId=' + encodeURIComponent(this.value) + '#collateralPanel';">
              <% nodeCollateralRows.forEach(function(row) { %>
                <option value="<%= row.node.nodeId %>" <%= row.node.nodeId === selectedCollateralNodeId ? 'selected' : '' %>><%= row.node.deviceName || row.node.serviceName || row.node.nodeId %> / 필요 <%= toDisplayAmount(row.requiredCollateral) %> TRX</option>
              <% }) %>
            </select>
          </label>
          <div class="wallet-node-focus">
            <div class="wallet-node-focus-head">
              <div>
                <span class="wallet-node-kicker">현재 선택된 노드</span>
                <h3><%= currentNodeName %></h3>
              </div>
              <span class="wallet-node-badge <%= currentCollateralAccount.status === 'active' ? 'active' : '' %>"><%= currentCollateralAccount.status %></span>
            </div>
            <div class="wallet-node-focus-grid">
              <div><span>제공 용량</span><strong><%= currentCapacityLabel %></strong></div>
              <div><span>필요 담보</span><strong><%= toDisplayAmount(currentNodeCollateral ? currentNodeCollateral.requiredCollateral : 0) %> TRX</strong></div>
              <div><span>확정 담보</span><strong><%= toDisplayAmount(currentCollateralAccount.confirmedAmount || 0) %> TRX</strong></div>
              <div><span>승인 대기</span><strong><%= toDisplayAmount(currentCollateralAccount.pendingAmount || 0) %> TRX</strong></div>
            </div>
            <% if (currentCollateralAccount.depositMemo) { %>
              <code class="wallet-node-memo">Memo: <%= currentCollateralAccount.depositMemo %></code>
            <% } %>
          </div>
        <% } else { %>
          <p class="wallet-field-error">등록된 내 노드가 없습니다. sync-client 노드가 연결된 뒤 노드별 담보를 요청할 수 있습니다.</p>
        <% } %>
        <div class="wallet-asset-strip">
          <div><span>확정 담보</span><strong><%= toDisplayAmount(currentCollateralAccount.confirmedAmount || 0) %> TRX</strong></div>
          <div><span>승인 대기</span><strong><%= toDisplayAmount(currentCollateralAccount.pendingAmount || 0) %> TRX</strong></div>
          <div><span>1TB 기준</span><strong><%= toDisplayAmount(trxCollateralStats.config.trxPerTb || 100) %> TRX</strong></div>
          <div><span>채굴 기준</span><strong><%= toDisplayAmount(currentNodeCollateral ? currentNodeCollateral.requiredCollateral : (trxCollateralStats.config.minNodeCollateral || 0)) %> TRX</strong></div>
        </div>
        <p class="muted">plais 상장 전까지 TRX를 임시 담보로 사용합니다. 보낸 TRX 주소를 입력하면 실제 입금 여부를 확인해 담보로 반영합니다.</p>
        <% if (trxCollateral.metadata && trxCollateral.metadata.mockAddress) { %>
          <p class="wallet-field-error">현재 주소는 테스트 전용 mock TRX 주소입니다. 실제 TRX를 보내지 마세요. 실제 입금 전에는 운영 TRX 입금주소 설정 또는 TRON 주소 생성 연동이 필요합니다.</p>
        <% } else { %>
          <p class="wallet-success">운영 TRX 입금주소가 설정되어 있습니다. 외부 TRX 지갑에서 입금 후 보낸 주소만 입력해 주세요.</p>
        <% } %>
        <p class="muted">현재 선택된 노드의 채굴 기준은 <%= toDisplayAmount(currentNodeCollateral ? currentNodeCollateral.requiredCollateral : (trxCollateralStats.config.minNodeCollateral || 0)) %> TRX이며, 1TB 기준은 <%= toDisplayAmount(trxCollateralStats.config.trxPerTb || 100) %> TRX입니다. 아래 TRX 주소를 복사해서 각자의 외부 TRX 지갑에서 기준에 맞게 전송한 뒤, 보낸 TRX 주소와 수량만 입력해 주세요.</p>
        <p class="wallet-field-error">TRX 전송 전 주소와 네트워크를 반드시 확인하세요. 잘못 보낸 TRX는 자동 복구되지 않을 수 있습니다.</p>
        <% if ((otherNodeCollateralRows || []).length > 0) { %>
          <details class="wallet-node-list">
            <summary>다른 노드 보기 <span><%= otherNodeCollateralRows.length %>개</span></summary>
            <div class="wallet-node-list-body">
            <% otherNodeCollateralRows.forEach(function(row) { %>
              <a class="wallet-node-link" href="/wallet?address=<%= encodeURIComponent(wallet.address) %>&nodeId=<%= encodeURIComponent(row.node.nodeId) %>#collateralPanel">
                <div class="item">
                  <strong><%= row.node.deviceName || row.node.serviceName || row.node.nodeId %> / <%= row.account.status %></strong>
                  <span><%= row.capacityLabel || (toDisplayAmount(row.capacityTb) + ' TB') %> / 필요 <%= toDisplayAmount(row.requiredCollateral) %> TRX</span>
                  <span>확정 <%= toDisplayAmount(row.account.confirmedAmount || 0) %> TRX / 대기 <%= toDisplayAmount(row.account.pendingAmount || 0) %> TRX</span>
                  <code><%= row.node.nodeId %></code>
                  <% if (row.account.depositMemo) { %>
                    <code>Memo: <%= row.account.depositMemo %></code>
                  <% } %>
                </div>
              </a>
            <% }) %>
            </div>
          </details>
        <% } %>
        <code class="address-code wallet-receive-address wallet-collateral-address" id="trxCollateralAddress"><%= trxCollateral.depositAddress %></code>
        <% if (currentCollateralAccount.depositMemo) { %>
          <code class="address-code wallet-collateral-address">Memo: <%= currentCollateralAccount.depositMemo %></code>
        <% } %>
        <div class="wallet-actions wallet-receive-actions wallet-collateral-actions">
          <button class="nav-button" type="button" onclick="copyById('trxCollateralAddress', this)">TRX 주소 복사</button>
        </div>
        <form class="wallet-form compact" method="post" action="/wallet/collateral/trx/request">
          <input type="hidden" name="walletAddress" value="<%= wallet.address %>">
          <% if ((nodeCollateralRows || []).length > 0) { %>
            <input type="hidden" name="nodeId" value="<%= selectedCollateralNodeId %>">
          <% } %>
          <label>보낸 TRX 주소<input name="senderTrxAddress" placeholder="T..." required></label>
          <label>입금한 TRX 수량<input id="trxCollateralAmountInput" name="amount" type="number" step="0.000001" min="0.000001" value="<%= currentNodeCollateral ? currentNodeCollateral.requiredCollateral : (trxCollateralStats.config.minNodeCollateral || 0) %>" placeholder="0.000000" required></label>
          <label>메모<input name="note" placeholder="담보 입금 메모"></label>
          <button type="submit">TRX 담보 확인 요청</button>
        </form>
        <div class="wallet-collateral-events">
          <% const currentCollateralEvents = selectedCollateralEvents || trxCollateralEvents || []; %>
          <% if ((currentCollateralEvents || []).length === 0) { %>
            <p class="empty">아직 TRX 담보 요청이 없습니다.</p>
          <% } %>
          <% (currentCollateralEvents || []).forEach(function(event) { %>
            <div class="item">
              <strong><%= event.amount %> TRX / <%= event.status %></strong>
              <span><%= event.senderTrxAddress || '-' %> → <%= event.depositAddress || '-' %></span>
              <span><%= event.createdAt %> / confirmations <%= event.confirmations || 0 %></span>
              <code><%= event.externalTxHash || event.id %></code>
            </div>
          <% }) %>
        </div>
      </section>

      <section class="grid wallet-grid">
        <article class="panel wallet-send-panel wallet-view wallet-view-send" id="sendPanel">
          <div class="panel-title"><h2>보내기</h2><span>체인 기록</span></div>
          <form class="wallet-form" method="post" action="/wallet/transfer">
            <input type="hidden" name="fromAddress" value="<%= wallet.address %>">
            <label>받는 주소<input name="toAddress" placeholder="plai..." required></label>
            <label>수량<input name="amount" type="number" step="0.000001" min="0.000001" placeholder="0.000000" required></label>
            <label>수수료<input name="fee" type="text" value="1 plais 고정" readonly></label>
            <label>메모<input name="memo" placeholder="메모"></label>
            <label>PIN<input name="pin" type="password" inputmode="numeric" placeholder="PIN" <%= pinEnabled ? 'required' : '' %>></label>
            <% if ((!safeErrorScope || safeErrorScope === 'transfer') && ['PIN_REQUIRED', 'INVALID_PIN', 'INSUFFICIENT_BALANCE', 'INVALID_AMOUNT', 'TARGET_WALLET_NOT_FOUND'].includes(safeErrorCode)) { %>
              <p class="wallet-field-error"><%= error %></p>
            <% } %>
            <button type="submit"><%= walletStats.coin.symbol %> 보내기</button>
          </form>
        </article>

        <article class="panel wallet-manage-panel wallet-view wallet-view-security">
          <div class="panel-title"><h2>내 지갑</h2><span><%= wallets.length %>개</span></div>
          <% if (wallets.length > 1) { %>
            <form class="wallet-form compact" method="get" action="/wallet">
              <label>지갑 선택
                <select name="address" onchange="this.form.submit()">
                  <% wallets.forEach(function(row) { %>
                    <option value="<%= row.address %>" <%= row.address === wallet.address ? 'selected' : '' %>><%= row.label %> / <%= toDisplayAmount(row.balance) %> <%= walletStats.coin.symbol %></option>
                  <% }) %>
                </select>
              </label>
            </form>
          <% } else { %>
            <p class="muted">현재 로그인 사용자에게 연결된 지갑만 표시됩니다.</p>
          <% } %>
          <form class="wallet-form compact" method="post" action="/wallet/create">
            <label>지갑 이름<input name="label" placeholder="plais User Wallet"></label>
            <label>새 PIN<input name="pin" type="password" inputmode="numeric" minlength="4" maxlength="12" placeholder="새 지갑 생성 시 필요"></label>
            <label>PIN 확인<input name="pinConfirm" type="password" inputmode="numeric" minlength="4" maxlength="12" placeholder="다시 입력"></label>
            <% if (safeErrorScope === 'create' && ['PIN_REQUIRED', 'PIN_MISMATCH'].includes(safeErrorCode)) { %>
              <p class="wallet-field-error"><%= error %></p>
            <% } %>
            <button type="submit">내 지갑 확인 / 만들기</button>
          </form>
          <% if (!pinEnabled && !(recoveryStatus && recoveryStatus.enabled) && transactions.length === 0 && Number(wallet.balance || 0) === 0 && Number(wallet.lockedBalance || 0) === 0) { %>
            <form class="wallet-form compact" method="post" action="/wallet/delete" onsubmit="return confirm('이 빈 지갑을 삭제하고 다시 만들까요?');">
              <input type="hidden" name="address" value="<%= wallet.address %>">
              <button type="submit" class="danger">빈 지갑 삭제</button>
            </form>
          <% } %>
        </article>

        <article class="panel wallet-pin-panel wallet-view wallet-view-security" id="securityPanel">
          <div class="panel-title"><h2>PIN 보호</h2><span><%= pinEnabled ? 'ON' : 'OFF' %></span></div>
          <form class="wallet-form compact" method="post" action="/wallet/pin">
            <input type="hidden" name="address" value="<%= wallet.address %>">
            <label>새 PIN<input name="pin" type="password" inputmode="numeric" minlength="4" maxlength="12" placeholder="숫자 4-12자리" required></label>
            <% if (safeErrorScope === 'pin' && ['PIN_REQUIRED', 'INVALID_PIN', 'PIN_MISMATCH'].includes(safeErrorCode)) { %>
              <p class="wallet-field-error"><%= error %></p>
            <% } %>
            <button type="submit"><%= pinEnabled ? 'PIN 변경' : 'PIN 켜기' %></button>
          </form>
        </article>

        <article class="panel wallet-recovery-panel wallet-view wallet-view-security">
          <div class="panel-title"><h2>복구 금고</h2><span><%= recoveryStatus && recoveryStatus.enabled ? (recoveryStatus.recoveryConfirmedAt ? '확인됨' : '암호화됨') : 'OFF' %></span></div>
          <p class="muted">복구문구와 테스트 개인키는 PIN 기반 AES-256-GCM으로 암호화해 저장합니다.</p>
          <div class="wallet-recovery-status">
            <span>금고 <strong><%= recoveryStatus && recoveryStatus.enabled ? 'ON' : 'OFF' %></strong></span>
            <span>확인 <strong><%= recoveryStatus && recoveryStatus.recoveryConfirmedAt ? 'YES' : 'NO' %></strong></span>
            <span>복원 <strong><%= recoveryStatus && recoveryStatus.restoredAt ? 'YES' : 'NO' %></strong></span>
          </div>
          <form class="wallet-form compact" method="post" action="/wallet/recovery/enable">
            <input type="hidden" name="address" value="<%= wallet.address %>">
            <label>지갑 PIN<input name="pin" type="password" inputmode="numeric" minlength="4" maxlength="12" placeholder="PIN 필수" required></label>
            <% if (safeErrorScope === 'recovery' && ['PIN_REQUIRED', 'INVALID_PIN', 'RECOVERY_EXPORT_FAILED'].includes(safeErrorCode)) { %>
              <p class="wallet-field-error"><%= error %></p>
            <% } %>
            <button type="submit"><%= recoveryStatus && recoveryStatus.enabled ? '복구 정보 보기' : '복구 금고 만들기' %></button>
          </form>
          <% if (recoveryStatus && recoveryStatus.enabled) { %>
            <form class="wallet-form compact" method="post" action="/wallet/recovery/confirm">
              <input type="hidden" name="address" value="<%= wallet.address %>">
              <label>지갑 PIN<input name="pin" type="password" inputmode="numeric" minlength="4" maxlength="12" placeholder="PIN 필수" required></label>
              <label>복구문구<textarea name="recoveryPhrase" rows="3" placeholder="12개 복구 단어" required></textarea></label>
              <% if (safeErrorScope === 'recoveryConfirm' && ['PIN_REQUIRED', 'INVALID_PIN', 'RECOVERY_PHRASE_REQUIRED', 'RECOVERY_PHRASE_MISMATCH'].includes(safeErrorCode)) { %>
                <p class="wallet-field-error"><%= error %></p>
              <% } %>
              <button type="submit">복구문구 확인</button>
            </form>
          <% } %>
          <details class="wallet-restore-box">
            <summary>복구문구로 지갑 복원</summary>
            <form class="wallet-form compact" method="post" action="/wallet/recovery/restore">
              <label>복구문구<textarea name="recoveryPhrase" rows="3" placeholder="12개 복구 단어" required></textarea></label>
              <label>새 PIN<input name="newPin" type="password" inputmode="numeric" minlength="4" maxlength="12" placeholder="숫자 4-12자리" required></label>
              <% if (safeErrorScope === 'recoveryRestore' && ['PIN_REQUIRED', 'INVALID_PIN', 'RECOVERY_PHRASE_REQUIRED', 'RECOVERY_WALLET_NOT_FOUND'].includes(safeErrorCode)) { %>
                <p class="wallet-field-error"><%= error %></p>
              <% } %>
              <button type="submit">지갑 찾고 다시 잠그기</button>
            </form>
          </details>
          <details class="wallet-restore-box">
            <summary>개인키로 지갑 복원</summary>
            <form class="wallet-form compact" method="post" action="/wallet/recovery/restore-private-key">
              <label>테스트 개인키<textarea name="privateKey" rows="3" placeholder="plai_mock_private_..." required></textarea></label>
              <label>새 PIN<input name="newPin" type="password" inputmode="numeric" minlength="4" maxlength="12" placeholder="숫자 4-12자리" required></label>
              <% if (safeErrorScope === 'privateKeyRestore' && ['PIN_REQUIRED', 'INVALID_PIN', 'PRIVATE_KEY_REQUIRED', 'PRIVATE_KEY_WALLET_NOT_FOUND'].includes(safeErrorCode)) { %>
                <p class="wallet-field-error"><%= error %></p>
              <% } %>
              <button type="submit">개인키로 지갑 찾고 다시 잠그기</button>
            </form>
          </details>
        </article>
      </section>

      <section class="panel wallet-history-panel wallet-view wallet-view-history" id="historyPanel">
        <div class="panel-title"><h2>거래 내역</h2><span><%= transactions.length %>건</span></div>
        <div class="wallet-history-filter" aria-label="거래 내역 필터">
          <button type="button" data-history-filter="all" class="active">전체</button>
          <button type="button" data-history-filter="in">받은 내역</button>
          <button type="button" data-history-filter="out">보낸 내역</button>
        </div>
        <div class="table-wrap">
          <table>
            <thead><tr><th>시간</th><th>유형</th><th>방향</th><th>수량</th><th>메모</th><th>상태</th><th>Ledger</th><th>Hash</th></tr></thead>
            <tbody>
              <% if (transactions.length === 0) { %><tr><td colspan="8">아직 지갑 거래가 없습니다.</td></tr><% } %>
              <% transactions.forEach(function(tx) { const incoming = tx.toAddress === wallet.address; %>
                <tr data-history-direction="<%= incoming ? 'in' : 'out' %>">
                  <td><%= tx.confirmedAt || tx.createdAt || '-' %></td>
                  <td><%= tx.type %></td>
                  <td><span class="badge <%= incoming ? 'badge-ok' : 'badge-warn' %>"><%= incoming ? 'IN' : 'OUT' %></span></td>
                  <td><strong><%= incoming ? '+' : '-' %><%= toDisplayAmount(tx.amount) %> <%= walletStats.coin.symbol %></strong></td>
                  <td><%= tx.memo || '-' %></td>
                  <td><%= tx.status %></td>
                  <td><%= tx.ledgerBlockHeight ? ('#' + tx.ledgerBlockHeight) : (tx.chainMockBlockHeight ? ('mock #' + tx.chainMockBlockHeight) : '-') %></td>
                  <td>
                    <a href="/explorer/tx/<%= encodeURIComponent(tx.txHash) %>"><code><%= tx.txHash %></code></a>
                    <% if (tx.chainTxHash) { %><br><a href="/explorer/tx/<%= encodeURIComponent(tx.chainTxHash) %>"><code>chain <%= tx.chainTxHash %></code></a><% } %>
                  </td>
                </tr>
              <% }) %>
            </tbody>
          </table>
        </div>
      </section>
      <% } %>
    </main>
    <script>
      function writeClipboard(text) {
        if (!navigator.clipboard) return Promise.reject(new Error('clipboard unavailable'));
        return navigator.clipboard.writeText(text);
      }

      function copyAddress() {
        const node = document.getElementById('walletAddress');
        if (!node) return;
        writeClipboard(node.textContent.trim()).catch(function() {});
      }

      function copyById(id, button) {
        const node = document.getElementById(id);
        if (!node) return;
        writeClipboard(node.textContent.trim()).then(function() {
          if (!button) return;
          const original = button.textContent;
          button.textContent = '복사됨';
          setTimeout(function() {
            button.textContent = original;
          }, 1200);
        }).catch(function() {});
      }

      function getWalletViewTarget(view) {
        if (view === 'send') return document.getElementById('sendPanel');
        if (view === 'receive') return document.getElementById('receivePanel');
        if (view === 'collateral') return document.getElementById('collateralPanel');
        if (view === 'history') return document.getElementById('historyPanel');
        if (view === 'security') return document.getElementById('securityPanel');
        return document.querySelector('.wallet-balance-panel');
      }

      function setWalletView(view, shouldFocus) {
        const main = document.querySelector('.wallet-native');
        if (!main) return;
        const allowed = ['home', 'send', 'receive', 'collateral', 'history', 'security'];
        const nextView = allowed.includes(view) ? view : 'home';
        main.dataset.walletView = nextView;
        document.querySelectorAll('[data-wallet-tab]').forEach(function(button) {
          button.classList.toggle('active', button.dataset.walletTab === nextView);
        });
        if (shouldFocus) {
          window.setTimeout(function() {
            const target = getWalletViewTarget(nextView);
            if (!target) return;
            const sticky = document.querySelector('.wallet-sticky-actions');
            const stickyHeight = sticky ? sticky.getBoundingClientRect().height : 0;
            const gap = 28;
            const top = target.getBoundingClientRect().top + window.pageYOffset - stickyHeight - gap;
            window.scrollTo({ top: Math.max(0, top), behavior: 'smooth' });
          }, 40);
        }
      }

      function setHistoryFilter(filter) {
        const nextFilter = ['all', 'in', 'out'].includes(filter) ? filter : 'all';
        document.querySelectorAll('[data-history-filter]').forEach(function(button) {
          button.classList.toggle('active', button.dataset.historyFilter === nextFilter);
        });
        document.querySelectorAll('[data-history-direction]').forEach(function(row) {
          row.classList.toggle('wallet-history-hidden', nextFilter !== 'all' && row.dataset.historyDirection !== nextFilter);
        });
      }

      document.addEventListener('DOMContentLoaded', function() {
        document.querySelectorAll('[data-wallet-tab]').forEach(function(button) {
          button.addEventListener('click', function() {
            setWalletView(button.dataset.walletTab, true);
          });
        });
        document.querySelectorAll('[data-history-filter]').forEach(function(button) {
          button.addEventListener('click', function() {
            setHistoryFilter(button.dataset.historyFilter);
          });
        });

        const errorScope = '<%= safeErrorScope %>';
        const securityScopes = ['pin', 'create', 'recovery', 'recoveryConfirm', 'recoveryRestore', 'privateKeyRestore'];
        const params = new URLSearchParams(window.location.search);
        const hashView = window.location.hash === '#collateralPanel'
          ? 'collateral'
          : window.location.hash === '#historyPanel'
            ? 'history'
            : window.location.hash === '#receivePanel'
              ? 'receive'
              : '';
        const queryView = params.has('nodeId') ? 'collateral' : '';
        const initialView = errorScope === 'transfer'
          ? 'send'
          : errorScope === 'collateral'
            ? 'collateral'
          : securityScopes.includes(errorScope)
            ? 'security'
            : hashView || queryView || '<%= txHash ? "history" : "home" %>';
        setWalletView(initialView, initialView !== 'home');
        setHistoryFilter('all');
      });
    </script>
  </body>
</html>
