/**
 * 文件职责：发票管理页面状态与动作编排。
 */
import type {
  FinanceInvoiceIssueResultDto,
  FinanceInvoiceRecordDetailDto,
  FinanceInvoiceRecordListItemDto,
  FinanceInvoiceStatsDto,
} from '#/api/finance';
import type {
  FinanceInvoiceFilterState,
  FinanceInvoiceIssueFormState,
  FinanceInvoicePaginationState,
  FinanceInvoiceSettingFormState,
  FinanceInvoiceTabKey,
  FinanceInvoiceVoidFormState,
} from '../types';

import { computed, onActivated, onMounted, reactive, ref, watch } from 'vue';

import { useAccessStore } from '@vben/stores';

import { message } from 'ant-design-vue';

import {
  createDefaultFilters,
  createDefaultIssueForm,
  createDefaultPagination,
  createDefaultSettingsForm,
  createDefaultVoidForm,
  DEFAULT_INVOICE_STATS,
  FINANCE_INVOICE_ISSUE_PERMISSION,
  FINANCE_INVOICE_SETTINGS_PERMISSION,
  FINANCE_INVOICE_VIEW_PERMISSION,
  FINANCE_INVOICE_VOID_PERMISSION,
  INVOICE_TAB_OPTIONS,
} from './invoice-page/constants';
import { createDataActions } from './invoice-page/data-actions';
import { createDrawerActions } from './invoice-page/drawer-actions';
import { isDateRangeInvalid } from './invoice-page/helpers';
import { createSettingsActions } from './invoice-page/settings-actions';

/** 创建发票管理页面组合状态。 */
export function useFinanceInvoicePage() {
  const accessStore = useAccessStore();

  const activeTab = ref<FinanceInvoiceTabKey>('records');

  const filters = reactive<FinanceInvoiceFilterState>(
    createDefaultFilters() as FinanceInvoiceFilterState,
  );
  const pagination = reactive<FinanceInvoicePaginationState>(
    createDefaultPagination(),
  );
  const rows = ref<FinanceInvoiceRecordListItemDto[]>([]);

  const stats = reactive<FinanceInvoiceStatsDto>({ ...DEFAULT_INVOICE_STATS });

  const settingForm = reactive<FinanceInvoiceSettingFormState>(
    createDefaultSettingsForm(),
  );
  const settingSnapshot = ref<FinanceInvoiceSettingFormState>(
    createDefaultSettingsForm(),
  );

  const issueForm = reactive<FinanceInvoiceIssueFormState>(
    createDefaultIssueForm(),
  );
  const voidForm = reactive<FinanceInvoiceVoidFormState>(createDefaultVoidForm());

  const detail = ref<FinanceInvoiceRecordDetailDto | null>(null);
  const issueDetail = ref<FinanceInvoiceRecordDetailDto | null>(null);
  const issueResult = ref<FinanceInvoiceIssueResultDto | null>(null);

  const issueTargetRecord = ref<FinanceInvoiceRecordListItemDto | null>(null);
  const voidTargetRecord = ref<FinanceInvoiceRecordListItemDto | null>(null);

  const isListLoading = ref(false);
  const isSettingsLoading = ref(false);
  const isDetailLoading = ref(false);
  const isIssueDetailLoading = ref(false);
  const isIssueSubmitting = ref(false);
  const isVoidSubmitting = ref(false);
  const isSettingsSaving = ref(false);

  const isDetailDrawerOpen = ref(false);
  const isIssueDrawerOpen = ref(false);
  const isVoidModalOpen = ref(false);
  const isIssueResultModalOpen = ref(false);
  const isSettingsConfirmModalOpen = ref(false);

  const accessCodeSet = computed(
    () => new Set((accessStore.accessCodes ?? []).map(String)),
  );

  const canViewRecords = computed(() => {
    const accessCodes = accessCodeSet.value;
    return (
      accessCodes.has(FINANCE_INVOICE_VIEW_PERMISSION) ||
      accessCodes.has(FINANCE_INVOICE_ISSUE_PERMISSION) ||
      accessCodes.has(FINANCE_INVOICE_VOID_PERMISSION)
    );
  });

  const canIssue = computed(() =>
    accessCodeSet.value.has(FINANCE_INVOICE_ISSUE_PERMISSION),
  );

  const canVoid = computed(() =>
    accessCodeSet.value.has(FINANCE_INVOICE_VOID_PERMISSION),
  );

  const canViewSettings = computed(() => {
    const accessCodes = accessCodeSet.value;
    return (
      accessCodes.has(FINANCE_INVOICE_VIEW_PERMISSION) ||
      accessCodes.has(FINANCE_INVOICE_SETTINGS_PERMISSION)
    );
  });

  const canManageSettings = computed(() =>
    accessCodeSet.value.has(FINANCE_INVOICE_SETTINGS_PERMISSION),
  );

  const canViewPage = computed(
    () => canViewRecords.value || canViewSettings.value,
  );

  const tabOptions = computed(() =>
    INVOICE_TAB_OPTIONS.filter((item) => {
      if (item.value === 'records') {
        return canViewRecords.value;
      }
      if (item.value === 'settings') {
        return canViewSettings.value;
      }
      return false;
    }),
  );

  const {
    applySettingsResult,
    clearByPermission,
    clearRecordData,
    loadRecordList,
    loadSettings,
  } = createDataActions({
    canViewRecords,
    canViewSettings,
    createDefaultSettingsForm,
    filters,
    isListLoading,
    isSettingsLoading,
    pagination,
    rows,
    settingForm,
    settingSnapshot,
    stats,
  });

  const {
    openDetail,
    openIssue,
    openVoid,
    setDetailDrawerOpen,
    setIssueDrawerOpen,
    setIssueResultModalOpen,
    setVoidModalOpen,
    submitIssue,
    submitVoid,
  } = createDrawerActions({
    canIssue,
    canVoid,
    detail,
    isDetailDrawerOpen,
    isDetailLoading,
    isIssueDetailLoading,
    isIssueDrawerOpen,
    isIssueResultModalOpen,
    isIssueSubmitting,
    isVoidModalOpen,
    isVoidSubmitting,
    issueDetail,
    issueForm,
    issueResult,
    issueTargetRecord,
    reloadRecordList: loadRecordList,
    voidForm,
    voidTargetRecord,
  });

  const {
    hasSettingsChanged,
    openSettingsConfirmModal,
    resetSettings,
    setSettingsConfirmModalOpen,
    submitSettings,
  } = createSettingsActions({
    applySettingsResult,
    canManageSettings,
    isSettingsConfirmModalOpen,
    isSettingsSaving,
    settingForm,
    settingSnapshot,
  });

  function setActiveTab(value: FinanceInvoiceTabKey) {
    activeTab.value = value;
  }

  function setStartDate(value: string) {
    filters.startDate = value;
  }

  function setEndDate(value: string) {
    filters.endDate = value;
  }

  function setStatus(value: string) {
    filters.status = (value || 'all') as FinanceInvoiceFilterState['status'];
  }

  function setInvoiceType(value: string) {
    filters.invoiceType = (value || 'all') as FinanceInvoiceFilterState['invoiceType'];
  }

  function setKeyword(value: string) {
    filters.keyword = value;
  }

  function setIssueFormContactEmail(value: string) {
    issueForm.contactEmail = value;
  }

  function setIssueFormRemark(value: string) {
    issueForm.issueRemark = value;
  }

  function setVoidReason(value: string) {
    voidForm.voidReason = value;
  }

  function setSettingsField<K extends keyof FinanceInvoiceSettingFormState>(
    field: K,
    value: FinanceInvoiceSettingFormState[K],
  ) {
    settingForm[field] = value;
  }

  async function handleSearch() {
    if (isDateRangeInvalid(filters)) {
      message.warning('开始日期不能晚于结束日期');
      return;
    }

    pagination.page = 1;
    await loadRecordList();
  }

  async function handlePageChange(page: number, pageSize: number) {
    pagination.page = page;
    pagination.pageSize = pageSize;
    await loadRecordList();
  }

  function closeTransientPanels() {
    setDetailDrawerOpen(false);
    setIssueDrawerOpen(false);
    setVoidModalOpen(false);
    setIssueResultModalOpen(false);
    setSettingsConfirmModalOpen(false);
  }

  async function loadByPermission() {
    const tasks: Array<Promise<void>> = [];

    if (canViewRecords.value) {
      tasks.push(loadRecordList());
    } else {
      clearRecordData();
    }

    if (canViewSettings.value) {
      tasks.push(loadSettings());
    }

    await Promise.all(tasks);
  }

  watch(tabOptions, (next) => {
    const values = next.map((item) => item.value);
    if (values.length === 0) {
      return;
    }

    if (!values.includes(activeTab.value)) {
      activeTab.value = values[0] as FinanceInvoiceTabKey;
    }
  });

  watch(
    canViewPage,
    async (value, oldValue) => {
      if (value === oldValue) {
        return;
      }

      if (!value) {
        clearByPermission();
        closeTransientPanels();
        return;
      }

      await loadByPermission();
    },
    { immediate: false },
  );

  onMounted(async () => {
    if (!canViewPage.value) {
      clearByPermission();
      closeTransientPanels();
      return;
    }

    await loadByPermission();
  });

  onActivated(() => {
    if (!canViewPage.value) {
      return;
    }

    void loadByPermission();
  });

  return {
    activeTab,
    canIssue,
    canManageSettings,
    canViewPage,
    canViewRecords,
    canViewSettings,
    canVoid,
    detail,
    filters,
    handlePageChange,
    handleSearch,
    hasSettingsChanged,
    isDetailDrawerOpen,
    isDetailLoading,
    isIssueDetailLoading,
    isIssueDrawerOpen,
    isIssueResultModalOpen,
    isIssueSubmitting,
    isListLoading,
    isSettingsConfirmModalOpen,
    isSettingsLoading,
    isSettingsSaving,
    isVoidModalOpen,
    isVoidSubmitting,
    issueDetail,
    issueForm,
    issueResult,
    issueTargetRecord,
    openDetail,
    openIssue,
    openSettingsConfirmModal,
    openVoid,
    pagination,
    resetSettings,
    rows,
    setActiveTab,
    setDetailDrawerOpen,
    setEndDate,
    setInvoiceType,
    setIssueDrawerOpen,
    setIssueFormContactEmail,
    setIssueFormRemark,
    setIssueResultModalOpen,
    setKeyword,
    setSettingsConfirmModalOpen,
    setSettingsField,
    setStartDate,
    setStatus,
    setVoidModalOpen,
    setVoidReason,
    settingForm,
    stats,
    submitIssue,
    submitSettings,
    submitVoid,
    tabOptions,
    voidForm,
    voidTargetRecord,
  };
}
