<template>
  <section
    class="bg-white dark:bg-gray-900 flex w-full justify-center min-h-[85vh] mt-20 mb-50"
  >
    <div class="mx-auto max-w-7xl px-6 w-full py-4 items-center">
      <!-- Header & Sort -->
      <div
        class="flex justify-between pt-6 pb-4 font-bold border-b border-gray-200 dark:border-gray-700"
      >
        <span class="text-xl card-title text-gray-900 dark:text-white">{{
          title
        }}</span>

        <!-- Sort Dropdown -->
        <Listbox
          :modelValue="modelValue"
          @update:modelValue="emit('update:modelValue', $event)"
        >
          <ListboxLabel
            class="block text-sm font-medium leading-6 text-gray-900 dark:text-white"
          />
          <div class="relative">
            <ListboxButton
              class="relative w-full cursor-default rounded-md bg-white dark:bg-gray-800 py-1.5 pl-3 pr-10 text-left text-gray-900 dark:text-white shadow-sm ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:outline-none focus:ring-2 focus:ring-indigo-600 sm:text-sm sm:leading-6"
            >
              <span class="block truncate">{{ selectedSort }}</span>
              <span
                class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2"
              >
                <ChevronUpDownIcon
                  class="h-5 w-5 text-gray-400"
                  aria-hidden="true"
                />
              </span>
            </ListboxButton>

            <ListboxOptions
              class="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white dark:bg-gray-800 py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm"
            >
              <ListboxOption
                as="div"
                v-for="sortOption in sortOptions"
                :key="sortOption.sortId"
                :value="sortOption"
                v-slot="{ active, selected }"
              >
                <li
                  :class="[
                    active
                      ? 'bg-indigo-600 text-white'
                      : 'text-gray-900 dark:text-white',
                    'relative cursor-default select-none py-2 pl-3 pr-9',
                  ]"
                >
                  <span
                    :class="[
                      selected ? 'font-semibold' : 'font-normal',
                      'block truncate',
                    ]"
                  >
                    {{ sortOption.name }}
                  </span>

                  <span
                    v-if="selected"
                    :class="[
                      active ? 'text-white' : 'text-indigo-600',
                      'absolute inset-y-0 right-0 flex items-center pr-4',
                    ]"
                  >
                    <CheckIcon class="h-5 w-5" aria-hidden="true" />
                  </span>
                </li>
              </ListboxOption>
            </ListboxOptions>
          </div>
        </Listbox>
      </div>

      <!-- List Items -->
      <div>
        <LoadingSection
          :isLoading="isLoading"
          :loadingMessage="loadingMessage"
        />
      </div>
      <ol>
        <slot name="list" />
      </ol>

      <!-- Buttons -->
      <div class="flex" v-if="userRole > 4">
        <span class="ml-auto inline-flex rounded-md shadow-sm m-4">
          <!-- Toggle Delete Mode -->
          <button
            v-if="!showSelectBoxes"
            @click.prevent="emit('toggle-select-boxes')"
            class="relative -ml-px inline-flex items-center bg-white dark:bg-gray-800 px-3 py-2 text-sm font-semibold text-gray-900 dark:text-white ring-1 ring-inset ring-gray-300 dark:ring-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700 focus:z-10"
          >
            삭제
          </button>

          <!-- Confirm Delete -->
          <button
            v-else
            @click.prevent="emit('delete-selected')"
            class="relative -ml-px inline-flex items-center bg-red-500 px-3 py-2 text-sm font-semibold text-white ring-1 ring-inset ring-gray-300 hover:bg-red-700 focus:z-10"
          >
            삭제
          </button>

          <!-- Upload Button -->
          <NuxtLink
            :to="uploadRoute"
            class="relative -ml-px inline-flex items-center rounded-r-md bg-white dark:bg-gray-800 px-3 py-2 text-sm font-semibold text-gray-900 dark:text-white ring-1 ring-inset ring-gray-300 dark:ring-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700 focus:z-10"
          >
            글쓰기
          </NuxtLink>
        </span>
      </div>

      <!-- Pagination -->
      <nav class="flex mx-4 mt-8 p-3 sm:px-0">
        <div class="flex-grow md:flex-none w-24 flex justify-center">
          <button
            :disabled="currentPage === 1"
            @click="emit('prev-page')"
            class="inline-flex items-center border-b-2 border-transparent pr-1 py-4 text-base font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700 dark:hover:text-gray-300 disabled:opacity-50"
          >
            <font-awesome-icon :icon="['fas', 'angle-left']" /> 이전
          </button>
        </div>
        <div
          class="flex-grow w-20 hidden md:flex md:flex-auto md:w-10 md:justify-center"
        >
          <div v-for="pageNumber in pageNumbers" :key="pageNumber">
            <button
              class="inline-flex items-center border-b-2 border-transparent px-4 py-4 text-base font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700 dark:hover:text-gray-300 group"
              :class="{
                'font-bold border-indigo-500 text-indigo-600':
                  currentPage === pageNumber,
              }"
              :disabled="currentPage === pageNumber"
              @click="emit('go-to-page', pageNumber)"
            >
              {{ pageNumber }}
            </button>
          </div>
        </div>
        <div class="flex-grow md:flex-none w-24 flex justify-center">
          <button
            :disabled="currentPage === totalPages"
            @click="emit('next-page')"
            class="inline-flex items-center border-b-2 border-transparent pr-1 py-4 text-base font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700 dark:hover:text-gray-300 disabled:opacity-50"
          >
            다음 <font-awesome-icon :icon="['fas', 'angle-right']" />
          </button>
        </div>
      </nav>
    </div>
  </section>
</template>

<script setup lang="ts">
import {
  Listbox,
  ListboxButton,
  ListboxLabel,
  ListboxOption,
  ListboxOptions,
} from '@headlessui/vue';
import { CheckIcon, ChevronUpDownIcon } from '@heroicons/vue/20/solid';

import type { SortOption } from '@/types';
import { computed } from 'vue';
import type { Ref } from 'vue';

const props = defineProps<{
  title: string;
  modelValue: SortOption;
  sortOptions: SortOption[];
  userRole: number;
  showSelectBoxes: boolean;
  currentPage: number;
  totalPages: number;
  pageNumbers: number[];
  uploadRoute: string;
  isLoading: boolean;
  loadingMessage: string;
}>();

const selectedSort = computed(() => props.modelValue.name);

const emit = defineEmits<{
  (e: 'update:modelValue', value: SortOption): void;
  (e: 'toggle-select-boxes'): void;
  (e: 'delete-selected'): void;
  (e: 'go-to-page', pageNumber: number): void;
  (e: 'prev-page'): void;
  (e: 'next-page'): void;
}>();
</script>
