<template>
  <div class="th-page task-list-view">
    <header class="page-heading">
      <div>
        <h1>{{ t('taskList.title') }}</h1>
        <p>{{ t('taskList.subtitle') }}</p>
      </div>
    </header>

    <section class="th-section filter-section">
      <div class="th-section-header">
        <h2 class="th-section-title">
          {{ t('workbench.filters') }}
        </h2>
        <button
          type="button"
          class="text-button"
          @click="resetFilters"
        >
          {{ t('workbench.reset') }}
        </button>
      </div>

      <div class="filter-grid">
        <label>
          <span>{{ t('taskList.keyword') }}</span>
          <input
            v-model="filters.keyword"
            type="search"
            :placeholder="t('taskList.keywordPlaceholder')"
            @input="resetToFirstPage"
          >
        </label>
        <label>
          <span>{{ t('taskList.taskType') }}</span>
          <select
            v-model="filters.task_type"
            name="task_type"
            @change="resetToFirstPage"
          >
            <option value="">{{ t('common.all') }}</option>
            <option value="NEW_BOOKING">{{ t('cardType.NEW_BOOKING') }}</option>
            <option value="UPDATE_BOOKING">{{ t('cardType.UPDATE_BOOKING') }}</option>
            <option value="CANCEL_BOOKING">{{ t('cardType.CANCEL_BOOKING') }}</option>
            <option value="MANUAL_REVIEW">{{ t('cardType.MANUAL_REVIEW') }}</option>
            <option value="SOURCE_MESSAGE_ONLY">{{ t('cardType.SOURCE_MESSAGE_ONLY') }}</option>
          </select>
        </label>
        <label>
          <span>{{ t('taskList.taskSubtype') }}</span>
          <select
            v-model="filters.task_subtype"
            name="task_subtype"
            @change="resetToFirstPage"
          >
            <option value="">{{ t('common.all') }}</option>
            <option value="NEW_BOOKING">{{ t('taskSubtype.NEW_BOOKING') }}</option>
            <option value="UPDATE_BOOKING">{{ t('taskSubtype.UPDATE_BOOKING') }}</option>
            <option value="CANCEL_BOOKING">{{ t('taskSubtype.CANCEL_BOOKING') }}</option>
            <option value="RATE_CHANGE">{{ t('taskSubtype.RATE_CHANGE') }}</option>
            <option value="UPDATE_STAY_DATES">{{ t('taskSubtype.UPDATE_STAY_DATES') }}</option>
            <option value="UPDATE_ROOM_TYPE">{{ t('taskSubtype.UPDATE_ROOM_TYPE') }}</option>
            <option value="UPDATE_FIX_CHARGE">{{ t('taskSubtype.UPDATE_FIX_CHARGE') }}</option>
            <option value="NEW_GROUP_BLOCK">{{ t('taskSubtype.NEW_GROUP_BLOCK') }}</option>
            <option value="NEW_FIT_RESERVATION">{{ t('taskSubtype.NEW_FIT_RESERVATION') }}</option>
            <option value="MANUAL_REVIEW">{{ t('taskSubtype.MANUAL_REVIEW') }}</option>
            <option value="S10">{{ t('taskSubtype.S10') }}</option>
            <option value="S99">{{ t('taskSubtype.S99') }}</option>
          </select>
        </label>
        <label>
          <span>{{ t('workbench.taskStatus') }}</span>
          <select
            v-model="filters.task_status"
            name="task_status"
            @change="resetToFirstPage"
          >
            <option value="">{{ t('common.all') }}</option>
            <option value="PENDING_CONFIRM">{{ t('status.PENDING_CONFIRM') }}</option>
            <option value="READY">{{ t('status.READY') }}</option>
            <option value="EXECUTING">{{ t('status.EXECUTING') }}</option>
            <option value="FAILED">{{ t('status.FAILED') }}</option>
            <option value="BLOCKED">{{ t('status.BLOCKED') }}</option>
            <option value="COMPLETED">{{ t('status.COMPLETED') }}</option>
          </select>
        </label>
        <label>
          <span>{{ t('workbench.orderStatus') }}</span>
          <select
            v-model="filters.order_status"
            name="order_status"
            @change="resetToFirstPage"
          >
            <option value="">{{ t('common.all') }}</option>
            <option value="TEMPORARY">{{ t('status.TEMPORARY') }}</option>
            <option value="ACTIVE">{{ t('status.ACTIVE') }}</option>
            <option value="ENDED">{{ t('status.ENDED') }}</option>
            <option value="LOGIC_DELETED">{{ t('status.LOGIC_DELETED') }}</option>
          </select>
        </label>
        <label>
          <span>{{ t('taskList.queueParticipation') }}</span>
          <select
            v-model="filters.queue_participation"
            name="queue_participation"
            @change="resetToFirstPage"
          >
            <option :value="undefined">{{ t('taskList.queueAll') }}</option>
            <option :value="true">{{ t('taskList.queueIncluded') }}</option>
            <option :value="false">{{ t('taskList.queueExcluded') }}</option>
          </select>
        </label>
      </div>
    </section>

    <section class="th-section table-section">
      <div class="th-section-header">
        <div>
          <h2 class="th-section-title">
            {{ t('taskList.tableTitle') }}
          </h2>
          <p class="th-muted">
            {{ t('workbench.totalPrefix') }} {{ total }} {{ t('taskList.totalSuffix') }}
          </p>
        </div>
      </div>

      <div
        v-if="loading"
        class="empty-state"
      >
        {{ t('common.loading') }}
      </div>
      <div
        v-else-if="errorMessage"
        class="empty-state empty-state--error"
      >
        {{ errorMessage }}
      </div>
      <div
        v-else-if="!tasks.length"
        class="empty-state"
      >
        {{ t('common.noData') }}
      </div>

      <div
        v-else
        class="table-wrap"
      >
        <table>
          <thead>
            <tr>
              <th>{{ t('taskList.columns.task') }}</th>
              <th>{{ t('taskList.columns.order') }}</th>
              <th>{{ t('taskList.columns.card') }}</th>
              <th>{{ t('taskList.columns.status') }}</th>
              <th>{{ t('taskList.columns.source') }}</th>
              <th>{{ t('taskList.columns.queue') }}</th>
              <th>{{ t('workbench.columns.operation') }}</th>
            </tr>
          </thead>
          <tbody>
            <tr
              v-for="task in tasks"
              :key="task.task_id"
            >
              <td>
                <strong class="th-code">#{{ task.task_id }}</strong>
                <small>{{ formatReservationTaskRouteSummary(t, task) }}</small>
              </td>
              <td>
                <template v-if="isReadonlyDiagnosticTask(task)">
                  <strong>{{ t('taskList.sourceOnlyOrderLabel') }}</strong>
                  <small>{{ t('taskList.hiddenTechnicalOrder') }}</small>
                </template>
                <template v-else>
                  <strong>{{ task.display_order_key ?? task.temporary_order_no ?? task.order_id }}</strong>
                  <small class="th-code">{{ task.order_id }}</small>
                </template>
              </td>
              <td>
                <span>{{ formatReservationTaskCardLabel(t, task) }}</span>
                <small v-if="task.result_type">{{ formatReservationResultType(t, task.result_type) }}</small>
              </td>
              <td><ReservationStatusBadge :status="task.task_status" /></td>
              <td>
                <span>{{ task.source_subject ?? t('taskList.noSourceSubject') }}</span>
                <small>{{ task.source_sender_summary ?? task.source_message_id ?? '-' }}</small>
              </td>
              <td>
                <span>{{ task.queue_sequence ?? '-' }}</span>
                <small>{{ task.can_process ? t('taskList.canProcess') : formatReservationReadonlyReason(t, task.readonly_reason_code) }}</small>
              </td>
              <td>
                <div class="row-actions">
                  <RouterLink
                    class="row-action"
                    :to="`/reservation/tasks/${task.task_id}`"
                  >
                    {{ t('taskList.viewTask') }}
                  </RouterLink>
                  <RouterLink
                    v-if="!isReadonlyDiagnosticTask(task)"
                    class="row-action"
                    :to="`/reservation/orders/${task.order_id}`"
                  >
                    {{ t('taskList.viewOrder') }}
                  </RouterLink>
                  <span
                    v-if="!task.source_message_id"
                    class="pending-link"
                  >
                    {{ t('common.endpointMissing') }}
                  </span>
                  <RouterLink
                    v-else
                    class="row-action"
                    :to="`/reservation/source-messages/${task.source_message_id}/conversation`"
                  >
                    {{ t('taskList.viewConversation') }}
                  </RouterLink>
                </div>
              </td>
            </tr>
          </tbody>
        </table>
      </div>

      <footer class="pagination-bar">
        <label class="page-size-control">
          <span>{{ t('common.pageSize') }}</span>
          <select
            v-model.number="filters.page_size"
            @change="resetToFirstPage"
          >
            <option :value="10">10</option>
            <option :value="20">20</option>
            <option :value="50">50</option>
          </select>
        </label>
        <div class="pagination-actions">
          <button
            type="button"
            class="secondary-button"
            :disabled="currentPage <= 1 || loading"
            @click="goToPage(currentPage - 1)"
          >
            {{ t('common.previousPage') }}
          </button>
          <span>{{ t('common.pageStatus', { current: currentPage, total: totalPages }) }}</span>
          <button
            type="button"
            class="secondary-button"
            :disabled="currentPage >= totalPages || loading"
            @click="goToPage(currentPage + 1)"
          >
            {{ t('common.nextPage') }}
          </button>
        </div>
      </footer>
    </section>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { RouterLink } from 'vue-router'
import { useI18n } from 'vue-i18n'

import ReservationStatusBadge from '@/components/reservation/ReservationStatusBadge.vue'
import { fetchReservationTaskList } from '@/services/reservationService'
import { useAuthStore } from '@/stores/authStore'
import type { ReservationPageResult, ReservationTaskListFilters, ReservationTaskListItem } from '@/types/reservation'
import {
  formatReservationReadonlyReason,
  formatReservationResultType,
  formatReservationTaskCardLabel,
  formatReservationTaskRouteSummary,
  isReservationReadonlyDiagnosticTask,
} from '@/utils/reservationDisplay'

const { t } = useI18n()
const authStore = useAuthStore()
const loading = ref(false)
const errorMessage = ref('')
const tasks = ref<ReservationTaskListItem[]>([])
const page = ref(createPage(1, 20, 0))
const total = computed(() => page.value.total)
const currentPage = computed(() => page.value.page_num)
const totalPages = computed(() => Math.max(1, Math.ceil(page.value.total / Math.max(page.value.page_size, 1))))
let taskListRequestSequence = 0
const filters = reactive<ReservationTaskListFilters>({
  keyword: '',
  task_type: '',
  task_subtype: '',
  task_status: '',
  order_status: '',
  queue_participation: undefined,
  page_num: 1,
  page_size: 20,
})

onMounted(() => {
  void loadTasks()
})

watch(filters, () => {
  void loadTasks()
})

watch(
  () => authStore.selectedHotelId,
  (nextHotelId, previousHotelId) => {
    if (!nextHotelId || nextHotelId === previousHotelId) {
      return
    }
    reloadTasksForHotelChange()
  },
)

async function loadTasks(): Promise<void> {
  const requestSequence = ++taskListRequestSequence
  loading.value = true
  errorMessage.value = ''
  try {
    const result = await fetchReservationTaskList({ ...filters })
    if (requestSequence !== taskListRequestSequence) {
      return
    }
    tasks.value = result.items
    page.value = result.page
  } catch (error) {
    if (requestSequence !== taskListRequestSequence) {
      return
    }
    tasks.value = []
    page.value = createPage(filters.page_num ?? 1, filters.page_size ?? 20, 0)
    errorMessage.value = error instanceof Error ? error.message : String(error)
  } finally {
    if (requestSequence === taskListRequestSequence) {
      loading.value = false
    }
  }
}

function resetFilters(): void {
  filters.keyword = ''
  filters.task_type = ''
  filters.task_subtype = ''
  filters.task_status = ''
  filters.order_status = ''
  filters.queue_participation = undefined
  filters.page_num = 1
  filters.page_size = 20
}

function resetToFirstPage(): void {
  filters.page_num = 1
}

function reloadTasksForHotelChange(): void {
  if (filters.page_num !== 1) {
    filters.page_num = 1
    return
  }
  void loadTasks()
}

function goToPage(page: number): void {
  filters.page_num = Math.min(Math.max(page, 1), totalPages.value)
}

function isReadonlyDiagnosticTask(task: ReservationTaskListItem): boolean {
  return isReservationReadonlyDiagnosticTask(task)
}

function createPage(pageNum: number, pageSize: number, total: number): ReservationPageResult {
  return {
    page_num: pageNum,
    page_size: pageSize,
    total,
  }
}
</script>

<style scoped>
.task-list-view {
  max-width: 1320px;
}

.page-heading h1,
.page-heading p {
  margin: 0;
}

.page-heading h1 {
  color: var(--th-color-slate-900);
  font-size: 28px;
}

.page-heading p {
  margin-top: 8px;
  color: var(--th-color-slate-500);
  font-size: 14px;
}

.filter-section {
  padding-bottom: 20px;
}

.filter-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  padding: 18px 20px 0;
}

.filter-grid label {
  display: grid;
  gap: 7px;
}

.filter-grid span {
  color: var(--th-color-slate-500);
  font-size: 12px;
  font-weight: 700;
}

.filter-grid input,
.filter-grid select {
  min-height: 38px;
  min-width: 0;
  border: 1px solid var(--th-color-slate-200);
  border-radius: var(--th-radius-sm);
  background: var(--th-color-white);
  color: var(--th-color-slate-900);
  padding: 8px 10px;
}

.filter-grid select:disabled {
  color: var(--th-color-slate-500);
  cursor: not-allowed;
  opacity: 0.72;
}

.filter-hint {
  color: var(--th-color-warning);
  font-size: 11px;
  font-weight: 800;
  line-height: 1.45;
}

.text-button,
.row-action {
  border: 0;
  background: transparent;
  color: var(--th-color-blue-600);
  cursor: pointer;
  font-size: 13px;
  font-weight: 800;
}

.empty-state {
  min-height: 220px;
  display: grid;
  place-items: center;
  color: var(--th-color-slate-500);
  font-size: 13px;
  padding: 24px;
}

.empty-state--error {
  color: var(--th-color-danger);
}

.table-section {
  overflow: hidden;
}

.table-wrap {
  overflow-x: auto;
  padding: 14px 20px 20px;
}

table {
  width: 100%;
  min-width: 980px;
  border-collapse: collapse;
}

th,
td {
  border-bottom: 1px solid var(--th-color-slate-200);
  padding: 14px 10px;
  text-align: left;
  vertical-align: middle;
}

th {
  color: var(--th-color-slate-500);
  font-size: 12px;
  font-weight: 800;
}

td {
  color: var(--th-color-slate-900);
  font-size: 13px;
}

td strong,
td small {
  display: block;
}

td small {
  margin-top: 4px;
  color: var(--th-color-slate-500);
  font-size: 12px;
}

.row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.pending-link {
  color: var(--th-color-slate-500);
  font-size: 12px;
  font-weight: 800;
}

.pagination-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  border-top: 1px solid var(--th-color-slate-200);
  padding: 14px 20px 18px;
}

.page-size-control,
.pagination-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.page-size-control span,
.pagination-actions span {
  color: var(--th-color-slate-500);
  font-size: 12px;
  font-weight: 800;
}

.page-size-control select {
  min-height: 34px;
  border: 1px solid var(--th-color-slate-200);
  border-radius: var(--th-radius-sm);
  background: var(--th-color-white);
  color: var(--th-color-slate-900);
  padding: 6px 8px;
}

.secondary-button {
  min-height: 34px;
  border: 1px solid var(--th-color-slate-200);
  border-radius: var(--th-radius-sm);
  background: var(--th-color-white);
  color: var(--th-color-slate-700);
  cursor: pointer;
  font-size: 12px;
  font-weight: 800;
  padding: 6px 12px;
}

.secondary-button:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

@media (max-width: 900px) {
  .filter-grid {
    grid-template-columns: 1fr;
  }

  .pagination-bar {
    align-items: flex-start;
    flex-direction: column;
  }
}
</style>
