<template>
    <div class="container-xxl flex-grow-1 container-p-y">
        <div class="card">
            <div class="card-header d-flex flex-column">
                <!-- 검색창 -->
                <div class="mb-3 w-100">
                    <search-bar @update:data="search" @keyup.enter="searchOnEnter" :initKeyword="searchText" class="flex-grow-1" />
                </div>
                <div class="d-flex align-items-center" style="gap: 15px">
                    <!-- 리스트 갯수 선택 -->
                    <select class="form-select w-auto" v-model="selectedSize" @change="handleSizeChange($event)" style="margin-left: 0">
                        <option value="10">10개씩</option>
                        <option value="20">20개씩</option>
                        <option value="30">30개씩</option>
                        <option value="50">50개씩</option>
                        <option value="100">100개씩</option>
                    </select>

                    <!-- 셀렉트 박스 -->
                    <select class="form-select w-auto" v-model="selectedOrder" @change="handleSortChange($event)">
                        <option value="date">날짜</option>
                        <option value="views">조회수</option>
                    </select>

                    <!-- 공지 접기 기능 -->
                    <div class="form-check mb-0">
                        <input
                            class="form-check-input mt-1"
                            type="checkbox"
                            v-model="showNotices"
                            id="hideNotices"
                            @change="handlePageFilter()"
                        />
                        <label class="form-check-label" for="hideNotices">공지 숨기기</label>
                    </div>

                    <!-- 새 글쓰기 버튼 -->
                    <router-link to="/board/write" class="ms-auto">
                        <WriteButton />
                    </router-link>
                </div>
            </div>
            <div class="card-datatable m">
                <div class="table-responsive">
                    <table class="datatables-users table border-top dataTable dtr-column">
                        <thead>
                            <tr>
                                <th style="width: 11%" class="text-center fw-bold">번호</th>
                                <th style="width: 45%" class="text-center fw-bold">제목</th>
                                <th style="width: 10%" class="text-center fw-bold">작성자</th>
                                <th style="width: 15%" class="text-center fw-bold">작성일</th>
                                <th style="width: 9%" class="text-center fw-bold">조회수</th>
                            </tr>
                        </thead>
                        <tbody>
                            <!-- 공지사항 -->
                            <template v-if="pagination.currentPage === 1 && !showNotices">
                                <tr
                                    v-for="(notice, index) in noticeList"
                                    :key="'notice-' + index"
                                    class="bg-label-gray fw-bold"
                                    @click="goDetail(notice.id)"
                                >
                                    <td class="text-center">공지</td>
                                    <td class="cursor-pointer">
                                        <div class="d-flex align-items-center">
                                            <span class="me-1">📌</span>
                                            <span>{{ truncateTitle(notice.title) }}</span>

                                            <span v-if="notice.commentCount" class="text-danger fw-bold mx-1">
                                                [ {{ notice.commentCount }} ]
                                            </span>

                                            <i v-if="notice.img" class="bi bi-image mx-1"></i>
                                            <i
                                                v-if="Array.isArray(notice.hasAttachment) && notice.hasAttachment.length > 0"
                                                class="bi bi-paperclip"
                                            ></i>

                                            <span v-if="isNewPost(notice.rawDate)" class="box-new badge text-white ms-2 fs-tiny"> N </span>
                                        </div>
                                    </td>
                                    <td class="text-center">{{ notice.author }}</td>
                                    <td class="text-center">{{ notice.date }}</td>
                                    <td class="text-center">{{ notice.views }}</td>
                                </tr>
                            </template>
                            <!-- 일반 게시물 -->
                            <tr
                                v-for="(post, index) in generalList"
                                :key="'post-' + index"
                                class="invert-bg-white"
                                @click="goDetail(post.realId)"
                            >
                                <td class="text-center">{{ post.id }}</td>
                                <td class="cursor-pointer">
                                    <div class="d-flex align-items-center">
                                        {{ truncateTitle(post.title) }}
                                        <span v-if="post.commentCount" class="comment-count">[ {{ post.commentCount }} ]</span>
                                        <i v-if="post.img" class="bi bi-image mx-1"></i>
                                        <i
                                            v-if="Array.isArray(post.hasAttachment) && post.hasAttachment.length > 0"
                                            class="bi bi-paperclip"
                                        ></i>
                                        <span v-if="isNewPost(post.rawDate)" class="box-new badge text-white ms-2 fs-tiny">N</span>
                                    </div>
                                </td>
                                <td class="text-center">{{ post.nickname ? post.nickname : post.author }}</td>
                                <td class="text-center">{{ post.date }}</td>
                                <td class="text-center">{{ post.views }}</td>
                            </tr>
                        </tbody>
                    </table>
                    <!-- 게시물이 없을 때 -->
                    <div v-if="generalList.length === 0">
                        <p class="text-center pt-10 mt-2 mb-0 text-muted">게시물이 없습니다.</p>
                    </div>
                </div>
            </div>
            <div class="card-footer">
                <!-- 페이지네이션 -->
                <div class="row g-3">
                    <div class="mt-8">
                        <Pagination v-if="pagination.pages" v-bind="pagination" @update:currentPage="handlePageChange" />
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
    import { ref, onMounted, watch } from 'vue';
    import Pagination from '@c/pagination/Pagination.vue';
    import SearchBar from '@c/search/SearchBar.vue';
    //import { route, router } from '@/router';
    import { useRoute, useRouter } from 'vue-router';
    import WriteButton from '@c/button/WriteBtn.vue';
    import axios from '@api';
    import dayjs from 'dayjs';
    import isToday from 'dayjs/plugin/isToday';
    import isYesterday from 'dayjs/plugin/isYesterday';
    import 'bootstrap-icons/font/bootstrap-icons.css';

    dayjs.extend(isToday);
    dayjs.extend(isYesterday);

    // 데이터 초기화
    const generalList = ref([]);
    const noticeList = ref([]);
    const searchText = ref('');
    const selectedOrder = ref('date');
    const selectedSize = ref(10);
    const showNotices = ref(false);

    const router = useRouter();
    const route = useRoute();

    const pagination = ref({
        currentPage: 1,
        pages: 1,
        prePage: 0,
        nextPage: 1,
        isFirstPage: true,
        isLastPage: false,
        hasPreviousPage: false,
        hasNextPage: false,
        navigatePages: 10,
        navigatepageNums: [1],
        navigateFirstPage: 1,
        navigateLastPage: 1,
    });

    // 상세 페이지 이동
    const goDetail = id => {
        saveFilterToStorage(id);
        router.push({ name: 'BoardDetail', params: { id: id } });
    };

    const truncateTitle = title => {
        return title.length > 28 ? title.slice(0, 28) + '...' : title;
    };

    // 로컬 스토리지 필터 저장
    const saveFilterToStorage = seq => {
        const query = {
            page: 1,
            size: selectedSize.value,
            orderBy: selectedOrder.value,
            searchText: searchText.value,
            showNotice: showNotices.value,
        };

        // 목록으로 바로 보낼때 필터 유지값
        //localStorage.setItem(`boardList_${seq}`, JSON.stringify(query));
    };

    // 스토리지 초기화
    const clearFliterStorage = () => {
        Object.keys(localStorage).forEach(key => {
            if (key.startsWith('boardList_')) {
                localStorage.removeItem(key);
            }
        });
    };

    // 날짜 포맷 변환 함수 (오늘이면 HH:mm, 아니면 YYYY-MM-DD)
    const formatDate = dateString => {
        const date = dayjs(dateString);
        return date.isToday() ? date.format('HH:mm') : date.format('YYYY-MM-DD');
    };

    // 새로 올라온 게시물 여부 판단 (오늘 또는 어제 작성된 경우)
    const isNewPost = dateString => {
        const date = dayjs(dateString);
        return date.isToday() || date.isYesterday();
    };

    // 검색 처리
    const search = e => {
        searchText.value = e.trim();
        handlePageFilter();
    };

    // 정렬 변경 핸들러
    const handleSortChange = e => {
        selectedOrder.value = e.target.value;
        handlePageFilter();
    };

    // 리스트 개수 변경 핸들러
    const handleSizeChange = e => {
        selectedSize.value = e.target.value;
        handlePageFilter();
    };

    // 일반 게시물 데이터 로드
    const fetchGeneralPosts = async (page = 1, keyword = '', orderBy = 'date', size = 10) => {
        try {
            const { data } = await axios.get('board/general', {
                params: {
                    page,
                    size: size,
                    orderBy: orderBy,
                    searchKeyword: keyword,
                },
            });

            if (data?.data) {
                const totalPosts = data.data.total;
                generalList.value = data.data.list.map((post, index) => ({
                    realId: post.id,
                    id: totalPosts - (page - 1) * selectedSize.value - index,
                    title: post.title,
                    author: post.author || '익명',
                    rawDate: post.date,
                    date: formatDate(post.date), // 날짜 변환 적용
                    views: post.cnt || 0,
                    hasAttachment: post.hasAttachment,
                    nickname: post.nickname || null,
                    img: post.firstImageUrl || null,
                    commentCount: post.commentCount,
                }));

                pagination.value = {
                    ...pagination.value,
                    currentPage: data.data.pageNum,
                    pages: data.data.pages,
                    prePage: data.data.prePage,
                    nextPage: data.data.nextPage,
                    isFirstPage: data.data.isFirstPage,
                    isLastPage: data.data.isLastPage,
                    hasPreviousPage: data.data.hasPreviousPage,
                    hasNextPage: data.data.hasNextPage,
                    navigatePages: data.data.navigatePages,
                    navigatepageNums: data.data.navigatepageNums,
                    navigateFirstPage: data.data.navigateFirstPage,
                    navigateLastPage: data.data.navigateLastPage,
                };
            }
        } catch (error) {}
    };

    // 공지사항 데이터 로드
    const fetchNoticePosts = async () => {
        try {
            const { data } = await axios.get('board/notices', {
                params: { searchKeyword: searchText.value },
            });

            if (data?.data) {
                noticeList.value = data.data.map(post => ({
                    id: post.id,
                    title: post.title,
                    author: post.author || '관리자',
                    date: formatDate(post.date),
                    rawDate: post.date,
                    views: post.cnt || 0,
                    hasAttachment: post.hasAttachment,
                    img: post.firstImageUrl || null,
                    commentCount: post.commentCount,
                }));
            }
        } catch (error) {}
    };

    // Enter 키를 눌렀을 때
    const searchOnEnter = event => {
        const searchTextValue = event.target.value.trim();

        if (!searchTextValue || searchTextValue[0] === ' ') {
            return; // 검색어가 비어있거나 첫 글자가 공백이면 실행 안 함
        }

        searchText.value = searchTextValue;
        handlePageFilter();
    };

    // 페이지 변경
    const handlePageChange = page => {
        if (page !== pagination.value.currentPage) {
            handlePageFilter(page);
        }
    };

    // 페이지 이동 (검색 필터 유지)
    const handlePageFilter = (page = 1) => {
        router.push({
            path: '/board',
            query: {
                page: page,
                size: selectedSize.value,
                orderBy: selectedOrder.value,
                searchText: searchText.value,
                showNotice: showNotices.value,
            },
        });
    };

    // 페이징, 검색 필터 감지
    watch(
        () => route.query,
        newQuery => {
            pagination.currentPage = newQuery.page || 1;
            const keyword = newQuery?.searchText;
            const orderBy = newQuery?.orderBy;
            const size = newQuery?.size;

            fetchGeneralPosts(pagination.currentPage, keyword, orderBy, size);
        },
    );
    // 데이터 로드
    onMounted(() => {
        // 쿼리 파라미터에서 페이지 정보 추출
        const page = route.query?.page;
        const keyword = route.query?.searchText;
        const orderBy = route.query?.orderBy;
        const size = route.query?.size;
        const showNotice = route.query?.showNotice;

        // 필터 항목 세팅
        if (keyword) searchText.value = keyword;
        if (orderBy) selectedOrder.value = orderBy;
        if (size) selectedSize.value = size;
        if (showNotice) showNotices.value = showNotice == 'false' ? false : true;

        clearFliterStorage();
        fetchNoticePosts();
        fetchGeneralPosts(page, keyword, orderBy, size);
    });
</script>

<style scoped>
    @media (max-width: 768px) {
        .w-md-100 {
            width: 100% !important;
        }
    }
    .comment-count {
        font-size: 0.9rem;
        font-weight: bold;
        border-radius: 4px;
        padding: 2px 6px;
        position: relative;
        top: -1px;
    }
</style>
