<script setup lang="ts">
import { ref, onMounted } from 'vue';
import DataTable from 'primevue/datatable';
import Column from 'primevue/column';
import Tag from 'primevue/tag';
import Button from 'primevue/button';
import DatePicker from 'primevue/datepicker';
import Select from 'primevue/select';
import BasePageHeader from '@/core/components/BasePageHeader.vue';
import { timesheetService } from '../timesheet.service';
import { TIMESHEET_STATUS } from '@/core/constants/app.constants';

const loading = ref(false);
const timesheets = ref<any[]>([]);
const totalRecords = ref(0);

// Filters
const dateFrom = ref<Date | null>(null);
const dateTo = ref<Date | null>(null);
const statusFilter = ref<string | null>(null);

const statusOptions = Object.entries(TIMESHEET_STATUS).map(([value, { label }]) => ({
  value,
  label,
}));

const page = ref(0);
const rows = ref(20);

async function fetchHistory() {
  loading.value = true;
  try {
    const params: Record<string, unknown> = {
      skip: page.value * rows.value,
      limit: rows.value,
    };
    if (dateFrom.value) params.from = formatDate(dateFrom.value);
    if (dateTo.value) params.to = formatDate(dateTo.value);
    if (statusFilter.value) params.status = statusFilter.value;

    const { data } = await timesheetService.getHistory(params);
    if (data.items) {
      timesheets.value = data.items;
      totalRecords.value = data.total;
    } else if (data.content) {
      timesheets.value = data.content;
      totalRecords.value = data.totalElements ?? data.content.length;
    } else if (Array.isArray(data)) {
      timesheets.value = data;
      totalRecords.value = data.length;
    }
  } catch {
    timesheets.value = [];
  } finally {
    loading.value = false;
  }
}

function formatDate(d: Date): string {
  return d.toISOString().slice(0, 10);
}

function onPage(event: any) {
  page.value = event.page;
  rows.value = event.rows;
  fetchHistory();
}

function applyFilter() {
  page.value = 0;
  fetchHistory();
}

function clearFilter() {
  dateFrom.value = null;
  dateTo.value = null;
  statusFilter.value = null;
  page.value = 0;
  fetchHistory();
}

function getStatusLabel(status: string) {
  return TIMESHEET_STATUS[status]?.label ?? status;
}

function getStatusSeverity(status: string): string {
  return (TIMESHEET_STATUS[status]?.severity as string) ?? 'secondary';
}

onMounted(() => fetchHistory());
</script>

<template>
  <div>
    <BasePageHeader title="시수 이력" subtitle="제출 및 승인된 시수 내역을 조회합니다." />

    <div class="card">
      <!-- Filter -->
      <div class="history-filter">
        <div class="history-filter__fields">
          <div class="history-filter__field">
            <label class="text-sm">시작일</label>
            <DatePicker v-model="dateFrom" dateFormat="yy-mm-dd" placeholder="시작일" showIcon fluid />
          </div>
          <div class="history-filter__field">
            <label class="text-sm">종료일</label>
            <DatePicker v-model="dateTo" dateFormat="yy-mm-dd" placeholder="종료일" showIcon fluid />
          </div>
          <div class="history-filter__field">
            <label class="text-sm">상태</label>
            <Select
              v-model="statusFilter"
              :options="statusOptions"
              optionLabel="label"
              optionValue="value"
              placeholder="전체"
              showClear
              fluid
            />
          </div>
        </div>
        <div class="history-filter__actions">
          <Button label="조회" icon="pi pi-search" size="small" @click="applyFilter" />
          <Button label="초기화" icon="pi pi-times" size="small" severity="secondary" text @click="clearFilter" />
        </div>
      </div>

      <!-- Table -->
      <DataTable
        :value="timesheets"
        :loading="loading"
        :paginator="true"
        :rows="rows"
        :totalRecords="totalRecords"
        :lazy="true"
        :rowsPerPageOptions="[10, 20, 50]"
        dataKey="id"
        stripedRows
        size="small"
        @page="onPage"
      >
        <template #empty>
          <div style="text-align: center; padding: 2rem; color: var(--p-text-muted-color);">
            <i class="pi pi-inbox" style="font-size: 2rem;" />
            <p>시수 이력이 없습니다.</p>
          </div>
        </template>

        <Column field="weekStartDate" header="주간 시작일" sortable style="width: 130px" />
        <Column field="weekEndDate" header="주간 종료일" sortable style="width: 130px" />
        <Column field="totalHours" header="총 시수" sortable style="width: 100px">
          <template #body="{ data }">
            <strong>{{ data.totalHours?.toFixed(1) ?? '0.0' }}h</strong>
          </template>
        </Column>
        <Column field="status" header="상태" sortable style="width: 120px">
          <template #body="{ data }">
            <Tag :value="getStatusLabel(data.status)" :severity="getStatusSeverity(data.status)" />
          </template>
        </Column>
        <Column field="submittedAt" header="제출일" style="width: 160px">
          <template #body="{ data }">
            {{ data.submittedAt ? data.submittedAt.substring(0, 16).replace('T', ' ') : '-' }}
          </template>
        </Column>
        <Column header="관리" style="width: 80px">
          <template #body="{ data }">
            <router-link :to="`/timesheets?week=${data.weekStartDate}`">
              <Button icon="pi pi-eye" text rounded size="small" v-tooltip="'상세 보기'" />
            </router-link>
          </template>
        </Column>
      </DataTable>
    </div>
  </div>
</template>

<style lang="scss" scoped>
@use '@/assets/styles/variables' as *;

.history-filter {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: $space-md;
  margin-bottom: $space-lg;

  &__fields {
    display: flex;
    gap: $space-md;
    flex-wrap: wrap;
  }

  &__field {
    display: flex;
    flex-direction: column;
    gap: $space-xs;
    min-width: 160px;
  }

  &__actions {
    display: flex;
    gap: $space-sm;
  }

  @media (max-width: $bp-mobile) {
    flex-direction: column;
    align-items: stretch;

    &__fields {
      flex-direction: column;
    }

    &__actions {
      justify-content: flex-end;
    }
  }
}
</style>
