<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { onBeforeRouteLeave } from 'vue-router';
import { fetchGetProjectReportOwnerProjectOptions } from '@/service/api';
import { useAuth } from '@/hooks/business/auth';
import WorkReportCreateDialog from './shared/components/create-dialog.vue';
import WorkReportPrototypePageDialog from './shared/components/prototype-page-dialog.vue';
import WorkReportTabs from './shared/components/tabs.vue';
import {
  WORK_REPORT_PROJECT_OWNER_PERMISSION,
  WORK_REPORT_TYPE_LABEL,
  type WorkReportRow,
  type WorkReportType
} from './shared/types';
import WeeklyReportIndex from './weekly/index.vue';
import WeeklyReportApprovalRecordDialog from './weekly/modules/approval-record-dialog.vue';
import MonthlyReportIndex from './monthly/index.vue';
import MonthlyReportApprovalRecordDialog from './monthly/modules/approval-record-dialog.vue';
import ProjectReportIndex from './project/index.vue';
import ProjectReportApprovalRecordDialog from './project/modules/approval-record-dialog.vue';

defineOptions({ name: 'PersonalCenterWorkReport' });

type PageDialogMode = 'add' | 'edit' | 'detail';
type ReportListExpose = {
  reload: (page?: number) => Promise<void>;
};

const { hasAuth } = useAuth();

const activeTab = ref<WorkReportType>('weekly');
const createVisible = ref(false);
const pageDialogVisible = ref(false);
const pageDialogMode = ref<PageDialogMode>('detail');
const approvalRecordVisible = ref(false);
const currentReportType = ref<WorkReportType>('weekly');
const currentRow = ref<WorkReportRow | null>(null);
const initialPeriod = ref<{
  periodKey: string;
  periodLabel: string;
  periodStartDate: string;
  periodEndDate: string;
} | null>(null);
const initialProjectId = ref('');
const initialFlag = ref(1);
const projectOptions = ref<Api.WorkReport.Project.ProjectReportOwnerProjectOption[]>([]);

const weeklyRef = ref<ReportListExpose | null>(null);
const monthlyRef = ref<ReportListExpose | null>(null);
const projectRef = ref<ReportListExpose | null>(null);

const canShowProjectTab = computed(() => hasAuth(WORK_REPORT_PROJECT_OWNER_PERMISSION));

/** 项目选项是否加载成功（用于项目半月报列表内部判断） */
const projectOptionsLoaded = ref(false);

const visibleTabs = computed<Array<{ label: string; name: WorkReportType }>>(() => {
  const tabs: Array<{ label: string; name: WorkReportType }> = [
    { label: WORK_REPORT_TYPE_LABEL.weekly, name: 'weekly' },
    { label: WORK_REPORT_TYPE_LABEL.monthly, name: 'monthly' }
  ];

  if (canShowProjectTab.value) {
    tabs.push({ label: WORK_REPORT_TYPE_LABEL.project, name: 'project' });
  }

  return tabs;
});

const currentApprovalRecordDialogComponent = computed(() => {
  if (currentReportType.value === 'monthly') return MonthlyReportApprovalRecordDialog;
  if (currentReportType.value === 'project') return ProjectReportApprovalRecordDialog;
  return WeeklyReportApprovalRecordDialog;
});

function getListRef(reportType: WorkReportType) {
  if (reportType === 'monthly') return monthlyRef.value;
  if (reportType === 'project') return projectRef.value;
  return weeklyRef.value;
}

async function loadProjectOptions() {
  if (!canShowProjectTab.value) return;

  const { error, data } = await fetchGetProjectReportOwnerProjectOptions();
  projectOptions.value = error || !data ? [] : data;
  projectOptionsLoaded.value = !error;
}

function openCreate(reportType: WorkReportType) {
  currentReportType.value = reportType;
  createVisible.value = true;
}

function handleCreateConfirm(
  payload:
    | { reportType: 'weekly' | 'monthly'; period: typeof initialPeriod.value extends infer T ? T : never }
    | {
        reportType: 'project';
        projectId: string;
        flag: number;
        period: typeof initialPeriod.value extends infer T ? T : never;
      }
) {
  currentReportType.value = payload.reportType;
  pageDialogMode.value = 'add';
  currentRow.value = null;
  initialPeriod.value = payload.period as typeof initialPeriod.value;
  initialProjectId.value = 'projectId' in payload ? payload.projectId : '';
  initialFlag.value = 'flag' in payload ? payload.flag : 1;
  pageDialogVisible.value = true;
}

function openEdit(reportType: WorkReportType, row: WorkReportRow) {
  currentReportType.value = reportType;
  pageDialogMode.value = 'edit';
  currentRow.value = row;
  initialPeriod.value = null;
  pageDialogVisible.value = true;
}

function openDetail(reportType: WorkReportType, row: WorkReportRow) {
  currentReportType.value = reportType;
  pageDialogMode.value = 'detail';
  currentRow.value = row;
  initialPeriod.value = null;
  pageDialogVisible.value = true;
}

function openApprovalRecord(reportType: WorkReportType, row: WorkReportRow) {
  currentReportType.value = reportType;
  currentRow.value = row;
  approvalRecordVisible.value = true;
}

function handleTabChange(tab: WorkReportType) {
  activeTab.value = tab;
  getListRef(tab)?.reload(1);
}

async function reloadReport(reportType = currentReportType.value) {
  await getListRef(reportType)?.reload();
}

function handleSubmitted() {
  pageDialogVisible.value = false;
  reloadReport(currentReportType.value);
}

function closeFloatingPanels() {
  createVisible.value = false;
  pageDialogVisible.value = false;
  approvalRecordVisible.value = false;
}

onMounted(async () => {
  await loadProjectOptions();
});

onBeforeRouteLeave(() => {
  closeFloatingPanels();
});
</script>

<template>
  <div
    class="work-report-page-shell min-h-560px gap-16px overflow-hidden xl:grid xl:grid-cols-[240px_minmax(0,1fr)] lt-xl:flex lt-xl:flex-col lt-xl:overflow-auto"
  >
    <!-- 左侧：报告类型导航 -->
    <div class="flex-col-stretch gap-16px xl:min-h-0">
      <WorkReportTabs :active-tab="activeTab" :tabs="visibleTabs" @update:active-tab="handleTabChange" />
    </div>

    <!-- 右侧：搜索区 + 列表区 -->
    <div class="flex-col-stretch gap-16px xl:min-h-0">
      <WeeklyReportIndex
        v-show="activeTab === 'weekly'"
        ref="weeklyRef"
        class="flex-1-hidden"
        @create="openCreate('weekly')"
        @edit="openEdit('weekly', $event)"
        @detail="openDetail('weekly', $event)"
        @approval-record="openApprovalRecord('weekly', $event)"
      />

      <MonthlyReportIndex
        v-show="activeTab === 'monthly'"
        ref="monthlyRef"
        class="flex-1-hidden"
        @create="openCreate('monthly')"
        @edit="openEdit('monthly', $event)"
        @detail="openDetail('monthly', $event)"
        @approval-record="openApprovalRecord('monthly', $event)"
      />

      <ProjectReportIndex
        v-if="canShowProjectTab"
        v-show="activeTab === 'project'"
        ref="projectRef"
        class="flex-1-hidden"
        :project-options="projectOptions"
        :project-options-loaded="projectOptionsLoaded"
        @create="openCreate('project')"
        @edit="openEdit('project', $event)"
        @detail="openDetail('project', $event)"
        @approval-record="openApprovalRecord('project', $event)"
      />
    </div>
    <WorkReportCreateDialog
      v-model:visible="createVisible"
      :default-report-type="currentReportType"
      :project-visible="canShowProjectTab"
      :project-options="projectOptions"
      @confirm="handleCreateConfirm"
    />

    <WorkReportPrototypePageDialog
      v-model:visible="pageDialogVisible"
      :mode="pageDialogMode"
      scene="fill"
      :report-type="currentReportType"
      :row-data="currentRow"
      :initial-period="initialPeriod"
      :initial-project-id="initialProjectId"
      :initial-flag="initialFlag"
      @submitted="handleSubmitted"
    />

    <component
      :is="currentApprovalRecordDialogComponent"
      v-model:visible="approvalRecordVisible"
      :row-data="currentRow"
    />
  </div>
</template>

<style scoped>
.work-report-page-shell {
  height: 100%;
}
</style>
