<script setup lang="ts">
import { ref, onMounted } from 'vue';
import Column from 'primevue/column';
import Button from 'primevue/button';
import Tag from 'primevue/tag';
import { useToast } from 'primevue/usetoast';
import { useConfirm } from 'primevue/useconfirm';
import BasePageHeader from '@/core/components/BasePageHeader.vue';
import BaseCrudTable from '@/core/components/BaseCrudTable.vue';
import ApprovalDetailDialog from '../components/ApprovalDetailDialog.vue';
import { approvalService } from '../approval.service';
import { TIMESHEET_STATUS } from '@/core/constants/app.constants';

const toast = useToast();
const confirm = useConfirm();

const items = ref<any[]>([]);
const loading = ref(false);
const selectedItems = ref<any[]>([]);
const detailVisible = ref(false);
const detailLoading = ref(false);
const selectedApproval = ref<any>(null);

async function loadPending() {
  loading.value = true;
  try {
    const { data } = await approvalService.getPending();
    items.value = Array.isArray(data) ? data : (data as any).content ?? (data as any).items ?? [];
  } catch {
    toast.add({ severity: 'error', summary: '오류', detail: '결재 대기 목록 로드 실패', life: 5000 });
  } finally {
    loading.value = false;
  }
}

async function openDetail(row: any) {
  detailLoading.value = true;
  detailVisible.value = true;
  try {
    const { data } = await approvalService.getById(row.id);
    selectedApproval.value = data;
  } catch {
    selectedApproval.value = row;
  } finally {
    detailLoading.value = false;
  }
}

async function onApprove(comment: string) {
  if (!selectedApproval.value) return;
  detailLoading.value = true;
  try {
    await approvalService.approve(selectedApproval.value.id, comment || undefined);
    toast.add({ severity: 'success', summary: '승인', detail: '승인되었습니다.', life: 3000 });
    detailVisible.value = false;
    await loadPending();
  } catch {
    toast.add({ severity: 'error', summary: '오류', detail: '승인 실패', life: 5000 });
  } finally {
    detailLoading.value = false;
  }
}

async function onReject(comment: string) {
  if (!selectedApproval.value) return;
  if (!comment.trim()) {
    toast.add({ severity: 'warn', summary: '알림', detail: '반려 시 코멘트를 입력해주세요.', life: 3000 });
    return;
  }
  detailLoading.value = true;
  try {
    await approvalService.reject(selectedApproval.value.id, comment);
    toast.add({ severity: 'success', summary: '반려', detail: '반려 처리되었습니다.', life: 3000 });
    detailVisible.value = false;
    await loadPending();
  } catch {
    toast.add({ severity: 'error', summary: '오류', detail: '반려 실패', life: 5000 });
  } finally {
    detailLoading.value = false;
  }
}

async function batchApprove() {
  if (!selectedItems.value.length) {
    toast.add({ severity: 'warn', summary: '알림', detail: '선택된 항목이 없습니다.', life: 3000 });
    return;
  }
  confirm.require({
    message: `${selectedItems.value.length}건을 일괄 승인하시겠습니까?`,
    header: '일괄 승인',
    icon: 'pi pi-check',
    accept: async () => {
      loading.value = true;
      try {
        const ids = selectedItems.value.map((i: any) => i.id);
        await approvalService.batchApprove(ids);
        toast.add({ severity: 'success', summary: '승인', detail: `${ids.length}건 승인 완료`, life: 3000 });
        selectedItems.value = [];
        await loadPending();
      } catch {
        toast.add({ severity: 'error', summary: '오류', detail: '일괄 승인 실패', life: 5000 });
      } finally {
        loading.value = false;
      }
    },
  });
}

function statusSeverity(status: string) {
  return (TIMESHEET_STATUS as Record<string, any>)[status]?.severity ?? 'secondary';
}
function statusLabel(status: string) {
  return (TIMESHEET_STATUS as Record<string, any>)[status]?.label ?? status;
}

onMounted(loadPending);
</script>

<template>
  <div class="approval-pending-view">
    <BasePageHeader title="결재 대기" subtitle="시수 결재 요청 목록" />

    <BaseCrudTable
      :value="items"
      :loading="loading"
      :globalFilterFields="['requesterName', 'projectName', 'status']"
      selectionMode="multiple"
    >
      <template #toolbar-left>
        <Button label="일괄 승인" icon="pi pi-check-circle" severity="success" size="small" @click="batchApprove" />
      </template>

      <Column selectionMode="multiple" style="width: 40px" />
      <Column field="requesterName" header="요청자" sortable style="min-width: 100px" />
      <Column field="projectName" header="프로젝트" sortable style="min-width: 140px" />
      <Column header="기간" style="min-width: 180px">
        <template #body="{ data }">
          {{ data.weekStartDate ?? '-' }} ~ {{ data.weekEndDate ?? '-' }}
        </template>
      </Column>
      <Column field="totalHours" header="총시수" sortable style="min-width: 80px">
        <template #body="{ data }">{{ data.totalHours ?? 0 }}h</template>
      </Column>
      <Column field="status" header="상태" sortable style="min-width: 90px">
        <template #body="{ data }">
          <Tag :value="statusLabel(data.status)" :severity="statusSeverity(data.status)" />
        </template>
      </Column>
      <Column field="submittedAt" header="제출일" sortable style="min-width: 120px" />
      <Column header="" style="width: 80px">
        <template #body="{ data }">
          <Button icon="pi pi-eye" text rounded severity="info" @click="openDetail(data)" />
        </template>
      </Column>
    </BaseCrudTable>

    <ApprovalDetailDialog
      :visible="detailVisible"
      :approval="selectedApproval"
      :loading="detailLoading"
      @update:visible="detailVisible = $event"
      @approve="onApprove"
      @reject="onReject"
    />
  </div>
</template>
