/**
 * 2026.01.07 작성
 * 태그별 게시물 조회 JS
 */
class ProcessTags
{
    constructor() 
    {
        this.loading = false;
        this.tags = document.getElementById('tags');
        this.posts = document.getElementById('posts');
        this.pagination = document.getElementById('pagination');
    }

    setActiveTag(target)
    {
        const links = this.tags.querySelectorAll('.tag-nav-link');
        links.forEach(link => link.classList.remove('active'));
        target.classList.add('active');
    }

    updateQueryString(tag, page)
    {
        const url = new URL(window.location.href);
        
        if (tag) {
            url.searchParams.set('name', tag);
        } else { 
            url.searchParams.delete('name');
        }

        if (page > 1) {
            url.searchParams.set('page', page.toString());
        } else {
            url.searchParams.delete('page');
        }

        window.history.pushState({}, '', url.toString());
    }

    getTagFromQuery() 
    {
        return new URLSearchParams(window.location.search).get('name')?.trim();
    }

    getPageFromQuery() {
        return parseInt(new URLSearchParams(window.location.search).get('page') || '1', 10) || 1;
    }

    findLinkByTag(tag) 
    {
        if (!tag) {
            return null;
        }

        const links = this.tags.querySelectorAll('.tag-nav-link');

        for (const link of links) {
            const name = (link.dataset.name || link.textContent || '').trim();
            if (name === tag) {
                return link;
            }
        }

        return null;
    }

    async loadPosts(tag, page)
    {
        const params = new URLSearchParams({
            name: tag,
            page: page
        });

        this.updateQueryString(tag, page);

        const nav = this.findLinkByTag(tag);
        if (nav) {
            this.setActiveTag(nav);
        }

        this.posts.innerHTML = ' \
            <div class="text-center my-4"> \
                <div class="spinner-border" role="status"> \
                    <span class="visually-hidden">Loading...</span> \
                </div> \
            </div> \
        ';

        try {

            if (this.loading) {
                return;
            }

            this.loading = true;

            const res = await fetch(`${BASE_URL}/tag/posts?${params.toString()}`, {
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                    'Accept': 'application/json',
                }
            });

            if (!res.ok) {
                throw new Error();
            }

            const data = await res.json().then(r => r.data);

            this.renderPosts(data);
            this.renderPagination(data);
            
        } catch (error) {
            this.posts.innerHTML = `
                <p>
                    조회 중 오류가 발생했습니다.<br/>
                    잠시 후 다시 시도해주세요.
                </p>
            `;
        } finally {
            this.loading = false;
        }
    }

    async fetchPosts(e)
    {
	    const target = e.target.closest?.('.tag-nav-link, .tag-sub-link, .page-link');
		if (!target) {
            return;
        }

        if (target.classList.contains('active') && target.classList.contains('tag-nav-link')) {
            this.posts.innerHTML = '<div class="text-center my-4">태그를 선택하면 게시글이 조회됩니다.</div>';
            this.pagination.innerHTML = '';
            target.classList.remove('active');
            this.updateQueryString('', 0);
            return;
        }

        let tag = (target.dataset.name || target.textContent || '').trim();
        let page = 1;

        if (target.classList.contains('page-link')) {
            e.preventDefault();
            tag = this.getTagFromQuery();
            page = parseInt(target.dataset.page || '1', 10) || 1;
        }

        return this.loadPosts(tag, page);
    }

    renderPosts(res) 
    {
		if (!res || res.rows <= 0) {
			this.posts.innerHTML = '<p class="p-5 text-center">관련 게시물이 없습니다.</p>';
			return;
		}

        let html = "";
		res.list.forEach(function(item) {
            html += `
                <li class="list-group-item">
                    <div class="row align-items-center">
                        ${item.thumbnail ? `
                        <div class="col col-lg-2">
                            <a href="${BASE_URL}/board/photo/${item.id}" target="_blank" rel="noopener">
                                <img src="${item.thumbnail}" alt="${item.subject}" class="img-fluid img-thumbnail"/>
                            </a>
                        </div>
                        ` : ''}
                        <div class="${item.thumbnail ? `col col-lg-10` : 'col'}">
                            <dl class="mb-0">
                                <dt>
                                    <div class="row">
                                        <div class="col">
                                            <h4>
                                                <a href="${BASE_URL}/board/photo/${item.id}" target="_blank" rel="noopener">
                                                    ${item.subject}
                                                </a>
                                            </h4>
                                        </div>
                                        <div class="col-auto">
                                            <small>${item.createdAt}</small>
                                        </div>
                                    </div>
                                </dt>
                                <dd>
                                    <blockquote class="blockquote">
                                        ${item.content}
                                    </blockquote>
                                </dd>
                                <dd>${item.userName}</dd>
                                <dd class="mb-0">
                                    ${item.tags.map(tag => `
                                        <span class="tag-sub-link" data-name="${tag.toString().replace(/"/g, '&quot;')}">
                                            #${tag}
                                        </span>
                                    `).join(',')}
                                </dd>
                            </dl>
                        </div>
                    </div>
                    
                </li>
            `;
		});

        this.posts.innerHTML = html;
    }
    
    renderPagination(res) 
    {
        const total = parseInt(res.total || '0', 0) || 0;
        const page = parseInt(res.page || '1', 10) || 1;
        const last = Math.ceil(total / 10);

        if (last <= 1) {
            return;
        }

        const make = (p, label, disabled = false, active = false) => `
            <li class="page-item ${disabled ? 'disabled' : ''} ${active ? 'active' : ''}">
                <a class="page-link" href="#" data-page="${p}">${label}</a>
            </li>
        `;

        let html = `<hr/><nav><ul class="pagination">`;

        html += make(page - 1, '‹', page <= 1);

        // 간단히 1~last 다 찍으면 페이지 많을 때 별로라서 window 방식(최대 7개)
        const windowSize = 7;
        let start = Math.max(1, page - Math.floor(windowSize / 2));
        let end = Math.min(last, start + windowSize - 1);
        start = Math.max(1, end - windowSize + 1);

        for (let p = start; p <= end; p++) {
            html += make(p, String(p), false, p === page);
        }

        html += make(page + 1, '›', page >= last);
        html += `</ul></nav>`;

        this.pagination.innerHTML = html;
    }

    initFromUrl() 
    {
        const tag = this.getTagFromQuery();
        if (!tag) {
            return;
        }

        const link = this.findLinkByTag(tag);
        if (!link) {
            return;
        }

        // 새로고침 시 active 유지
        this.setActiveTag(link);

        // 새로고침 시 자동 조회
        this.fetchPosts({ target: link });
    }
}

document.addEventListener('DOMContentLoaded', function() 
{
    let processTags = new ProcessTags();

    if (processTags.tags) {
        processTags.tags.addEventListener('click', (e) => processTags.fetchPosts(e));
    }

    if (processTags.posts) {
        processTags.posts.addEventListener('click', (e) => processTags.fetchPosts(e));
    }

    if (processTags.pagination) {
        processTags.pagination.addEventListener('click', (e) => processTags.fetchPosts(e));
    }

    // 새로고침/직접접속 시 URL의 tag 반영
    processTags.initFromUrl();

    // 뒤로가기/앞으로가기 대응
    window.addEventListener('popstate', () => processTags.initFromUrl());
});
