import { computed, ref } from 'vue'
import { ElDropdown, ElDropdownItem, ElDropdownMenu } from 'element-plus/es/components/dropdown/index.mjs'

import EnterpriseListPage from '../../components/shared/EnterpriseListPage.vue'
import { mapExpenseClaimToRequest } from '../../composables/useRequests.js'
import {
  REIMBURSEMENT_LIST_PREVIEW_PARAMS,
  extractExpenseClaimItems,
  fetchArchivedExpenseClaims
} from '../../services/reimbursements.js'
import {
  ARCHIVE_FILTER_ALL,
  applyArchiveListFilters,
  buildArchiveMonthFilterOptions,
  buildDepartmentFilterOptions,
  buildTypeFilterOptions,
  countClaimRisks,
  extractArchiveMonth,
  formatArchiveMonthLabel,
  formatArchiveRiskCountLabel,
  hasActiveArchiveListFilters,
  resolveArchiveRiskTone
} from '../../utils/archiveCenterListFilters.js'
import { normalizeRequestForUi } from '../../utils/requestViewModel.js'
import TravelRequestDetailView from '../TravelRequestDetailView.vue'

const ARCHIVE_TAB_ALL = '全部归档'
const ARCHIVE_TAB_APPLICATION = '申请归档'
const ARCHIVE_TAB_REIMBURSEMENT = '报销归档'
const ARCHIVE_TYPE_APPLICATION = '申请'
const ARCHIVE_TYPE_APPLICATION_CODE = 'application'
const ARCHIVE_TYPE_REIMBURSEMENT = '报销'
const ARCHIVE_TYPE_REIMBURSEMENT_CODE = 'reimbursement'
const tabs = [ARCHIVE_TAB_ALL, ARCHIVE_TAB_APPLICATION, ARCHIVE_TAB_REIMBURSEMENT]
const RISK_FILTER_OPTIONS = [
  { value: ARCHIVE_FILTER_ALL, label: '全部风险' },
  { value: 'has', label: '有风险' },
  { value: 'none', label: '无风险' },
  { value: 'high', label: '高风险' },
  { value: 'medium', label: '中风险' },
  { value: 'low', label: '低风险' }
]

function formatCurrency(value) {
  const amount = Number(value)
  return new Intl.NumberFormat('zh-CN', {
    style: 'currency',
    currency: 'CNY',
    minimumFractionDigits: 0,
    maximumFractionDigits: Number.isInteger(amount) ? 0 : 2
  }).format(Number.isFinite(amount) ? amount : 0)
}

function buildArchiveRow(request) {
  const normalized = normalizeRequestForUi(request)
  const riskCount = countClaimRisks(normalized.riskFlags, normalized.riskSummary)
  const riskTone = riskCount > 0 ? resolveArchiveRiskTone(normalized.riskFlags, normalized.riskSummary) : 'none'
  const hasRisk = riskCount > 0
  const isApplicationDocument = normalized.documentTypeCode === 'application'
  const archiveMonth = extractArchiveMonth(
    normalized.updatedAt,
    normalized.submittedAt,
    normalized.createdAt,
    normalized.occurredAt,
    normalized.applyTime
  )

  return {
    ...normalized,
    applicant: normalized.person,
    avatar: String(normalized.person || '?').trim().slice(0, 1) || '?',
    department: normalized.dept,
    type: normalized.typeLabel,
    amount: formatCurrency(normalized.amountValue),
    time: normalized.applyTime,
    archivedAt: normalized.updatedAt || normalized.applyTime,
    archiveMonth,
    archiveMonthLabel: formatArchiveMonthLabel(archiveMonth),
    archiveType: isApplicationDocument ? ARCHIVE_TYPE_APPLICATION : ARCHIVE_TYPE_REIMBURSEMENT,
    archiveTypeCode: isApplicationDocument ? ARCHIVE_TYPE_APPLICATION_CODE : ARCHIVE_TYPE_REIMBURSEMENT_CODE,
    node: isApplicationDocument ? '申请归档' : (normalized.workflowNode || '已付款'),
    hasRisk,
    riskCount,
    risk: formatArchiveRiskCountLabel(riskCount),
    riskTone,
    status: '已归档',
    statusTone: 'archived',
    archiveTab: isApplicationDocument ? ARCHIVE_TAB_APPLICATION : ARCHIVE_TAB_REIMBURSEMENT
  }
}

function resolveFilterLabel(options, activeValue, fallbackLabel) {
  return options.find((item) => item.value === activeValue)?.label || fallbackLabel
}

export default {
  name: 'ArchiveCenterView',
  components: {
    ElDropdown,
    ElDropdownItem,
    ElDropdownMenu,
    EnterpriseListPage,
    TravelRequestDetailView
  },
  setup() {
    const activeTab = ref(ARCHIVE_TAB_ALL)
    const activeRiskFilter = ref(ARCHIVE_FILTER_ALL)
    const activeTypeFilter = ref(ARCHIVE_FILTER_ALL)
    const activeDepartmentFilter = ref(ARCHIVE_FILTER_ALL)
    const activeArchiveMonthFilter = ref(ARCHIVE_FILTER_ALL)
    const selectedClaimId = ref('')
    const listKeyword = ref('')
    const rows = ref([])
    const loading = ref(false)
    const error = ref('')

    const typeFilterOptions = computed(() => buildTypeFilterOptions(rows.value))
    const departmentFilterOptions = computed(() => buildDepartmentFilterOptions(rows.value))
    const archiveMonthFilterOptions = computed(() => buildArchiveMonthFilterOptions(rows.value))

    const riskFilterLabel = computed(() => resolveFilterLabel(RISK_FILTER_OPTIONS, activeRiskFilter.value, '全部风险'))
    const typeFilterLabel = computed(() => resolveFilterLabel(typeFilterOptions.value, activeTypeFilter.value, '归档类型'))
    const departmentFilterLabel = computed(() => resolveFilterLabel(departmentFilterOptions.value, activeDepartmentFilter.value, '所属部门'))
    const archiveMonthFilterLabel = computed(() => resolveFilterLabel(archiveMonthFilterOptions.value, activeArchiveMonthFilter.value, '归档月份'))

    const filterMenus = computed(() => [
      {
        key: 'risk',
        label: riskFilterLabel.value,
        options: RISK_FILTER_OPTIONS,
        activeValue: activeRiskFilter.value
      },
      {
        key: 'type',
        label: typeFilterLabel.value,
        options: typeFilterOptions.value,
        activeValue: activeTypeFilter.value
      },
      {
        key: 'department',
        label: departmentFilterLabel.value,
        options: departmentFilterOptions.value,
        activeValue: activeDepartmentFilter.value
      },
      {
        key: 'archiveMonth',
        label: archiveMonthFilterLabel.value,
        options: archiveMonthFilterOptions.value,
        activeValue: activeArchiveMonthFilter.value
      }
    ])

    const selectedRow = computed({
      get() {
        return rows.value.find((row) => row.claimId === selectedClaimId.value) || null
      },
      set(value) {
        selectedClaimId.value = value?.claimId || ''
      }
    })

    const visibleRows = computed(() => applyArchiveListFilters(rows.value, {
      tab: activeTab.value,
      risk: activeRiskFilter.value,
      type: activeTypeFilter.value,
      department: activeDepartmentFilter.value,
      archiveMonth: activeArchiveMonthFilter.value,
      keyword: listKeyword.value
    }))

    const showEmpty = computed(() => !loading.value && !error.value && visibleRows.value.length === 0)
    const archiveEmptyState = computed(() => {
      if (!rows.value.length) {
        return {
          eyebrow: '归档中心',
          title: '当前还没有已归档单据',
          desc: '财务确认付款后进入「已付款」状态的报销单会自动汇总到这里，形成公司级财务归档库。',
          icon: 'mdi mdi-archive-check-outline',
          actionLabel: null,
          actionIcon: null,
          tone: 'slate',
          artLabel: 'ARCHIVE',
          tips: ['仅展示已付款或已归档的单据', '申请人仍可在报销中心查看自己的归档记录']
        }
      }

      const filtersActive = hasActiveArchiveListFilters({
        tab: activeTab.value,
        risk: activeRiskFilter.value,
        type: activeTypeFilter.value,
        department: activeDepartmentFilter.value,
        archiveMonth: activeArchiveMonthFilter.value,
        keyword: listKeyword.value
      })

      return {
        eyebrow: filtersActive ? '筛选结果为空' : '归档中心',
        title: filtersActive ? '没有符合当前筛选条件的归档单据' : `“${activeTab.value}”里暂时没有归档单据`,
        desc: filtersActive
          ? '可以调整风险、归档类型、部门或归档月份筛选，也可以修改搜索关键词后重试。'
          : '可以切换到其他归档分类查看，或调整筛选条件后重新检索。',
        icon: 'mdi mdi-archive-outline',
        actionLabel: null,
        actionIcon: null,
        tone: 'sky',
        artLabel: filtersActive ? 'FILTER' : 'ARCHIVE',
        tips: ['归档中心保存全公司归档数据', '非申请人无法在报销中心查看他人归档单']
      }
    })

    function resetListFilters() {
      activeTab.value = ARCHIVE_TAB_ALL
      activeRiskFilter.value = ARCHIVE_FILTER_ALL
      activeTypeFilter.value = ARCHIVE_FILTER_ALL
      activeDepartmentFilter.value = ARCHIVE_FILTER_ALL
      activeArchiveMonthFilter.value = ARCHIVE_FILTER_ALL
      listKeyword.value = ''
    }

    function handleEmptyAction() {
      if (!rows.value.length) {
        void reload()
        return
      }

      resetListFilters()
    }

    function selectFilterValue(key, value) {
      if (key === 'risk') {
        activeRiskFilter.value = value
      } else if (key === 'type') {
        activeTypeFilter.value = value
      } else if (key === 'department') {
        activeDepartmentFilter.value = value
      } else if (key === 'archiveMonth') {
        activeArchiveMonthFilter.value = value
      }

    }

    function closeSelectedDetail() {
      selectedClaimId.value = ''
    }

    async function reload() {
      loading.value = true
      error.value = ''

      try {
        const payload = await fetchArchivedExpenseClaims(REIMBURSEMENT_LIST_PREVIEW_PARAMS)
        const mappedRows = extractExpenseClaimItems(payload)
          .map((item) => mapExpenseClaimToRequest(item))
          .filter(Boolean)
          .map((item) => buildArchiveRow(item))
        rows.value = mappedRows
        if (!mappedRows.some((item) => item.claimId === selectedClaimId.value)) {
          selectedClaimId.value = ''
        }
      } catch (nextError) {
        rows.value = []
        selectedClaimId.value = ''
        error.value = nextError instanceof Error ? nextError.message : '归档中心加载失败。'
      } finally {
        loading.value = false
      }
    }

    void reload()

    return {
      activeTab,
      archiveEmptyState,
      closeSelectedDetail,
      error,
      filterMenus,
      handleEmptyAction,
      listKeyword,
      loading,
      reload,
      resetListFilters,
      rows,
      selectFilterValue,
      selectedRow,
      showEmpty,
      tabs,
      visibleRows
    }
  }
}
