<script setup>
import { defineProps, defineEmits, ref, computed, inject, watch } from "vue";
import { twMerge } from "tailwind-merge";
import { useI18n } from "vue-i18n";
const { t } = useI18n();

/* -------------------------------------------------------------
  > 規格：
  - pageSize：每頁筆數
  - totalPages：外部可強制指定總頁數（可選）
  - dataSource：完整資料陣列（當未提供 onPageChange 時，會在內部分頁切片）
  - totalItems：顯示用總筆數（未提供則使用 dataSource.length）
  - sort：當排序變更時重算頁面
  - onPageChange(page: number)：外部受控回呼（若提供，內部不切片，只回呼）
---------------------------------------------------------------- */
const props = defineProps({
  pageSize: { type: Number, default: 10 },
  totalPages: { type: Number, default: 0 },
  onPageChange: Function,
  dataSource: { type: Array, default: () => [] },
  totalItems: Number,
  sort: { type: Object, default: null },
});

const emit = defineEmits(["page-change"]);

// 可能由上層 Table 透過 provide 注入（可選）
const current_table_data = inject("current_table_data", null);

const currentPage = ref(1);

/** 總頁數：優先用 props.totalPages；否則用 dataSource.length 推導 */
const totalPage = computed(() => {
  const ps = Math.max(1, props.pageSize || 1);
  const derived = Math.ceil((props.dataSource?.length || 0) / ps);
  return props.totalPages > 0 ? props.totalPages : derived;
});

/** 首段頁碼（總頁數>6 顯示 1..3，否則顯示 1..totalPage） */
const beforeInputPage = computed(() => (totalPage.value > 6 ? 3 : totalPage.value));

/** Input 欄位的顯示值：只有在中間區間才回填目前頁碼 */
const pageInput = computed(() => {
  if (currentPage.value > 3 && currentPage.value < totalPage.value - 2) {
    return String(currentPage.value);
  }
  return "";
});

/** 夾住頁碼到合法區間 */
const clampPage = (n) => {
  if (!Number.isFinite(n)) return 1;
  n = Math.floor(n);
  return Math.min(Math.max(n, 1), Math.max(totalPage.value, 1));
};

/** 切頁核心：外部受控就呼叫 onPageChange；否則本地切片並更新注入的資料 */
const choosePage = (page) => {
  const next = clampPage(Number(page));
  if (currentPage.value === next) return;

  currentPage.value = next;

  if (typeof props.onPageChange === "function") {
    props.onPageChange(next);
  } else {
    changePageData(next);
  }
  emit("page-change", next);
};

/** 無 onPageChange 時，內部分頁切片 */
const changePageData = (page) => {
  if (!Array.isArray(props.dataSource)) return;
  const ps = Math.max(1, props.pageSize || 1);
  const start = (page - 1) * ps;
  const end = page * ps;
  const sliced = props.dataSource.slice(start, end);
  // 有提供注入器才更新
  if (current_table_data?.updateDataSource) current_table_data.updateDataSource(sliced);
};

/** 監看資料長度、排序、每頁筆數、外部總頁數變化 */
watch(
  () => [props.dataSource?.length, props.sort, props.pageSize, props.totalPages],
  () => {
    // 當資料或設定變化，調整目前頁碼到合法範圍
    currentPage.value = clampPage(currentPage.value);

    if (typeof props.onPageChange === "function") {
      // 受控模式：直接把全量 data 丟給外面管理
      if (current_table_data?.updateDataSource)
        current_table_data.updateDataSource(props.dataSource || []);
    } else {
      // 非受控：內部切片
      changePageData(currentPage.value);
    }
  },
  { immediate: true }
);

/** 處理 input 變更：僅允許正整數 */
const handleInputChange = (e) => {
  const v = String(e.target.value || "").trim();
  const n = Number(v);
  if (!/^\d+$/.test(v) || !Number.isFinite(n)) return; // 忽略非法輸入
  choosePage(n);
};
</script>

<template>
  <div class="relative flex justify-end items-end my-5" v-if="dataSource.length > 0 || totalPage > 0">
    <!-- 上一頁 -->
    <span class="mx-1">
      <button
        type="button"
        class="prev focus:border-0 disabled:text-gray-500 hover:text-warning"
        :disabled="currentPage === 1"
        @click="choosePage(currentPage - 1)"
        aria-label="Previous page"
      >
        <font-awesome-icon :icon="['fas', 'chevron-left']" class="text-3xl" />
      </button>
    </span>

    <!-- 前三頁（或全部，若總頁數 <= 6） -->
    <ul class="flex items-center list-none">
      <li
        v-for="page in beforeInputPage"
        :key="`page${page}`"
        :class="
          twMerge(
            'w-10 h-10 mx-1 border-2 border-sub-success rounded-full flex items-center justify-center cursor-pointer select-none',
            currentPage === page ? 'bg-sub-success' : 'bg-transparent'
          )
        "
        @click="choosePage(page)"
        :aria-current="currentPage === page ? 'page' : undefined"
        role="button"
        :tabindex="0"
        @keydown.enter.prevent="choosePage(page)"
        @keydown.space.prevent="choosePage(page)"
      >
        <span class="text-white font-extrabold italic">{{ page }}</span>
      </li>
    </ul>

    <!-- 總筆數（總頁數 <= 6 顯示簡版） -->
    <span v-if="totalPage <= 6" class="absolute -bottom-8 text-base text-center">
      {{ totalItems || dataSource.length }} {{ $t('table.in_otal') }}
    </span>

    <!-- 跳頁輸入（總頁數 > 6） -->
    <label v-if="totalPage > 6" class="mx-2 relative input border-2 border-sub-success flex items-center gap-2">
      <input
        type="text"
        inputmode="numeric"
        pattern="[0-9]*"
        maxlength="6"
        class="bg-transparent h-full w-20 font-extrabold italic text-lg"
        :placeholder="t('table.skip_to')"
        :value="pageInput"
        @change="handleInputChange"
        aria-label="Go to page"
      />
      <span>
        <font-awesome-icon :icon="['fas', 'search']" class="text-xl text-sub-success" />
      </span>
      <span class="w-full text-center absolute -bottom-8 left-1/2 -translate-x-1/2 text-base">
        {{ totalItems || dataSource.length }} {{ $t('table.in_otal') }}
      </span>
    </label>

    <!-- 後三頁（倒序） -->
    <ul v-if="totalPage > 6" class="flex flex-row-reverse items-center list-none">
      <li
        v-for="(page, index) in 3"
        :key="`tail${index}`"
        :class="
          twMerge(
            'w-10 h-10 mx-1 border-2 border-sub-success rounded-full flex items-center justify-center cursor-pointer select-none',
            currentPage === (totalPage - index) ? 'bg-sub-success' : 'bg-transparent'
          )
        "
        @click.stop.prevent="choosePage(totalPage - index)"
        :aria-current="currentPage === (totalPage - index) ? 'page' : undefined"
        role="button"
        :tabindex="0"
        @keydown.enter.prevent="choosePage(totalPage - index)"
        @keydown.space.prevent="choosePage(totalPage - index)"
      >
        <span class="text-white font-extrabold italic">{{ totalPage - index }}</span>
      </li>
    </ul>

    <!-- 下一頁 -->
    <span class="mx-1">
      <button
        type="button"
        class="next focus:border-0 disabled:text-gray-500 hover:text-warning"
        :disabled="currentPage === totalPage"
        @click="choosePage(currentPage + 1)"
        aria-label="Next page"
      >
        <font-awesome-icon :icon="['fas', 'chevron-right']" class="text-3xl" />
      </button>
    </span>
  </div>
</template>
