<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
      layout:decorate="~{layout/default_layout}">

<th:block layout:fragment="head">
    <style>
        .tabs { display: flex; border-bottom: 2px solid #ddd; margin-bottom: 1.5em; flex-wrap: wrap; }
        .tab-link { padding: 10px 20px; cursor: pointer; border: 1px solid transparent; border-bottom: 0; color: #777; }
        .tab-link.active { border-color: #ddd; border-bottom-color: white; background: white; margin-bottom: -2px; font-weight: bold; color: #333; }
        .tab-content { display: none; }
        .tab-content.active { display: block; }
        .user-list, .post-list { list-style: none; padding-left: 0; }
        .user-list li, .post-list li { display: flex; justify-content: space-between; align-items: center; padding: 10px; border-bottom: 1px solid #eee; }
        .user-list li:last-child, .post-list li:last-child { border-bottom: none; }
        .button.small { margin-left: 0.5em; }
        .custom-radio {
            display: none; /* 기본 라디오 버튼 숨기기 */
        }

        .custom-label {
            position: relative;
            padding-left: 25px; /* 라벨 왼쪽에 가짜 버튼을 위한 공간 확보 */
            cursor: pointer;
            line-height: 20px;
            display: inline-block;
            color: #555; /* 라벨 텍스트 색상 */
        }

        /* 가짜 라디오 버튼 (원) 만들기 */
        .custom-label::before {
            content: '';
            position: absolute;
            left: 0;
            top: 0;
            width: 18px;
            height: 18px;
            border: 2px solid #ddd;
            border-radius: 50%; /* 원 모양 */
            background: #fff;
        }

        /* 선택되었을 때 가짜 라디오 버튼 스타일 변경 */
        .custom-radio:checked + .custom-label::before {
            border-color: #FFA500; /* 테두리 색상 변경 (사이트의 포인트 색상) */
            background: #FFA500; /* 배경 색상 채우기 */
        }

        /* 선택되었을 때 원 안에 작은 점 추가 */
        .custom-radio:checked + .custom-label::after {
            content: '';
            position: absolute;
            left: 6px;
            top: 6px;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: white;
        }
    </style>
</th:block>

<th:block layout:fragment="content">
    <section class="wrapper style1">
        <div class="container">
            <header class="major">
                <h2 th:text="${isAdmin} ? '관리자 대시보드' : (${user.user_id} + '님의 정보')"></h2>
                <p>가입일: <span th:text="${joinDate}"></span></p>
            </header>

            <div class="tabs">
                <div class="tab-link active" onclick="openTab(event, 'myInfo')">내 정보</div>
                <div class="tab-link" onclick="openTab(event, 'myPosts')">내가 쓴 글</div>
                <div class="tab-link" onclick="openTab(event, 'myComments')">내가 쓴 댓글</div>
                <div class="tab-link" onclick="openTab(event, 'myRanks')">내 게임 랭킹</div>
                <div class="tab-link" onclick="openTab(event, 'myMessages')">쪽지함</div>
                <div class="tab-link" onclick="openTab(event, 'myBookmarks')">저장한 페이지</div>

                <th:block sec:authorize="hasRole('ADMIN')">
                    <div class="tab-link" onclick="openTab(event, 'userManagement')">회원 관리</div>
                    <div class="tab-link" onclick="openTab(event, 'postManagement')">게시물 관리</div>
                    <div class="tab-link" onclick="openTab(event, 'bannerManagement')">배너 관리</div>
                    <div class="tab-link" onclick="openTab(event, 'aboutManagement')">사이트 소개 관리</div>

                </th:block>
            </div>

            <div id="myInfo" class="tab-content active">
                <div class="box">
                    <h3>기본 정보</h3>
                    <ul>
                        <li><strong>아이디:</strong> <span th:text="${user.user_id}"></span></li>
                        <li><strong>이메일:</strong> <span th:text="${user.user_email}"></span></li>
                        <li>
                            <strong>현재 권한:</strong> <span th:id="'user-role-status-' + ${user.user_id}" th:text="${user.getRole().name()}"></span>
                            <th:block th:if="${user.getRole().name() == 'READ' and !user.writePermissionRequested}">
                                <a href="javascript:requestWritePermission()" id="request-perm-btn" class="button small alt" style="margin-left: 1em;">글쓰기 권한 요청</a>
                            </th:block>
                            <span th:if="${user.writePermissionRequested}" id="request-perm-status" style="margin-left: 1em; color: #007bff;">(권한 요청 처리 중)</span>
                        </li>
                    </ul>
                </div>
            </div>

            <div id="myPosts" class="tab-content">
                <div class="box">
                    <ul class="post-list">
                        <li th:each="post : ${myPosts}">
                            <a th:href="@{'/blog/viewer/' + ${post.id}}" th:text="${post.title}">게시물 제목</a>
                            <span th:text="${#dates.format(post.modifyTime, 'yyyy-MM-dd HH:mm')}"></span>
                        </li>
                        <li th:if="${#lists.isEmpty(myPosts)}">작성한 글이 없습니다.</li>
                    </ul>
                </div>
            </div>

            <div id="myComments" class="tab-content">
                <div class="box">
                    <ul class="post-list">
                        <li th:each="comment : ${myComments}">
                            <span th:text="${comment.content}">댓글 내용</span>
                            <a th:href="@{'/blog/viewer/' + ${comment.postId} + '#comment-' + ${comment.id}}">원문보기</a>
                        </li>
                        <li th:if="${#lists.isEmpty(myComments)}">작성한 댓글이 없습니다.</li>
                    </ul>
                </div>
            </div>
            <div id="myBookmarks" class="tab-content">
                <div class="box">
                    <h4>새 페이지 저장하기</h4>
                    <div id="bookmark-form">
                        <input type="url" id="bookmark-url-input" placeholder="저장할 페이지 URL을 입력하세요" style="margin-bottom: 1em;">
                        <div id="og-preview" style="display:none; border: 1px solid #ddd; padding: 1em; margin-bottom: 1em; border-radius: 5px;">
                            <img id="og-image" src="" style="max-width: 150px; float: left; margin-right: 1em;">
                            <h5 id="og-title"></h5>
                            <p id="og-description" style="font-size: 0.9em; color: #555;"></p>
                        </div>
                        <textarea id="bookmark-comment-input" placeholder="이 페이지에 대한 나의 생각 (선택)" rows="3"></textarea>
                        <div id="visibility-selector" style="margin-top: 1em; display: flex; align-items: center; flex-wrap: wrap;">
                            <strong style="margin-right: 1.5em;">공개 범위:</strong>

                            <div style="display: flex; align-items: center; margin-right: 1.5em;">
                                <input type="radio" name="visibility" id="visibility-private" value="PRIVATE" class="custom-radio" checked>
                                <label for="visibility-private" class="custom-label">비공개</label>
                            </div>

                            <div style="display: flex; align-items: center; margin-right: 1.5em;">
                                <input type="radio" name="visibility" id="visibility-members" value="MEMBERS" class="custom-radio">
                                <label for="visibility-members" class="custom-label">회원 공개</label>
                            </div>

                            <div style="display: flex; align-items: center;">
                                <input type="radio" name="visibility" id="visibility-public" value="PUBLIC" class="custom-radio">
                                <label for="visibility-public" class="custom-label">전체 공개</label>
                            </div>
                        </div>
                        <div class="form-control-wrapper" onclick="openBookmarkCategoryPopup('new-bookmark-category-display', 'new-bookmark-category')">
                            <strong>카테고리</strong>
                            <div id="new-bookmark-category-display" class="tag-display-box">카테고리 선택</div>
                        </div>
                        <input type="hidden" id="new-bookmark-category">

                        <div class="form-control-wrapper" onclick="openBookmarkTagPopup('new-bookmark-tags-display', 'new-bookmark-tags')">
                            <strong>태그</strong>
                            <div id="new-bookmark-tags-display" class="tag-display-box">태그 선택</div>
                        </div>
                        <input type="hidden" id="new-bookmark-tags">
                        <button id="save-bookmark-btn" class="button primary" style="margin-top: 1em;">저장하기</button>
                    </div>
                </div>

                <div class="box" style="margin-top: 2em;">
                    <h4>저장된 목록</h4>
                    <div id="bookmarks-list" class="row">
                        <div class="col-12" th:if="${#lists.isEmpty(myBookmarks)}">
                            <p style="text-align: center; padding: 2em 0;">저장한 페이지가 없습니다.</p>
                        </div>

                        <div class="col-4 col-12-medium" th:each="bookmark : ${myBookmarks}" th:id="|bookmark-row-${bookmark.id}|">
                            <section class="box feature">
                                <a th:href="${bookmark.url}" target="_blank" class="image featured">
                                    <img th:src="${apiBaseUrl + bookmark.displayImageUrl}" alt="Bookmark Thumbnail" />
                                </a>
                                <div class="inner">
                                    <header>
                                        <h2 th:text="${bookmark.title ?: '제목 없음'}">카드 제목</h2>
                                        <p th:if="${!#strings.isEmpty(bookmark.userComment)}" th:text="${bookmark.userComment}">사용자 코멘트</p>
                                    </header>
                                    <p style="font-size: 0.8em; color: #888;" th:text="${#strings.abbreviate(bookmark.description, 100)}">원본 페이지 설명...</p>

                                    <div class="actions" style="margin-top: 1em; text-align: right;">
                                        <button class="button small" th:onclick="openEditBookmarkModal([[${bookmark.id}]])">수정</button>
                                        <button class="button small alt" th:onclick="deleteBookmark([[${bookmark.id}]])">삭제</button>
                                    </div>
                                </div>
                            </section>
                        </div>
                    </div>
                </div>
            </div>
            <div id="myRanks" class="tab-content">
                <div class="box">
                    <ul class="post-list">
                        <li th:if="${#lists.isEmpty(myRanks)}">플레이한 게임 기록이 없습니다.</li>
                        <li th:each="rank : ${myRanks}">
                            <div>
                                <span th:switch="${rank.gameType.name()}">
                                    <strong th:case="'GAME_2048'">2048</strong>
                                    <strong th:case="'SUDOKU'">스도쿠</strong>
                                    <strong th:case="'SPIDER'">스파이더 카드</strong>
                                    <strong th:case="'NONOGRAM'">노노그램</strong>
                                    <strong th:case="*">기타 게임</strong>
                                </span>
                                <span style="margin-left: 1em;" th:switch="${rank.gameType.name()}">
                                    <span th:case="'SUDOKU'" th:text="|기록: ${rank.primaryScore / 60}분 ${rank.primaryScore % 60}초|"></span>
                                    <span th:case="'NONOGRAM'" th:text="|기록: ${rank.primaryScore / 60}분 ${rank.primaryScore % 60}초|"></span>
                                    <span th:case="'SPIDER'" th:text="|기록: ${rank.primaryScore} moves|"></span>
                                    <span th:case="*" th:text="|점수: ${#numbers.formatInteger(rank.primaryScore, 3, 'COMMA')}|"></span>
                                </span>
                            </div>
                            <span th:text="${#temporals.format(rank.timestamp, 'yyyy-MM-dd HH:mm')}"></span>
                        </li>
                    </ul>
                </div>
            </div>
            <div id="myMessages" class="tab-content">
                <div class="box">
                    <ul class="post-list">
                        <li th:if="${#lists.isEmpty(myMessages)}">주고받은 쪽지가 없습니다.</li>
                        <li th:each="msg : ${myMessages}">
                            <div style="display: flex; align-items: center; gap: 1em;">
                                <span th:if="${msg.senderId == user.user_id}" class="tag-item" style="background: #e0f7fa;">보냄</span>
                                <span th:if="${msg.receiverId == user.user_id}" class="tag-item" style="background: #fffbe5;">받음</span>

                                <div style="min-width: 150px;">
                                    <strong th:if="${msg.senderId == user.user_id}" th:text="'To: ' + ${msg.receiverId}"></strong>
                                    <strong th:if="${msg.receiverId == user.user_id}" th:text="'From: ' + ${msg.senderId}"></strong>
                                </div>

                                <a th:href="@{/messages}" th:text="${msg.title}">쪽지 제목</a>
                            </div>
                            <span th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(msg.timestamp).atZone(T(java.time.ZoneId).systemDefault()), 'yyyy-MM-dd HH:mm')}"></span>
                        </li>
                    </ul>
                </div>
            </div>
            <div id="userManagement" class="tab-content" sec:authorize="hasRole('ADMIN')">
                <div class="box" style="border: 2px solid #e67e22; background: #fff3e0;">
                    <h4>데이터 마이그레이션 (주의!)</h4>
                    <p>
                        게시물 데이터 구조를 새 버전으로 업그레이드합니다.
                        <strong>이 작업은 시스템 전체에 영향을 미치며, 반드시 한 번만 실행해야 합니다.</strong>
                    </p>
                    <button id="run-migration-btn" class="button alt">게시물 데이터 마이그레이션 실행</button>
                    <div id="migration-result" style="margin-top: 1em; font-weight: bold;"></div>
                </div>
                <div class="box">
                    <h4>권한 요청</h4>
                    <ul id="permission-requests-list" class="user-list">
                        <li th:each="reqUser : ${permissionRequests}" th:id="'request-row-' + ${reqUser.user_id}">
                            <span>
                                <strong th:text="${reqUser.user_id}"></strong> (<span th:text="${reqUser.user_email}"></span>)
                            </span>
                            <div>
                                <button class="button small primary" th:onclick="handlePermission('[[${reqUser.user_id}]]', 'approve')">승인</button>
                                <button class="button small alt" th:onclick="handlePermission('[[${reqUser.user_id}]]', 'reject')">거절</button>
                            </div>
                        </li>
                        <li th:if="${#lists.isEmpty(permissionRequests)}">새로운 권한 요청이 없습니다.</li>
                    </ul>
                </div>
                <div class="box" style="margin-top: 2em;">
                    <h4>전체 회원</h4>
                    <ul id="all-users-list" class="user-list">
                        <li th:each="u : ${allUsers}">
                             <span>
                                <strong th:text="${u.user_id}"></strong> - 현재 권한: <span th:id="'user-role-' + ${u.user_id}" th:text="${u.getRole().name()}"></span>
                            </span>
                        </li>
                    </ul>
                </div>
            </div>

            <div id="postManagement" class="tab-content" sec:authorize="hasRole('ADMIN')">
                <div class="box">
                    <h4>최신 글 관리</h4>
                    <ul class="post-list">
                        <li th:each="post : ${allRecentPosts}" th:id="'post-row-' + ${post.id}">
                            <a th:href="@{'/blog/viewer/' + ${post.id}}" th:text="${post.title}">게시물 제목</a>
                            <div>
                                <span th:if="${post.isBlocked}" style="color: red; margin-right: 1em;">(차단됨)</span>

                                <a th:href="@{/user/admin/posts/{postId}/history(postId=${post.id})}" class="button small">히스토리</a>

                                <button th:if="${!post.isBlocked}" class="button small" th:onclick="handleContent('[[${post.id}]]', 'block')">차단</button>
                                <button th:if="${post.isBlocked}" class="button small" th:onclick="handleContent('[[${post.id}]]', 'unblock')">차단 해제</button>

                                <button class="button small alt" th:onclick="handleDeletePost('[[${post.id}]]')">삭제</button>
                            </div>
                        </li>
                    </ul>
                </div>
            </div>
            <div id="bannerManagement" class="tab-content" sec:authorize="hasRole('ADMIN')">
                <div class="box">
                    <h4>배너 이미지 관리</h4>
                    <ul class="post-list">
                        <li th:each="image : ${allImages}" th:id="'image-row-' + ${image.id}">
                            <div style="display: flex; align-items: center; gap: 1em;">
<!--                                <img th:src="${post.thumb != null and not #strings.isEmpty(post.thumb)} ? ${apiBaseUrl + post.thumb} : @{/images/pic01.jpg}" alt="Post Thumbnail" />-->
                                <img th:src="${apiBaseUrl + '/api/images/' + image.fileName + '?type=thumbnail'}" alt="Image Thumbnail" style="width: 100px; height: 60px; object-fit: cover; border-radius: 4px;"/>
                                <div>
                                    <strong th:text="${image.fileName}"></strong><br>
                                    <span th:if="${image.isBannerCandidate}" style="color: #2a9d8f; font-weight: bold;">(배너로 사용 중)</span>
                                    <span th:unless="${image.isBannerCandidate}" style="color: #888;">(배너로 사용 안 함)</span>
                                </div>
                            </div>
                            <div>
                                <button th:if="${!image.isBannerCandidate}" class="button small primary" th:onclick="handleBannerPermission('[[${image.id}]]', 'approve')">배너로 승인</button>
                                <button th:if="${image.isBannerCandidate}" class="button small alt" th:onclick="handleBannerPermission('[[${image.id}]]', 'revoke')">승인 해제</button>
                            </div>
                        </li>
                        <li th:if="${#lists.isEmpty(allImages)}">업로드된 이미지가 없습니다.</li>
                    </ul>
                </div>
            </div>
            <div id="aboutManagement" class="tab-content" sec:authorize="hasRole('ADMIN')">
                <div class="box">
                    <h4>사이트 소개글 관리</h4>
                    <p>
                        '사이트 소개' 페이지에 표시될 내용입니다. 글을 수정하면 이전 버전은 히스토리로 여기에 남게 됩니다.
                    </p>
                    <th:block th:with="latestAbout=${!#lists.isEmpty(aboutPostHistory) ? aboutPostHistory[0] : null}">
                        <a th:if="${latestAbout != null}" th:href="@{/blog/edit/{postId}(postId=${latestAbout.id})}" class="button primary">최신 소개글 수정</a>
                        <a th:if="${latestAbout == null}" th:href="@{/blog/edit(type='ABOUT_SITE')}" class="button">새 소개글 작성</a>
                    </th:block>

                    <h5 style="margin-top: 2em;">수정 히스토리</h5>
                    <ul class="post-list">
                        <li th:each="post : ${aboutPostHistory}">
                            <a th:href="@{'/blog/viewer/' + ${post.id}}" th:text="${post.title}">수정된 버전 제목</a>
                            <span th:text="|수정일: ${#dates.format(post.modifyTime, 'yyyy-MM-dd HH:mm')}|"></span>
                        </li>
                        <li th:if="${#lists.isEmpty(aboutPostHistory)}">작성된 소개글이 없습니다.</li>
                    </ul>
                </div>
            </div>

        </div>
    </section>

    <script th:inline="javascript">
        // CSRF 토큰을 meta 태그에서 읽어옴 (POST 요청 시 필요)
        const csrfToken = document.querySelector('meta[name="_csrf"]')?.getAttribute('content');
        const csrfHeader = document.querySelector('meta[name="_csrf_header"]')?.getAttribute('content');

        /**
         * 탭 클릭 시 해당 탭 콘텐츠를 보여주는 함수
         */
        function openTab(evt, tabName) {
            // 모든 탭 콘텐츠 숨기기
            document.querySelectorAll('.tab-content').forEach(tab => tab.style.display = 'none');
            // 모든 탭 링크에서 'active' 클래스 제거
            document.querySelectorAll('.tab-link').forEach(link => link.classList.remove('active'));

            // 클릭된 탭 콘텐츠 보이기
            document.getElementById(tabName).style.display = 'block';
            // 클릭된 탭 링크에 'active' 클래스 추가
            evt.currentTarget.classList.add('active');
        }

        /**
         * '글쓰기 권한 요청'을 서버에 전송하는 함수
         */
        function requestWritePermission() {
            if (!confirm('글쓰기 권한을 요청하시겠습니까? 관리자 승인 후 적용됩니다.')) return;

            fetch('/user/request-write', {
                method: 'POST',
                headers: { [csrfHeader]: csrfToken }
            })
                .then(response => {
                    if (response.ok) {
                        alert('요청이 성공적으로 접수되었습니다.');
                        // 버튼을 '처리 중' 텍스트로 변경
                        document.getElementById('request-perm-btn').style.display = 'none';
                        const statusSpan = document.getElementById('request-perm-status');
                        if(statusSpan) {
                            statusSpan.innerText = '(권한 요청 처리 중)';
                        } else {
                            // span이 없는 경우 새로 만들어 추가
                            const newStatusSpan = document.createElement('span');
                            newStatusSpan.id = 'request-perm-status';
                            newStatusSpan.innerText = '(권한 요청 처리 중)';
                            newStatusSpan.style = 'margin-left: 1em; color: #007bff;';
                            document.getElementById('request-perm-btn').parentElement.appendChild(newStatusSpan);
                        }
                    } else {
                        alert('요청에 실패했습니다. 잠시 후 다시 시도해주세요.');
                    }
                })
                .catch(error => console.error('Error:', error));
        }

        /**
         * (관리자) 사용자 권한 요청을 처리하는 함수
         * @param {string} userId - 대상 사용자 ID
         * @param {'approve' | 'reject'} action - 수행할 작업
         */
        function handlePermission(userId, action) {
            const url = `/user/${action}-writer/${userId}`;
            fetch(url, {
                method: 'POST',
                headers: { [csrfHeader]: csrfToken }
            })
                .then(response => response.json())
                .then(data => {
                    if (data && data.user_id) {
                        alert(`'${userId}'님의 권한 요청을 ${action === 'approve' ? '승인' : '거절'}했습니다.`);
                        // UI에서 해당 항목 제거
                        document.getElementById(`request-row-${userId}`).remove();
                        // 전체 사용자 목록의 권한 정보 업데이트
                        const userRoleSpan = document.getElementById(`user-role-${userId}`);
                        if (userRoleSpan) {
                            userRoleSpan.innerText = data.role.name;
                        }
                    } else {
                        alert('작업에 실패했습니다.');
                    }
                })
                .catch(error => console.error('Error:', error));
        }


        const migrationBtn = document.getElementById('run-migration-btn');
        if (migrationBtn) {
            migrationBtn.addEventListener('click', async function() {
                if (!await showConfirm('경고', '정말로 데이터 마이그레이션을 실행하시겠습니까? 이 작업은 되돌릴 수 없으며, 반드시 한 번만 실행해야 합니다.')) {
                    return;
                }

                const resultDiv = document.getElementById('migration-result');
                resultDiv.innerHTML = '마이그레이션 진행 중... 페이지를 닫지 마세요.';
                migrationBtn.disabled = true;

                try {
                    const response = await fetch('/user/admin/migrate-posts', {
                        method: 'POST',
                        headers: { [csrfHeader]: csrfToken }
                    });

                    const report = await response.json();

                    if (response.ok) {
                        resultDiv.innerHTML = `✅ 마이그레이션 성공!<br>
                    - 처리된 게시물 그룹: ${report.processedGroups}<br>
                    - 최신 글로 이전됨: ${report.latestPostsMigrated}<br>
                    - 히스토리로 이전됨: ${report.historyPostsMigrated}`;
                        resultDiv.style.color = 'green';
                    } else {
                        throw new Error(report.errors.join(', '));
                    }
                } catch (error) {
                    resultDiv.innerHTML = `❌ 마이그레이션 실패: ${error.message}`;
                    resultDiv.style.color = 'red';
                    migrationBtn.disabled = false;
                }
            });
        }

        /**
         * (관리자) 콘텐츠(게시물)를 차단하거나 해제하는 함수
         * @param {string} postId - 대상 게시물 ID
         * @param {'block' | 'unblock'} action - 수행할 작업
         */
        function handleContent(postId, action) {
            const cleanpostId = postId.replace(/^"|"$/g, '');
            const url = `/blog/post/${cleanpostId}/${action}`;
            fetch(url, {
                method: 'POST',
                headers: { [csrfHeader]: csrfToken }
            })
                .then(response => response.json())
                .then(data => {
                    if (data && data.id) {
                        alert(`게시물을 ${action === 'block' ? '차단' : '차단 해제'}했습니다.`);
                        location.reload(); // 페이지를 새로고침하여 상태 업데이트
                    } else {
                        alert('작업에 실패했습니다.');
                    }
                })
                .catch(error => console.error('Error:', error));
        }

        /**
         * (관리자) 이미지의 배너 사용 권한을 승인하거나 해제하는 함수
         * @param {string} imageId - 대상 이미지의 ID
         * @param {'approve' | 'revoke'} action - 수행할 작업
         */
        function handleBannerPermission(imageId, action) {
            const cleanImageId = imageId.replace(/^"|"$/g, '');

            // [수정] 깨끗하게 정리된 cleanImageId를 URL에 사용합니다.
            const url = `/api/images/${cleanImageId}/${action === 'approve' ? 'approve-banner' : 'revoke-banner'}`;


            fetch(url, {
                method: 'POST',
                headers: { [csrfHeader]: csrfToken }
            })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('Server returned an error.');
                    }
                    return response.json();
                })
                .then(data => {
                    if (data && data.id) {
                        alert(`이미지 상태를 성공적으로 변경했습니다.`);
                        location.reload(); // 페이지를 새로고침하여 상태(버튼, 텍스트)를 즉시 반영
                    } else {
                        alert('작업에 실패했습니다.');
                    }
                })
                .catch(error => {
                    console.error('Error:', error);
                    alert('작업 중 오류가 발생했습니다.');
                });
        }
        document.addEventListener('DOMContentLoaded', function() {
            const urlInput = document.getElementById('bookmark-url-input');
            const preview = document.getElementById('og-preview');

            let ogData = {}; // OG 파싱 결과를 저장할 변수

            // URL 입력 필드에서 포커스가 벗어났을 때(onblur) OG 정보 파싱 API 호출
            urlInput.addEventListener('blur', async function() {
                const url = this.value.trim();
                if (!url) return;

                try {
                    const response = await fetch(`/api/og/parse?url=${encodeURIComponent(url)}`);
                    if (!response.ok) throw new Error('파싱 실패');

                    ogData = await response.json();

                    // 미리보기 UI 업데이트
                    document.getElementById('og-title').textContent = ogData.title || '제목 없음';
                    document.getElementById('og-description').textContent = ogData.description || '';
                    const ogImage = document.getElementById('og-image');
                    if (ogData.thumbnailUrl) {
                        ogImage.src = ogData.thumbnailUrl;
                        ogImage.style.display = 'block';
                    } else {
                        ogImage.style.display = 'none';
                    }
                    preview.style.display = 'block';

                } catch (error) {
                    console.error(error);
                    preview.style.display = 'none';
                    alert('페이지 정보를 가져오는 데 실패했습니다. URL을 확인해주세요.');
                }
            });

            // 저장 버튼 클릭 이벤트
            document.getElementById('save-bookmark-btn').addEventListener('click', async function() {
                const comment = document.getElementById('bookmark-comment-input').value.trim();

                // [수정] 선택된 공개 범위(visibility) 값을 읽어오는 코드 추가
                const visibility = document.querySelector('input[name="visibility"]:checked').value;
                const category = document.getElementById('new-bookmark-category').value;
                const tags = document.getElementById('new-bookmark-tags').value;

                const bookmarkData = {
                    url: urlInput.value.trim(),
                    // title, description 등은 ogData에서 가져오는 것은 그대로 유지
                    title: ogData.title,
                    description: ogData.description,
                    thumbnailUrl: ogData.thumbnailUrl,
                    userComment: comment,
                    // [수정] bookmarkData 객체에 visibility 프로퍼티 추가
                    visibility: visibility,
                    category: category,
                    tags: tags
                };

                if (!bookmarkData.url) {
                    alert('URL을 입력해주세요.');
                    return;
                }

                // 서버에 북마크 저장 요청 (이하 코드는 동일)
                const response = await fetch('/user/bookmarks/save', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        [csrfHeader]: csrfToken
                    },
                    body: JSON.stringify(bookmarkData)
                });

                if (response.ok) {
                    alert('페이지가 저장되었습니다.');
                    location.reload();
                } else {
                    alert('저장에 실패했습니다.');
                }
            });
        });

        /**
         * [수정] 북마크 수정 팝업을 열고 데이터를 채우는 함수
         */
        async function openEditBookmarkModal(bookmarkId) {
            try {
                // /api/** 경로는 JWT 인증 헤더(Authorization)가 필요합니다.
                // 이는 전역 fetch 인터셉터 등에서 처리된다고 가정합니다.
                const response = await fetch(`/api/bookmarks/${bookmarkId}`,{
                    headers: {
                        'Authorization': `Bearer ${serverData.token}` // 헤더에 토큰 추가
                    },
                });
                if (!response.ok) {
                    throw new Error(`서버 응답: ${response.status}`);
                }
                const bookmark = await response.json();

                // 이 부분은 모달 요소가 없어서 실패했었습니다.
                // 이제 default_layout.html에 요소가 추가되었습니다.
                document.getElementById('edit-bookmark-id').value = bookmark.id;
                document.getElementById('edit-bookmark-title').value = bookmark.title || '';
                document.getElementById('edit-bookmark-comment').value = bookmark.userComment || '';
                document.getElementById('edit-bookmark-visibility').value = bookmark.visibility || 'PRIVATE';

                document.getElementById('edit-bookmark-category-display').innerHTML = bookmark.category ? `<span class="tag-item">${bookmark.category}</span>` : '카테고리 선택';
                document.getElementById('edit-bookmark-category').value = bookmark.category || '';

                document.getElementById('edit-bookmark-tags-display').innerHTML = (bookmark.tags || []).map(t => `<span class="tag-item">#${t}</span>`).join(' ') || '태그 선택';
                document.getElementById('edit-bookmark-tags').value = (bookmark.tags || []).join(',');

                // 공통 openPopup 함수 사용
                const dummyEl = document.createElement('div');
                dummyEl.setAttribute('to', '#bookmark-edit-popup');
                openPopup(dummyEl);

            } catch(error) {
                console.error("수정 모달 열기 실패:", error);
                showAlert('오류', '북마크 정보를 불러오는 데 실패했습니다. 로그인 상태를 확인해주세요.', 'error');
            }
        }
        /**
         * [수정] 북마크 수정 내용을 서버에 제출하는 함수
         */
        async function submitBookmarkUpdate() {
            const bookmarkId = document.getElementById('edit-bookmark-id').value;
            const tagsValue = document.getElementById('edit-bookmark-tags').value;

            const updatedData = {
                title: document.getElementById('edit-bookmark-title').value,
                userComment: document.getElementById('edit-bookmark-comment').value,
                visibility: document.getElementById('edit-bookmark-visibility').value,
                category: document.getElementById('edit-bookmark-category').value,
                tags: tagsValue ? tagsValue.split(',').map(t => t.trim()).filter(t => t) : []
            };

            try {
                const response = await fetch(`/api/bookmarks/${bookmarkId}`, {
                    method: 'PUT',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${serverData.token}` // 헤더에 토큰 추가
                    },
                    body: JSON.stringify(updatedData)
                });

                if (response.ok) {
                    showAlert('성공', '북마크 정보가 수정되었습니다.', 'success');
                    location.reload(); // 변경 사항을 확인하기 위해 페이지 새로고침
                } else {
                    const errorData = await response.text();
                    showAlert('오류', `수정에 실패했습니다: ${errorData}`, 'error');
                }
            } catch (error) {
                console.error('Error updating bookmark:', error);
                showAlert('오류', '네트워크 오류로 수정에 실패했습니다.', 'error');
            }
        }

        /**
         * [신규] 북마크를 삭제하는 함수.
         * 'deleteBookmark is not defined' 오류를 해결합니다.
         */
        async function deleteBookmark(bookmarkId) {
            // common.js의 공통 확인 모달 사용
            const confirmed = await showConfirm('삭제 확인', '이 북마크를 정말로 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.');
            if (confirmed) {
                try {
                    // /api/** 경로는 상태가 없는(stateless) JWT 인증을 사용하므로 CSRF 토큰이 필요 없습니다.
                    const response = await fetch(`/api/bookmarks/${bookmarkId}`, {
                        method: 'DELETE',
                        headers: {
                            'Authorization': `Bearer ${serverData.token}` // 헤더에 토큰 추가
                        },
                    });

                    if (response.ok) {
                        showAlert('성공', '북마크가 삭제되었습니다.', 'success');
                        // 페이지에서 삭제된 항목 제거
                        document.getElementById(`bookmark-row-${bookmarkId}`).remove();
                    } else {
                        const errorData = await response.text();
                        showAlert('오류', `삭제에 실패했습니다: ${errorData}`, 'error');
                    }
                } catch (error) {
                    console.error('Error deleting bookmark:', error);
                    showAlert('오류', '네트워크 오류로 삭제에 실패했습니다.', 'error');
                }
            }
        }



    </script>
</th:block>
</html>