import { computed, nextTick, onMounted, ref, watch } from 'vue'
import { ElButton } from 'element-plus/es/components/button/index.mjs'
import { useRoute } from 'vue-router'

import BudgetTrendChart from '../../components/charts/BudgetTrendChart.vue'
import DocumentDropdownFilter from '../../components/shared/DocumentDropdownFilter.vue'
import EnterpriseDetailCard from '../../components/shared/EnterpriseDetailCard.vue'
import EnterpriseDetailPage from '../../components/shared/EnterpriseDetailPage.vue'
import EnterprisePagination from '../../components/shared/EnterprisePagination.vue'
import TableEmptyState from '../../components/shared/TableEmptyState.vue'
import TableLoadingState from '../../components/shared/TableLoadingState.vue'
import { fetchEmployeeMeta } from '../../services/employees.js'
import {
  canEditBudgetCenter,
  canSwitchBudgetDepartments,
  isBudgetMonitorUser,
  isExecutiveUser
} from '../../utils/accessControl.js'
import {
  BUDGET_QUARTER_OPTIONS,
  BUDGET_YEAR_OPTIONS,
  resolveBudgetExpenseTypeLabel
} from '../../utils/budgetOntology.js'
import {
  BUDGET_CONFIGURATION_NOTICE,
  readBudgetConfigurationFocus
} from './cfoValueSourceLinks.js'
import {
  BUDGET_PAGE_SIZE_OPTIONS,
  BUDGET_SCOPE_ALL,
  BUDGET_SCOPE_ARCHIVE,
  BUDGET_SCOPE_REVIEW,
  buildBudgetRows,
  buildBudgetScopeTabs,
  buildBudgetUsageData,
  getBudgetStatusOptions,
  matchesBudgetKeyword
} from './budgetCenterListModel.js'

const FALLBACK_DEPARTMENTS = [
  { code: 'MARKET-DEPT', name: '市场部', costCenter: 'CC-4100' },
  { code: 'FINANCE-DEPT', name: '财务部', costCenter: 'CC-2100' },
  { code: 'TECH-DEPT', name: '技术部', costCenter: 'CC-6100' },
  { code: 'HR-DEPT', name: '人力资源部', costCenter: 'CC-3200' },
  { code: 'PRODUCTION-DEPT', name: '生产部', costCenter: 'CC-7200' },
  { code: 'PRESIDENT-OFFICE', name: '总裁办', costCenter: 'CC-1000' }
]

function mapOptions(values, suffix = '') {
  return values.map((value) => ({
    label: suffix ? `${value}${suffix}` : value,
    value
  }))
}

function resolveOptionLabel(options, value, fallback) {
  return (Array.isArray(options) ? options : []).find((option) => option.value === value)?.label || fallback
}

function resolveBudgetUpdatedAt(row) {
  return row?.updatedAt || row?.submittedAt || row?.archivedAt || '-'
}

function resolveBudgetCompiler(row) {
  return row?.compiler || row?.owner || '-'
}

function buildBudgetDetailKpis(row) {
  return [
    {
      label: '编制人',
      value: resolveBudgetCompiler(row),
      unit: '',
      meta: row.scope === BUDGET_SCOPE_REVIEW ? '提交草案' : '预算编制',
      color: 'var(--theme-primary)'
    },
    {
      label: '审核人',
      value: row.reviewer || '-',
      unit: '',
      meta: '高级财务审核',
      color: '#3b82f6'
    },
    {
      label: '版本',
      value: row.version || '-',
      unit: '',
      meta: row.periodType || '预算版本',
      color: '#64748b'
    },
    {
      label: '更新时间',
      value: resolveBudgetUpdatedAt(row),
      unit: '',
      meta: '最近同步',
      color: '#f59e0b'
    }
  ]
}

export default {
  name: 'BudgetCenterView',
  props: {
    currentUser: {
      type: Object,
      default: () => ({})
    }
  },
  emits: ['openAssistant', 'detail-open-change', 'detail-topbar-change'],
  components: {
    BudgetTrendChart,
    DocumentDropdownFilter,
    EnterprisePagination,
    EnterpriseDetailCard,
    EnterpriseDetailPage,
    TableEmptyState,
    TableLoadingState,
    ElButton
  },
  setup(props, { emit }) {
    const route = useRoute()
    const departments = ref(FALLBACK_DEPARTMENTS)
    const activeBudgetScope = ref(BUDGET_SCOPE_ALL)
    const budgetKeyword = ref('')
    const budgetPage = ref(1)
    const budgetPageSize = ref(8)
    const budgetLoading = ref(true)
    const budgetError = ref('')
    const selectedBudgetId = ref('')
    const activeBudgetFilterKey = ref('')
    const filters = ref({
      year: '2026',
      quarter: 'Q1',
      status: '全部'
    })
    const budgetConfigurationFocus = computed(() => readBudgetConfigurationFocus(route.query))
    const budgetConfigurationFocusSummary = computed(() => {
      const focus = budgetConfigurationFocus.value
      const department = focus.departmentName || focus.departmentId || '当前可见部门'
      const expenseType = resolveBudgetExpenseTypeLabel(focus.expenseType, focus.expenseType)
      return [department, expenseType].filter(Boolean).join(' · ')
    })

    const canEditBudget = computed(() =>
      canEditBudgetCenter(props.currentUser) || isBudgetMonitorUser(props.currentUser)
    )
    const canAuditBudgetDrafts = computed(() => canEditBudgetCenter(props.currentUser))
    const canSwitchDepartments = computed(() => canSwitchBudgetDepartments(props.currentUser))
    const isDepartmentBudgetMonitor = computed(
      () => isBudgetMonitorUser(props.currentUser) && !canSwitchDepartments.value && !isExecutiveUser(props.currentUser)
    )
    const currentUserDepartmentName = computed(() =>
      String(props.currentUser?.departmentName || props.currentUser?.department || '').trim()
    )
    const currentUserCostCenter = computed(() =>
      String(props.currentUser?.costCenter || props.currentUser?.cost_center || '').trim()
    )

    const yearOptions = mapOptions(BUDGET_YEAR_OPTIONS, '年度')
    const quarterOptions = mapOptions(BUDGET_QUARTER_OPTIONS)
    const budgetPageSizeOptions = BUDGET_PAGE_SIZE_OPTIONS.map((size) => ({ label: `${size} 条/页`, value: size }))

    const budgetRowsByScope = computed(() =>
      buildBudgetRows({
        departments: departments.value,
        year: filters.value.year,
        quarter: filters.value.quarter
      })
    )

    const budgetScopeTabs = computed(() =>
      buildBudgetScopeTabs(budgetRowsByScope.value)
        .filter((tab) => canAuditBudgetDrafts.value || tab.value !== BUDGET_SCOPE_REVIEW)
    )
    const activeScopeRows = computed(() => budgetRowsByScope.value[activeBudgetScope.value] || [])
    const activeScopeLabel = computed(
      () => budgetScopeTabs.value.find((item) => item.value === activeBudgetScope.value)?.label || '预算'
    )
    const statusOptions = computed(() => mapOptions(getBudgetStatusOptions(activeBudgetScope.value)))
    const budgetYearFilterLabel = computed(() => resolveOptionLabel(yearOptions, filters.value.year, '年度'))
    const budgetQuarterFilterLabel = computed(() => resolveOptionLabel(quarterOptions, filters.value.quarter, '季度'))
    const budgetStatusFilterLabel = computed(() => resolveOptionLabel(statusOptions.value, filters.value.status, '状态'))

    const filteredBudgetRows = computed(() =>
      activeScopeRows.value
        .filter((row) => filters.value.status === '全部' || row.statusLabel === filters.value.status)
        .filter((row) => matchesBudgetConfigurationExpense(row))
        .filter((row) => matchesBudgetKeyword(row, budgetKeyword.value))
    )
    const totalBudgetRows = computed(() => filteredBudgetRows.value.length)
    const totalBudgetPages = computed(() =>
      Math.max(1, Math.ceil(totalBudgetRows.value / Number(budgetPageSize.value || 8)))
    )
    const currentBudgetPage = computed(() =>
      Math.min(Math.max(1, budgetPage.value), totalBudgetPages.value)
    )
    const visibleBudgetRows = computed(() => {
      const pageSize = Number(budgetPageSize.value || 8)
      const start = (currentBudgetPage.value - 1) * pageSize
      return filteredBudgetRows.value.slice(start, start + pageSize)
    })

    const selectedBudget = computed(() =>
      activeScopeRows.value.find((row) => row.id === selectedBudgetId.value) || null
    )
    const detailMode = computed(() => Boolean(selectedBudget.value))
    const selectedBudgetUsageData = computed(() => buildBudgetUsageData(selectedBudget.value))
    const budgetDetailTopBarPayload = computed(() => {
      const row = selectedBudget.value
      if (!row) return null

      return {
        view: {
          eyebrow: '预算详情',
          title: `${row.departmentName} · ${row.periodLabel}`,
          desc: `${row.budgetNo} / ${row.version} · 仅覆盖差旅、通信、招待费、办公用品`
        },
        alerts: [],
        kpis: buildBudgetDetailKpis(row)
      }
    })
    const selectedBudgetStatusNotes = computed(() => {
      const row = selectedBudget.value
      if (!row) return []

      return [
        {
          label: '预算状态',
          value: row.statusLabel,
          tone: row.statusTone || 'ok',
          desc: row.auditSummary || '当前预算状态已完成同步，可在预算中心继续追踪。'
        },
        {
          label: '风险状态',
          value: row.riskLabel,
          tone: row.riskTone || 'ok',
          desc: `当前已发生与已占用合计使用率为 ${row.usageRateLabel}，系统按四类费用的提醒、告警和风险阈值综合判断。`
        }
      ]
    })
    const showTable = computed(() => !budgetLoading.value && !budgetError.value && visibleBudgetRows.value.length > 0)
    const showEmpty = computed(() => !budgetLoading.value && !budgetError.value && visibleBudgetRows.value.length === 0)
    const emptyState = computed(() => ({
      eyebrow: activeScopeLabel.value,
      title: budgetConfigurationFocus.value.active ? '未找到匹配的预算配置' : `暂无${activeScopeLabel.value}`,
      desc: budgetConfigurationFocus.value.active
        ? `当前配置列表没有“${budgetConfigurationFocusSummary.value}”对应的预算科目；这不代表预算为零。`
        : '当前筛选条件下没有匹配的预算记录。',
      icon: 'mdi mdi-database-search-outline',
      tone: 'blue',
      artLabel: '预算列表为空',
      tips: budgetConfigurationFocus.value.active
        ? ['返回经营价值看板调整维度，或等待正式预算科目数据接入。']
        : ['可以调整年度、季度、状态或关键词后重试。']
    }))
    const pageSummary = computed(() => `共 ${totalBudgetRows.value} 条，目前第 ${currentBudgetPage.value} / ${totalBudgetPages.value} 页`)

    function buildBudgetAssistantContext(row, mode = 'edit') {
      if (!row) return null
      return {
        mode,
        budgetNo: row.budgetNo,
        departmentCode: row.departmentCode,
        departmentName: row.departmentName,
        costCenter: row.costCenter,
        periodLabel: row.periodLabel,
        periodType: row.periodType,
        budgetYear: row.budgetYear,
        budgetQuarter: row.budgetQuarter,
        version: row.version,
        compiler: row.compiler || row.owner,
        reviewer: row.reviewer,
        submittedAt: row.submittedAt,
        requestedAmount: row.requestedAmount || row.quarterAmount,
        previousAmount: row.quarterAmount,
        categoryRows: Array.isArray(row.categoryRows)
          ? row.categoryRows.map((item) => ({ ...item }))
          : []
      }
    }

    function resolveEditableBudgetRow() {
      const allRows = budgetRowsByScope.value[BUDGET_SCOPE_ALL] || []
      if (isDepartmentBudgetMonitor.value) {
        return allRows.find((row) => (
          row.scope === BUDGET_SCOPE_ALL &&
          (
            (currentUserCostCenter.value && row.costCenter === currentUserCostCenter.value) ||
            (currentUserDepartmentName.value && row.departmentName === currentUserDepartmentName.value)
          )
        )) || allRows[0] || null
      }

      return allRows.find((row) => row.scope === BUDGET_SCOPE_ALL) || allRows[0] || null
    }

    function openBudgetAssistant(prompt = '', budgetContext = null) {
      if (!canEditBudget.value) return
      const context = budgetContext || buildBudgetAssistantContext(resolveEditableBudgetRow(), 'edit')
      emit('openAssistant', {
        source: 'budget',
        sessionType: 'budget',
        prompt: prompt || (
          context?.departmentName
            ? `编辑${context.departmentName}${context.periodLabel || ''}预算`
            : '编辑本部门预算'
        ),
        files: [],
        conversation: null,
        budgetContext: context
      })
    }

    function openBudgetReviewAssistant(row) {
      if (!row || !canAuditBudgetDrafts.value) {
        openBudgetDetail(row)
        return
      }

      openBudgetAssistant(
        `请进入预算审核模式，审核${row.departmentName}${row.periodLabel}预算草案，重点看差旅、通信、招待费和办公用品的合理性、风险点和是否可以通过。`,
        buildBudgetAssistantContext(row, 'review')
      )
    }

    function openBudgetDetail(row) {
      if (!row?.id) return
      selectedBudgetId.value = row.id
    }

    function backToList() {
      selectedBudgetId.value = ''
    }

    async function applyBudgetConfigurationFocus() {
      const focus = budgetConfigurationFocus.value
      if (!focus.active) return
      const scopeChanged = activeBudgetScope.value !== BUDGET_SCOPE_ALL
      activeBudgetScope.value = BUDGET_SCOPE_ALL
      filters.value.status = '全部'
      budgetPage.value = 1
      if (scopeChanged) await nextTick()

      const departmentTokens = [focus.departmentId, focus.departmentName]
        .map((value) => String(value || '').trim().toLocaleLowerCase('zh-CN'))
        .filter(Boolean)
      const department = departments.value.find((item) => [
        item.id, item.code, item.name, item.costCenter
      ].some((value) => departmentTokens.includes(String(value || '').trim().toLocaleLowerCase('zh-CN'))))
      const rows = budgetRowsByScope.value[BUDGET_SCOPE_ALL] || []
      const row = department
        ? rows.find((item) => (
          item.departmentCode === department.code
          || item.departmentName === department.name
          || (department.costCenter && item.costCenter === department.costCenter)
        ))
        : null

      selectedBudgetId.value = row && matchesBudgetConfigurationExpense(row) ? row.id : ''
      budgetKeyword.value = row ? '' : (focus.departmentName || focus.departmentId || '')
    }

    function matchesBudgetConfigurationExpense(row = {}) {
      const focus = String(budgetConfigurationFocus.value.expenseType || '').trim().toLocaleLowerCase('zh-CN')
      if (!budgetConfigurationFocus.value.active || !focus) return true
      return (Array.isArray(row.categoryRows) ? row.categoryRows : []).some((item) => (
        [item.code, item.name].some((value) => String(value || '').trim().toLocaleLowerCase('zh-CN') === focus)
      ))
    }

    function isFocusedBudgetCategory(item = {}) {
      const focus = String(budgetConfigurationFocus.value.expenseType || '').trim().toLocaleLowerCase('zh-CN')
      if (!focus) return false
      return [item.code, item.name].some((value) => (
        String(value || '').trim().toLocaleLowerCase('zh-CN') === focus
      ))
    }

    function handleRowAction(row) {
      if (activeBudgetScope.value === BUDGET_SCOPE_REVIEW && canAuditBudgetDrafts.value) {
        openBudgetReviewAssistant(row)
        return
      }
      openBudgetDetail(row)
    }

    function goToBudgetPage(page) {
      budgetPage.value = Math.min(Math.max(Number(page) || 1, 1), totalBudgetPages.value)
    }

    function changeBudgetPageSize(size) {
      budgetPageSize.value = Number(size) || 8
      budgetPage.value = 1
    }

    function toggleBudgetFilter(key) {
      activeBudgetFilterKey.value = activeBudgetFilterKey.value === key ? '' : key
    }

    function selectBudgetFilter(key, value) {
      filters.value[key] = value
      activeBudgetFilterKey.value = ''
    }

    function resolveScopedDepartments(options) {
      if (!isDepartmentBudgetMonitor.value) return options

      const userDepartment = currentUserDepartmentName.value
      const userCostCenter = currentUserCostCenter.value
      const scoped = options.filter((item) => {
        if (userCostCenter && item.costCenter === userCostCenter) return true
        return userDepartment && item.name === userDepartment
      })

      if (scoped.length) return scoped

      return [
        {
          id: '',
          code: userCostCenter || userDepartment || 'CURRENT-DEPARTMENT',
          name: userDepartment || '当前部门',
          costCenter: userCostCenter
        }
      ]
    }

    async function loadDepartments() {
      budgetLoading.value = true
      budgetError.value = ''
      try {
        const payload = await fetchEmployeeMeta()
        const options = Array.isArray(payload?.organizationOptions) ? payload.organizationOptions : []
        const nextDepartments = options
          .filter((item) => item?.code && item?.name)
          .map((item) => ({
            id: String(item.id || ''),
            code: String(item.code),
            name: String(item.name),
            costCenter: String(item.costCenter || '')
          }))
        const scopedDepartments = resolveScopedDepartments(nextDepartments)
        if (scopedDepartments.length) {
          departments.value = scopedDepartments
        }
      } catch (error) {
        console.warn('Failed to load budget departments from employee meta:', error)
      } finally {
        budgetLoading.value = false
      }
    }

    onMounted(() => {
      void loadDepartments().then(() => applyBudgetConfigurationFocus())
    })

    watch(
      () => [
        route.query.budget_view,
        route.query.budget_department_id,
        route.query.budget_department_name,
        route.query.budget_expense_type
      ],
      () => void applyBudgetConfigurationFocus()
    )

    watch(
      () => activeBudgetScope.value,
      () => {
        filters.value.status = '全部'
        budgetPage.value = 1
        selectedBudgetId.value = ''
      }
    )

    watch(canAuditBudgetDrafts, (allowed) => {
      if (!allowed && activeBudgetScope.value === BUDGET_SCOPE_REVIEW) {
        activeBudgetScope.value = BUDGET_SCOPE_ALL
      }
    }, { immediate: true })

    watch(
      [
        budgetPageSize,
        budgetKeyword,
        () => filters.value.year,
        () => filters.value.quarter,
        () => filters.value.status
      ],
      () => {
        budgetPage.value = 1
      }
    )

    watch(totalBudgetPages, (pages) => {
      if (budgetPage.value > pages) {
        budgetPage.value = pages
      }
    })

    watch(detailMode, (value) => {
      emit('detail-open-change', value)
    }, { immediate: true })

    watch(budgetDetailTopBarPayload, (payload) => {
      emit('detail-topbar-change', payload)
    }, { immediate: true, deep: true })

    return {
      BUDGET_SCOPE_ALL,
      BUDGET_SCOPE_ARCHIVE,
      BUDGET_SCOPE_REVIEW,
      activeBudgetFilterKey,
      activeBudgetScope,
      budgetError,
      budgetConfigurationFocus,
      budgetConfigurationFocusSummary,
      budgetConfigurationNotice: BUDGET_CONFIGURATION_NOTICE,
      budgetKeyword,
      budgetLoading,
      budgetPage: currentBudgetPage,
      budgetPageSize,
      budgetPageSizeOptions,
      budgetScopeTabs,
      budgetQuarterFilterLabel,
      budgetStatusFilterLabel,
      budgetYearFilterLabel,
      backToList,
      canAuditBudgetDrafts,
      canEditBudget,
      changeBudgetPageSize,
      detailMode,
      emptyState,
      filters,
      goToBudgetPage,
      handleRowAction,
      isFocusedBudgetCategory,
      openBudgetAssistant,
      openBudgetDetail,
      openBudgetReviewAssistant,
      pageSummary,
      quarterOptions,
      selectedBudget,
      selectedBudgetStatusNotes,
      selectedBudgetUsageData,
      showEmpty,
      showTable,
      statusOptions,
      selectBudgetFilter,
      totalBudgetPages,
      totalBudgetRows,
      toggleBudgetFilter,
      visibleBudgetRows,
      yearOptions
    }
  }
}
