<%@ 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="com.pandoli365.bibimbap.data.JamEntryData" %>
<%@ page import="com.pandoli365.bibimbap.data.JamTeamData" %>
<%@ page import="com.pandoli365.bibimbap.data.JamAwardData" %>
<%@ page import="org.springframework.web.util.HtmlUtils" %>
<%
    String ctx = request.getContextPath();
    JamData jam = (JamData) request.getAttribute("jam");
    List<JamEntryData> entries = (List<JamEntryData>) request.getAttribute("entries");
    List<JamTeamData> teams = (List<JamTeamData>) request.getAttribute("teams");
    List<JamAwardData> awardsSummary = (List<JamAwardData>) request.getAttribute("awardsSummary");
    Object rawCsrf = request.getAttribute("csrfToken");
    String csrfToken = rawCsrf == null ? "" : String.valueOf(rawCsrf);
    String csrfTokenHtml = HtmlUtils.htmlEscape(csrfToken);
    // JS 문자열 컨텍스트용: 따옴표/역슬래시/스크립트 종료 시퀀스 차단 (admin-console.jsp 동형)
    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><%= jam == null ? "게임잼" : HtmlUtils.htmlEscape(jam.getTitle()) %> | 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);
      }
      .detail-page {
        max-width: 64rem;
        margin: 0 auto;
        padding: 1.5rem max(1rem, env(safe-area-inset-left)) 3rem max(1rem, env(safe-area-inset-right));
      }
      .detail-back {
        display: inline-flex;
        align-items: center;
        gap: 0.4rem;
        min-height: 2.25rem;
        margin-bottom: 1rem;
        color: var(--text-muted);
        font-size: 0.875rem;
        font-weight: 800;
        text-decoration: none;
      }
      .detail-back:hover {
        color: var(--accent);
      }
      .detail-hero {
        margin-bottom: 1rem;
        padding: 1.5rem;
        border: 1px solid var(--border);
        border-radius: 12px;
        background: var(--card-bg);
        box-shadow: 0 2px 8px var(--shadow);
      }
      .detail-badges {
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem;
        margin-bottom: 0.85rem;
      }
      .detail-badge {
        min-height: 1.85rem;
        padding: 0 0.65rem;
        border-radius: 999px;
        display: inline-flex;
        align-items: center;
        background: var(--accent-soft);
        color: var(--accent);
        font-size: 0.75rem;
        font-weight: 900;
      }
      .detail-hero h1 {
        margin: 0;
        font-size: 2rem;
        line-height: 1.2;
        letter-spacing: 0;
      }
      .detail-hero p {
        margin: 0.65rem 0 0;
        color: var(--text-muted);
        line-height: 1.65;
      }
      .detail-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 0.6rem;
        margin-top: 1.25rem;
      }
      .detail-button {
        min-height: 2.75rem;
        padding: 0 1rem;
        border: 1px solid var(--border);
        border-radius: 10px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        background: var(--card-bg);
        color: var(--text);
        font-size: 0.9375rem;
        font-weight: 900;
        text-decoration: none;
        cursor: pointer;
      }
      .detail-button--primary {
        border-color: transparent;
        background: var(--accent);
        color: var(--button-text);
      }
      .detail-section {
        margin-bottom: 1rem;
        padding: 1.25rem;
        border: 1px solid var(--border);
        border-radius: 12px;
        background: var(--card-bg);
        box-shadow: 0 2px 8px var(--shadow);
      }
      .detail-section h2 {
        margin: 0 0 0.9rem;
        font-size: 1.1rem;
        letter-spacing: 0;
      }
      .detail-section p {
        margin: 0;
        color: var(--text-muted);
        line-height: 1.7;
      }
      .entry-grid {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
        gap: 0.85rem;
      }
      .entry-card {
        display: flex;
        flex-direction: column;
        border: 1px solid var(--border);
        border-radius: 10px;
        overflow: hidden;
        background: var(--surface);
        text-decoration: none;
        color: inherit;
      }
      .entry-card img {
        width: 100%;
        aspect-ratio: 16 / 9;
        object-fit: cover;
        background: var(--accent-soft);
      }
      .entry-card__body {
        padding: 0.75rem;
      }
      .entry-card__name {
        margin: 0;
        font-size: 0.95rem;
        font-weight: 900;
        color: var(--text);
      }
      .entry-card__meta {
        margin: 0.35rem 0 0;
        font-size: 0.8rem;
        color: var(--text-muted);
      }
      .team-list {
        margin: 0;
        padding: 0;
        list-style: none;
        display: grid;
        gap: 0.5rem;
      }
      .team-list li {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 0.6rem 0.8rem;
        border: 1px solid var(--border);
        border-radius: 8px;
        background: var(--surface);
      }
      .team-list__name {
        font-weight: 800;
        color: var(--text);
      }
      .team-list__count {
        font-size: 0.8rem;
        color: var(--text-muted);
      }
      .jam-form {
        display: grid;
        gap: 0.75rem;
      }
      .jam-form label {
        display: grid;
        gap: 0.3rem;
        font-size: 0.8rem;
        font-weight: 800;
        color: var(--text-muted);
      }
      .jam-form input {
        min-height: 2.6rem;
        padding: 0 0.7rem;
        border: 1px solid var(--border);
        border-radius: 8px;
        background: var(--field-bg);
        color: var(--text);
        font-size: 0.95rem;
        box-sizing: border-box;
      }
      .jam-form button {
        justify-self: start;
      }
      .empty-note {
        color: var(--text-muted);
        font-size: 0.9rem;
      }
      @media (max-width: 760px) {
        .detail-actions {
          flex-direction: column;
        }
        .detail-button {
          width: 100%;
          box-sizing: border-box;
        }
      }
    </style>
</head>
<body>
    <jsp:include page="/WEB-INF/views/header.jsp"/>
    <main class="detail-page">
        <a class="detail-back" href="<%= ctx %>/jams">← 게임잼 목록</a>
<%
    if (jam == null) {
%>
        <section class="detail-section">
            <p class="empty-note">잼 정보를 찾을 수 없습니다.</p>
        </section>
<%
    } else {
        String slugEsc = HtmlUtils.htmlEscape(jam.getSlug() == null ? "" : jam.getSlug());
        String status = jam.getStatus() == null ? "" : jam.getStatus();
        String description = jam.getDescription() == null ? "" : jam.getDescription();
        String discordUrl = jam.getDiscordUrl();
        String prizeInfo = jam.getPrizeInfo();
        String sponsorInfo = jam.getSponsorInfo();
%>
        <section class="detail-hero" aria-labelledby="jam-title">
            <div class="detail-badges">
<%
        if (!status.isBlank()) {
%>
                <span class="detail-badge"><%= HtmlUtils.htmlEscape(status) %></span>
<%
        }
%>
            </div>
            <h1 id="jam-title"><%= HtmlUtils.htmlEscape(jam.getTitle() == null ? "" : jam.getTitle()) %></h1>
            <p><%= description.isBlank() ? "소개가 아직 없습니다." : HtmlUtils.htmlEscape(description) %></p>
<%
        if (discordUrl != null && !discordUrl.isBlank()) {
%>
            <div class="detail-actions">
                <a class="detail-button detail-button--primary" href="<%= HtmlUtils.htmlEscape(discordUrl) %>" target="_blank" rel="noopener noreferrer">Discord 참여</a>
            </div>
<%
        }
%>
        </section>

<%
        if ((prizeInfo != null && !prizeInfo.isBlank()) || (sponsorInfo != null && !sponsorInfo.isBlank())) {
%>
        <section class="detail-section" aria-labelledby="jam-ops">
            <h2 id="jam-ops">운영 안내</h2>
<%
            if (prizeInfo != null && !prizeInfo.isBlank()) {
%>
            <p><strong>상금/시상</strong><br><%= HtmlUtils.htmlEscape(prizeInfo) %></p>
<%
            }
            if (sponsorInfo != null && !sponsorInfo.isBlank()) {
%>
            <p style="margin-top:0.75rem;"><strong>후원</strong><br><%= HtmlUtils.htmlEscape(sponsorInfo) %></p>
<%
            }
%>
        </section>
<%
        }
%>

<%
        if (awardsSummary != null && !awardsSummary.isEmpty()) {
%>
        <section class="detail-section" aria-labelledby="jam-awards">
            <h2 id="jam-awards">수상 결과</h2>
            <ul class="team-list">
<%
            for (JamAwardData award : awardsSummary) {
                if (award == null) {
                    continue;
                }
                String awardTrack = award.getAwardTrack();
                Integer awardRank = award.getRank();
                boolean isGrand = "GRAND".equals(awardTrack);
                // GRAND 트랙은 상위 순위 전부, 그 외 트랙은 1위(대상)만 요약 배지로 노출
                if (!isGrand && (awardRank == null || awardRank.intValue() != 1)) {
                    continue;
                }
                String awardGameName = award.getGameName() == null || award.getGameName().isBlank() ? "이름 없는 게임" : award.getGameName();
                String rankLabel = awardRank == null ? "" : (awardRank.intValue() + "위");
                String trackLabel = isGrand ? "종합" : (awardTrack == null || awardTrack.isBlank() ? "" : awardTrack);
%>
                <li>
                    <span class="detail-badge"><%= trackLabel.isBlank() ? "" : HtmlUtils.htmlEscape(trackLabel) + (rankLabel.isBlank() ? "" : " " + rankLabel) %></span>
                    <span class="team-list__name"><%= HtmlUtils.htmlEscape(awardGameName) %></span>
                </li>
<%
            }
%>
            </ul>
            <div class="detail-actions">
                <a class="detail-button" href="<%= ctx %>/jams/<%= HtmlUtils.htmlEscape(jam.getSlug() == null ? "" : jam.getSlug()) %>/results">전체 결과 보기</a>
            </div>
        </section>
<%
        }
%>

        <section class="detail-section" aria-labelledby="jam-entries">
            <h2 id="jam-entries">출품작</h2>
<%
        if (entries == null || entries.isEmpty()) {
%>
            <p class="empty-note">아직 출품작이 없습니다.</p>
<%
        } else {
%>
            <div class="entry-grid">
<%
            for (JamEntryData entry : entries) {
                if (entry == null) {
                    continue;
                }
                String gameName = entry.getGameName() == null || entry.getGameName().isBlank() ? "이름 없는 게임" : entry.getGameName();
                String thumbnailUrl = entry.getThumbnailUrl();
                String entrantType = entry.getEntrantType();
                String entrantName = entry.getEntrantName();
                Long gameId = entry.getGameId();
                boolean hasGameLink = gameId != null;
%>
<%
                if (hasGameLink) {
%>
                <a class="entry-card" href="<%= ctx %>/game/<%= gameId %>">
<%
                } else {
%>
                <div class="entry-card">
<%
                }
%>
<%
                if (thumbnailUrl != null && !thumbnailUrl.isBlank()) {
%>
                    <img src="<%= HtmlUtils.htmlEscape(thumbnailUrl) %>" alt="">
<%
                }
%>
                    <div class="entry-card__body">
                        <p class="entry-card__name"><%= HtmlUtils.htmlEscape(gameName) %></p>
<%
                if (entrantName != null && !entrantName.isBlank()) {
%>
                        <p class="entry-card__meta"><%= entrantType != null && !entrantType.isBlank() ? HtmlUtils.htmlEscape(entrantType) + " · " : "" %><%= HtmlUtils.htmlEscape(entrantName) %></p>
<%
                } else if (entrantType != null && !entrantType.isBlank()) {
%>
                        <p class="entry-card__meta"><%= HtmlUtils.htmlEscape(entrantType) %></p>
<%
                }
%>
                    </div>
<%
                if (hasGameLink) {
%>
                </a>
<%
                } else {
%>
                </div>
<%
                }
%>
<%
            }
%>
            </div>
<%
        }
%>
        </section>

<%
        boolean voteOpen = "EVAL".equals(status);
        boolean evalEnded = jam.getEvalEndAt() != null && java.time.OffsetDateTime.now().isAfter(jam.getEvalEndAt());
        boolean resultsPublic = "CLOSED".equals(status) || evalEnded;
%>
        <section class="detail-section" aria-labelledby="jam-vote">
            <h2 id="jam-vote">인기투표</h2>
<%
        if (entries == null || entries.isEmpty()) {
%>
            <p class="empty-note">출품작이 없습니다.</p>
<%
        } else if (voteOpen) {
%>
            <p>평가기간입니다. 마음에 드는 출품작에 투표하세요. (한 표만 행사할 수 있으며 변경·취소가 가능합니다.)</p>
            <div class="entry-grid">
<%
            for (JamEntryData entry : entries) {
                if (entry == null || entry.getGameId() == null) {
                    continue;
                }
                String voteGameName = entry.getGameName() == null || entry.getGameName().isBlank() ? "이름 없는 게임" : entry.getGameName();
%>
                <div class="entry-card">
                    <div class="entry-card__body">
                        <p class="entry-card__name"><%= HtmlUtils.htmlEscape(voteGameName) %></p>
                        <p class="entry-card__meta">
                            <button type="button" class="detail-button vote-btn" data-game-id="<%= entry.getGameId() %>">투표</button>
                        </p>
                    </div>
                </div>
<%
            }
%>
            </div>
            <div class="detail-actions">
                <button type="button" id="vote-cancel" class="detail-button">투표 취소</button>
            </div>
<%
        } else {
%>
            <p class="empty-note">투표 기간이 아닙니다.</p>
<%
        }
%>
            <div id="my-vote" class="empty-note" style="margin-top:0.75rem;"></div>
<%
        if (resultsPublic) {
%>
            <h2 style="margin-top:1.25rem;">투표 결과</h2>
            <div id="vote-results"></div>
<%
        } else {
%>
            <p class="empty-note" style="margin-top:0.75rem;">투표 결과는 평가 종료 후 공개됩니다.</p>
<%
        }
%>
        </section>

<%
        if (teams != null && !teams.isEmpty()) {
%>
        <section class="detail-section" aria-labelledby="jam-teams">
            <h2 id="jam-teams">참가 팀</h2>
            <ul class="team-list">
<%
            for (JamTeamData team : teams) {
                if (team == null) {
                    continue;
                }
                Integer memberCount = team.getMemberCount();
%>
                <li>
                    <span class="team-list__name"><%= HtmlUtils.htmlEscape(team.getName() == null ? "" : team.getName()) %></span>
                    <span class="team-list__count">멤버 <%= memberCount == null ? 0 : memberCount.intValue() %>명</span>
                </li>
<%
            }
%>
            </ul>
        </section>
<%
        }
%>

        <section class="detail-section" aria-labelledby="jam-entry-form">
            <h2 id="jam-entry-form">출품하기</h2>
            <form class="jam-form" method="post" action="<%= ctx %>/jams/<%= slugEsc %>/entries">
                <input type="hidden" name="_csrf" value="<%= csrfTokenHtml %>">
                <label>
                    게임 ID
                    <input type="number" name="gameId" min="1" required>
                </label>
                <label>
                    팀 ID (개인 출품이면 비워두세요)
                    <input type="number" name="jamTeamId" min="1">
                </label>
                <button type="submit" class="detail-button detail-button--primary">출품 등록</button>
            </form>
        </section>

        <section class="detail-section" aria-labelledby="jam-team-form">
            <h2 id="jam-team-form">팀 만들기</h2>
            <form class="jam-form" method="post" action="<%= ctx %>/jams/<%= slugEsc %>/teams">
                <input type="hidden" name="_csrf" value="<%= csrfTokenHtml %>">
                <label>
                    팀 이름
                    <input type="text" name="name" maxlength="100" required>
                </label>
                <button type="submit" class="detail-button detail-button--primary">팀 생성</button>
            </form>
        </section>

        <script>
        (function () {
            var ctx = '<%= ctx %>';
            // slug 는 JS 문자열 컨텍스트 이스케이프 후 주입, 사용 시점에 encodeURIComponent 로 경로 안전화
            var slug = '<%= jam.getSlug() == null ? "" : jam.getSlug().replace("\\", "\\\\").replace("'", "\\'").replace("<", "\\u003C").replace(">", "\\u003E").replace("\r", "").replace("\n", "") %>';
            var csrf = (document.querySelector('meta[name="_csrf"]') || {}).content || '';
            var resultsPublic = <%= resultsPublic %>;
            var base = ctx + '/jams/' + encodeURIComponent(slug) + '/vote';

            var myVoteEl = document.getElementById('my-vote');
            var resultsEl = document.getElementById('vote-results');

            function renderMyVote(votedGameId) {
                if (!myVoteEl) {
                    return;
                }
                myVoteEl.textContent = (votedGameId == null || votedGameId === undefined)
                    ? '아직 투표하지 않았습니다.'
                    : ('내가 투표한 게임 ID: ' + votedGameId);
            }

            function loadMyVote() {
                fetch(base + '/mine', { headers: { 'X-CSRF-Token': csrf }, credentials: 'same-origin' })
                    .then(function (r) { return r.ok ? r.json() : null; })
                    .then(function (data) {
                        if (data) {
                            renderMyVote(data.votedGameId);
                        }
                    })
                    .catch(function () {});
            }

            function renderResults(data) {
                if (!resultsEl) {
                    return;
                }
                resultsEl.textContent = '';
                if (!data || !data.results || data.results.length === 0) {
                    var empty = document.createElement('p');
                    empty.className = 'empty-note';
                    empty.textContent = '집계된 표가 없습니다.';
                    resultsEl.appendChild(empty);
                    return;
                }
                var list = document.createElement('ul');
                list.className = 'team-list';
                data.results.forEach(function (row) {
                    var li = document.createElement('li');
                    var name = document.createElement('span');
                    name.className = 'team-list__name';
                    name.textContent = '게임 ID ' + row.gameId;
                    var count = document.createElement('span');
                    count.className = 'team-list__count';
                    count.textContent = (row.voteCount == null ? 0 : row.voteCount) + '표';
                    li.appendChild(name);
                    li.appendChild(count);
                    list.appendChild(li);
                });
                resultsEl.appendChild(list);
                if (data.total != null) {
                    var totalEl = document.createElement('p');
                    totalEl.className = 'empty-note';
                    totalEl.style.marginTop = '0.5rem';
                    totalEl.textContent = '총 ' + data.total + '표';
                    resultsEl.appendChild(totalEl);
                }
            }

            function loadResults() {
                if (!resultsPublic || !resultsEl) {
                    return;
                }
                fetch(base + '/results', { headers: { 'X-CSRF-Token': csrf }, credentials: 'same-origin' })
                    .then(function (r) { return r.ok ? r.json() : null; })
                    .then(function (data) {
                        if (data && data.open) {
                            // 서버 기준 아직 진행 중이면 집계 미노출 (밴드왜건 회피)
                            resultsEl.textContent = '';
                            return;
                        }
                        renderResults(data);
                    })
                    .catch(function () {});
            }

            Array.prototype.forEach.call(document.querySelectorAll('.vote-btn'), function (btn) {
                btn.addEventListener('click', function () {
                    var gameId = btn.getAttribute('data-game-id');
                    if (!gameId) {
                        return;
                    }
                    fetch(base, {
                        method: 'POST',
                        headers: {
                            'X-CSRF-Token': csrf,
                            'Content-Type': 'application/x-www-form-urlencoded'
                        },
                        credentials: 'same-origin',
                        body: 'gameId=' + encodeURIComponent(gameId)
                    })
                        .then(function (r) { return r.ok ? r.json() : null; })
                        .then(function (data) {
                            if (data) {
                                renderMyVote(data.votedGameId);
                            }
                        })
                        .catch(function () {});
                });
            });

            var cancelBtn = document.getElementById('vote-cancel');
            if (cancelBtn) {
                cancelBtn.addEventListener('click', function () {
                    fetch(base, {
                        method: 'DELETE',
                        headers: { 'X-CSRF-Token': csrf },
                        credentials: 'same-origin'
                    })
                        .then(function (r) { return r.ok ? r.json() : null; })
                        .then(function (data) {
                            if (data) {
                                renderMyVote(data.votedGameId);
                            }
                        })
                        .catch(function () {});
                });
            }

            loadMyVote();
            loadResults();
        })();
        </script>
<%
    }
%>
    </main>
    <jsp:include page="/WEB-INF/views/footer.jsp"/>
</body>
</html>
