<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" language="java" %>
<%@ page import="java.util.List" %>
<%@ page import="com.pandoli365.bibimbap.data.JamData" %>
<%@ page import="org.springframework.web.util.HtmlUtils" %>
<%
    String ctx = request.getContextPath();

    Object rawJams = request.getAttribute("jams");
    List<JamData> jams = rawJams instanceof List<?> ? (List<JamData>) rawJams : null;

    Object rawCsrf = request.getAttribute("csrfToken");
    String csrfToken = rawCsrf == null ? "" : String.valueOf(rawCsrf);
    String csrfTokenHtml = HtmlUtils.htmlEscape(csrfToken);
    // JS 문자열 컨텍스트용: 따옴표/역슬래시/스크립트 종료 시퀀스 차단
    String csrfTokenJs = csrfToken
            .replace("\\", "\\\\")
            .replace("'", "\\'")
            .replace("\"", "\\\"")
            .replace("<", "\\u003C")
            .replace(">", "\\u003E")
            .replace("\r", "")
            .replace("\n", "");
%>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="_csrf" content="<%= csrfTokenHtml %>">
    <jsp:include page="/WEB-INF/views/theme-init.jsp"/>
    <title>게임잼 관리 | bibimbap</title>
    <style>
      html {
        color-scheme: light;
        --surface: #faf8f5;
        --card-bg: #fff;
        --text: #1a1a1a;
        --text-muted: #5c5c5c;
        --accent: #e8a54b;
        --accent-soft: rgba(232, 165, 75, 0.16);
        --border: rgba(0, 0, 0, 0.08);
        --shadow: rgba(0, 0, 0, 0.06);
        --field-bg: #fff;
        --button-text: #1a1a1a;
      }
      html[data-theme="dark"] {
        color-scheme: dark;
        --surface: #121212;
        --card-bg: #1e1e1e;
        --text: #ece8e1;
        --text-muted: #a39e96;
        --border: rgba(255, 255, 255, 0.1);
        --shadow: rgba(0, 0, 0, 0.35);
        --field-bg: #181818;
        --button-text: #1a1a1a;
      }
      body {
        margin: 0;
        min-height: 100vh;
        font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans KR", sans-serif;
        background: var(--surface);
        color: var(--text);
      }
      .admin-page {
        max-width: 78rem;
        margin: 0 auto;
        padding: 1.5rem max(1rem, env(safe-area-inset-left)) 3rem max(1rem, env(safe-area-inset-right));
      }
      .admin-hero {
        margin-bottom: 1.5rem;
      }
      .admin-hero__eyebrow {
        margin: 0 0 0.35rem;
        color: var(--accent);
        font-size: 0.75rem;
        font-weight: 900;
      }
      .admin-hero h1 {
        margin: 0;
        font-size: 1.9rem;
        line-height: 1.2;
        letter-spacing: 0;
      }
      .admin-hero p {
        margin: 0.45rem 0 0;
        color: var(--text-muted);
        line-height: 1.6;
      }
      .admin-section {
        margin-bottom: 2rem;
        padding: 1.25rem;
        border: 1px solid var(--border);
        border-radius: 12px;
        background: var(--card-bg);
        box-shadow: 0 2px 8px var(--shadow);
      }
      .admin-section h2 {
        margin: 0 0 1rem;
        font-size: 1.15rem;
        letter-spacing: 0;
      }
      .admin-form-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
        gap: 0.9rem;
      }
      .admin-field {
        display: grid;
        gap: 0.375rem;
      }
      .admin-field--full {
        grid-column: 1 / -1;
      }
      .admin-field label {
        font-size: 0.8125rem;
        font-weight: 700;
        color: var(--text);
      }
      .admin-field input,
      .admin-field textarea {
        box-sizing: border-box;
        padding: 0.7rem 0.875rem;
        border: 1px solid var(--border);
        border-radius: 12px;
        background: var(--field-bg);
        color: var(--text);
        font: inherit;
        font-size: 1rem;
      }
      .admin-field input {
        height: 3rem;
      }
      .admin-field textarea {
        min-height: 5rem;
        resize: vertical;
      }
      .admin-form-actions {
        margin-top: 1rem;
      }
      .admin-table-wrap {
        overflow-x: auto;
      }
      .admin-table {
        width: 100%;
        border-collapse: collapse;
        font-size: 0.9rem;
      }
      .admin-table th,
      .admin-table td {
        padding: 0.65rem 0.5rem;
        border-bottom: 1px solid var(--border);
        text-align: left;
        vertical-align: top;
      }
      .admin-table th {
        color: var(--text-muted);
        font-size: 0.8125rem;
        font-weight: 800;
        white-space: nowrap;
      }
      .admin-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 0.35rem;
        align-items: center;
      }
      .admin-btn {
        min-height: 2.25rem;
        padding: 0 0.85rem;
        border: 1px solid var(--border);
        border-radius: 10px;
        background: var(--card-bg);
        color: var(--text);
        font: inherit;
        font-size: 0.8125rem;
        font-weight: 800;
        cursor: pointer;
      }
      .admin-btn:hover {
        border-color: rgba(232, 165, 75, 0.45);
      }
      .admin-btn--primary {
        border-color: transparent;
        background: var(--accent);
        color: var(--button-text);
      }
      .admin-btn--danger {
        border-color: rgba(200, 60, 60, 0.45);
        color: #c83c3c;
      }
      .admin-select {
        min-height: 2.25rem;
        padding: 0 0.5rem;
        border: 1px solid var(--border);
        border-radius: 10px;
        background: var(--field-bg);
        color: var(--text);
        font: inherit;
        font-size: 0.8125rem;
      }
      .admin-muted {
        color: var(--text-muted);
        font-size: 0.8125rem;
      }
      .admin-status {
        display: inline-flex;
        align-items: center;
        padding: 0.15rem 0.55rem;
        border-radius: 999px;
        background: var(--accent-soft);
        color: var(--accent);
        font-size: 0.75rem;
        font-weight: 800;
      }
    </style>
</head>
<body>
    <jsp:include page="/WEB-INF/views/header.jsp"/>
    <main class="admin-page">
        <section class="admin-hero" aria-labelledby="jam-admin-title">
            <p class="admin-hero__eyebrow">JAM ADMIN</p>
            <h1 id="jam-admin-title">게임잼 관리</h1>
            <p>게임잼을 생성하고 상태 전이, 가시성, 삭제를 관리합니다. 실제 권한 검증은 서버에서 수행됩니다.</p>
        </section>

        <section class="admin-section" aria-labelledby="jam-create-title">
            <h2 id="jam-create-title">신규 게임잼 생성</h2>
            <form id="jam-create-form" action="<%= ctx %>/admin/jams" method="post" autocomplete="off">
                <input type="hidden" name="_csrf" value="<%= csrfTokenHtml %>" />
                <div class="admin-form-grid">
                    <div class="admin-field admin-field--full">
                        <label for="jam-title">제목 (필수)</label>
                        <input type="text" id="jam-title" name="title" placeholder="게임잼 제목" required />
                    </div>
                    <div class="admin-field admin-field--full">
                        <label for="jam-description">설명</label>
                        <textarea id="jam-description" name="description" placeholder="게임잼 설명"></textarea>
                    </div>
                    <div class="admin-field">
                        <label for="jam-recruit-start">모집 시작 (ISO)</label>
                        <input type="datetime-local" id="jam-recruit-start" name="recruitStartAt" />
                    </div>
                    <div class="admin-field">
                        <label for="jam-dev-start">개발 시작 (ISO)</label>
                        <input type="datetime-local" id="jam-dev-start" name="devStartAt" />
                    </div>
                    <div class="admin-field">
                        <label for="jam-eval-start">평가 시작 (ISO)</label>
                        <input type="datetime-local" id="jam-eval-start" name="evalStartAt" />
                    </div>
                    <div class="admin-field">
                        <label for="jam-eval-end">평가 종료 (ISO)</label>
                        <input type="datetime-local" id="jam-eval-end" name="evalEndAt" />
                    </div>
                    <div class="admin-field admin-field--full">
                        <label for="jam-discord-url">Discord URL</label>
                        <input type="text" id="jam-discord-url" name="discordUrl" placeholder="https://discord.gg/..." />
                    </div>
                    <div class="admin-field admin-field--full">
                        <label for="jam-prize-info">시상 정보</label>
                        <textarea id="jam-prize-info" name="prizeInfo" placeholder="시상 정보"></textarea>
                    </div>
                    <div class="admin-field admin-field--full">
                        <label for="jam-sponsor-info">후원 정보</label>
                        <textarea id="jam-sponsor-info" name="sponsorInfo" placeholder="후원 정보"></textarea>
                    </div>
                </div>
                <div class="admin-form-actions">
                    <button class="admin-btn admin-btn--primary" type="submit">게임잼 생성</button>
                </div>
            </form>
        </section>

        <section class="admin-section" aria-labelledby="jam-list-title">
            <h2 id="jam-list-title">게임잼 목록</h2>
            <div class="admin-table-wrap">
                <table class="admin-table">
                    <thead>
                        <tr>
                            <th scope="col">제목</th>
                            <th scope="col">슬러그</th>
                            <th scope="col">상태</th>
                            <th scope="col">가시성</th>
                            <th scope="col">생성일</th>
                            <th scope="col">액션</th>
                        </tr>
                    </thead>
                    <tbody>
                        <%
                            if (jams == null || jams.isEmpty()) {
                        %>
                        <tr>
                            <td colspan="6"><span class="admin-muted">등록된 잼이 없습니다.</span></td>
                        </tr>
                        <%
                            } else {
                                for (JamData jam : jams) {
                                    if (jam == null || jam.getId() == null) {
                                        continue;
                                    }
                                    String jamId = String.valueOf(jam.getId());
                                    String jamIdAttr = HtmlUtils.htmlEscape(jamId);
                                    String jamTitle = HtmlUtils.htmlEscape(jam.getTitle() == null || jam.getTitle().isBlank() ? "(제목 없음)" : jam.getTitle());
                                    String jamSlug = HtmlUtils.htmlEscape(jam.getSlug() == null || jam.getSlug().isBlank() ? "-" : jam.getSlug());
                                    String rawStatus = jam.getStatus() == null ? "" : jam.getStatus();
                                    String jamStatus = HtmlUtils.htmlEscape(rawStatus.isBlank() ? "-" : rawStatus);
                                    boolean visible = Boolean.TRUE.equals(jam.getIsVisible());
                                    String jamCreatedAt = HtmlUtils.htmlEscape(jam.getCreatedAt() == null ? "-" : String.valueOf(jam.getCreatedAt()));
                        %>
                        <tr>
                            <td><%= jamTitle %></td>
                            <td><%= jamSlug %></td>
                            <td><span class="admin-status"><%= jamStatus %></span></td>
                            <td><%= visible ? "공개" : "비공개" %></td>
                            <td><%= jamCreatedAt %></td>
                            <td>
                                <div class="admin-actions">
                                    <select class="admin-select" data-status-select="<%= jamIdAttr %>" aria-label="전이 대상 상태">
                                        <option value="RECRUIT"<%= "RECRUIT".equals(rawStatus) ? " selected" : "" %>>RECRUIT</option>
                                        <option value="DEV"<%= "DEV".equals(rawStatus) ? " selected" : "" %>>DEV</option>
                                        <option value="EVAL"<%= "EVAL".equals(rawStatus) ? " selected" : "" %>>EVAL</option>
                                        <option value="CLOSED"<%= "CLOSED".equals(rawStatus) ? " selected" : "" %>>CLOSED</option>
                                    </select>
                                    <button class="admin-btn" type="button"
                                            data-action="status"
                                            data-jam-id="<%= jamIdAttr %>">전이</button>
                                    <button class="admin-btn" type="button"
                                            data-action="visibility"
                                            data-jam-id="<%= jamIdAttr %>"><%= visible ? "비공개로" : "공개로" %></button>
                                    <button class="admin-btn admin-btn--danger" type="button"
                                            data-action="delete"
                                            data-jam-id="<%= jamIdAttr %>">삭제</button>
                                    <button class="admin-btn" type="button"
                                            data-action="judges"
                                            data-jam-id="<%= jamIdAttr %>">심사위원</button>
                                </div>
                            </td>
                        </tr>
                        <%
                                }
                            }
                        %>
                    </tbody>
                </table>
            </div>
        </section>

        <section class="admin-section" id="jam-judges-section" aria-labelledby="jam-judges-title" style="display:none">
            <h2 id="jam-judges-title">심사위원 관리 — 잼 #<span id="jam-judges-jam-id"></span></h2>
            <form id="jam-judge-assign-form" autocomplete="off">
                <input type="hidden" name="_csrf" value="<%= csrfTokenHtml %>" />
                <div class="admin-form-grid">
                    <div class="admin-field">
                        <label for="jam-judge-user-id">심사위원 사용자 ID (필수)</label>
                        <input type="number" id="jam-judge-user-id" name="userId" min="1" step="1" placeholder="사용자 ID" />
                    </div>
                </div>
                <div class="admin-form-actions">
                    <button class="admin-btn admin-btn--primary" type="button" data-action="judge-assign">심사위원 지정</button>
                </div>
            </form>
            <div class="admin-table-wrap">
                <table class="admin-table">
                    <thead>
                        <tr>
                            <th scope="col">사용자 ID</th>
                            <th scope="col">표시 이름</th>
                            <th scope="col">지정자</th>
                            <th scope="col">지정일</th>
                            <th scope="col">액션</th>
                        </tr>
                    </thead>
                    <tbody id="jam-judge-list">
                        <tr>
                            <td colspan="5"><span class="admin-muted">잼을 선택하면 심사위원이 표시됩니다.</span></td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </section>
    </main>
    <jsp:include page="/WEB-INF/views/footer.jsp"/>
    <script>
(function () {
  var ctx = '<%= ctx %>';
  var CSRF_TOKEN = '<%= csrfTokenJs %>';

  function notify(message) {
    if (window.BibimbapModal && typeof window.BibimbapModal.alert === 'function') {
      window.BibimbapModal.alert({ title: '게임잼 관리', message: message });
      return;
    }
    alert(message);
  }

  function post(url, params) {
    var options = {
      method: 'POST',
      headers: {
        'X-CSRF-Token': CSRF_TOKEN,
        'Accept': 'application/json'
      }
    };
    if (params) {
      options.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
      options.body = params.toString();
    }
    return fetch(url, options);
  }

  function handleResult(res) {
    if (res.ok) {
      window.location.reload();
      return;
    }
    notify('요청을 처리하지 못했습니다. (상태 ' + res.status + ')');
  }

  function handleError() {
    notify('요청 중 오류가 발생했습니다.');
  }

  function transitionStatus(jamId) {
    var select = document.querySelector('[data-status-select="' + jamId + '"]');
    var toStatus = select ? select.value : '';
    if (!toStatus) {
      notify('전이할 상태를 선택해 주세요.');
      return;
    }
    var params = new URLSearchParams();
    params.set('toStatus', toStatus);
    post(ctx + '/admin/jams/' + encodeURIComponent(jamId) + '/status', params)
      .then(handleResult)
      .catch(handleError);
  }

  function toggleVisibility(jamId) {
    post(ctx + '/admin/jams/' + encodeURIComponent(jamId) + '/visibility')
      .then(handleResult)
      .catch(handleError);
  }

  function removeJam(jamId) {
    post(ctx + '/admin/jams/' + encodeURIComponent(jamId) + '/delete')
      .then(handleResult)
      .catch(handleError);
  }

  var selectedJudgeJamId = null;

  function cell(text) {
    var td = document.createElement('td');
    td.textContent = String(text == null ? '-' : text);
    return td;
  }

  function renderJudges(jamId, judges) {
    var tbody = document.getElementById('jam-judge-list');
    if (!tbody) {
      return;
    }
    while (tbody.firstChild) {
      tbody.removeChild(tbody.firstChild);
    }
    if (!Array.isArray(judges) || judges.length === 0) {
      var emptyRow = document.createElement('tr');
      var emptyCell = document.createElement('td');
      emptyCell.setAttribute('colspan', '5');
      var emptySpan = document.createElement('span');
      emptySpan.className = 'admin-muted';
      emptySpan.textContent = '지정된 심사위원이 없습니다.';
      emptyCell.appendChild(emptySpan);
      emptyRow.appendChild(emptyCell);
      tbody.appendChild(emptyRow);
      return;
    }
    judges.forEach(function (judge) {
      var userId = judge ? judge.userId : null;
      var tr = document.createElement('tr');
      tr.appendChild(cell(userId));
      tr.appendChild(cell(judge ? judge.displayName : null));
      tr.appendChild(cell(judge ? judge.assignedBy : null));
      tr.appendChild(cell(judge ? judge.createdAt : null));

      var actionTd = document.createElement('td');
      var removeBtn = document.createElement('button');
      removeBtn.type = 'button';
      removeBtn.className = 'admin-btn admin-btn--danger';
      removeBtn.textContent = '해제';
      removeBtn.setAttribute('data-action', 'judge-remove');
      removeBtn.setAttribute('data-jam-id', String(jamId));
      removeBtn.setAttribute('data-user-id', String(userId == null ? '' : userId));
      actionTd.appendChild(removeBtn);
      tr.appendChild(actionTd);

      tbody.appendChild(tr);
    });
  }

  function loadJudges(jamId) {
    fetch(ctx + '/admin/jams/' + encodeURIComponent(jamId) + '/judges', {
      headers: { 'Accept': 'application/json' }
    })
      .then(function (res) {
        if (!res.ok) {
          throw new Error('status ' + res.status);
        }
        return res.json();
      })
      .then(function (data) {
        renderJudges(jamId, data ? data.judges : []);
      })
      .catch(function () {
        notify('심사위원 목록을 불러오지 못했습니다.');
      });
  }

  function openJudges(jamId) {
    selectedJudgeJamId = jamId;
    var section = document.getElementById('jam-judges-section');
    if (section) {
      section.style.display = '';
    }
    var label = document.getElementById('jam-judges-jam-id');
    if (label) {
      label.textContent = String(jamId);
    }
    loadJudges(jamId);
  }

  function assignJudge() {
    if (!selectedJudgeJamId) {
      notify('먼저 잼 목록에서 심사위원을 누르세요.');
      return;
    }
    var input = document.getElementById('jam-judge-user-id');
    var userId = input ? input.value.trim() : '';
    if (!userId) {
      notify('지정할 사용자 ID를 입력해 주세요.');
      return;
    }
    var jamId = selectedJudgeJamId;
    var params = new URLSearchParams();
    params.set('userId', userId);
    post(ctx + '/admin/jams/' + encodeURIComponent(jamId) + '/judges', params)
      .then(function (res) {
        if (!res.ok) {
          notify('심사위원 지정에 실패했습니다. (상태 ' + res.status + ')');
          return;
        }
        if (input) {
          input.value = '';
        }
        loadJudges(jamId);
      })
      .catch(handleError);
  }

  function removeJudge(jamId, userId) {
    post(ctx + '/admin/jams/' + encodeURIComponent(jamId) + '/judges/' + encodeURIComponent(userId) + '/remove')
      .then(function (res) {
        if (!res.ok) {
          notify('심사위원 해제에 실패했습니다. (상태 ' + res.status + ')');
          return;
        }
        loadJudges(jamId);
      })
      .catch(handleError);
  }

  // data-* 속성 + 위임 핸들러 (inline 핸들러에 사용자 데이터 삽입 금지)
  document.addEventListener('click', function (ev) {
    var btn = ev.target.closest('[data-action]');
    if (!btn) {
      return;
    }
    var action = btn.getAttribute('data-action');
    if (action === 'judge-assign') {
      assignJudge();
      return;
    }
    var jamId = btn.getAttribute('data-jam-id');
    if (!jamId) {
      return;
    }
    if (action === 'status') {
      transitionStatus(jamId);
    } else if (action === 'visibility') {
      toggleVisibility(jamId);
    } else if (action === 'delete') {
      removeJam(jamId);
    } else if (action === 'judges') {
      openJudges(jamId);
    } else if (action === 'judge-remove') {
      var userId = btn.getAttribute('data-user-id');
      if (userId) {
        removeJudge(jamId, userId);
      }
    }
  });
})();
    </script>
</body>
</html>
