<template>
  <div class="app-container dispute-page">
    <div class="dispute-topbar">
      <el-tabs v-model="activeTab" class="dispute-topbar__tabs" @tab-click="handleTabChange">
        <el-tab-pane v-for="item in stepOptions" :key="item.tab" :name="item.tab">
          <template #label>
            <span>{{ item.label }}</span>
          </template>
        </el-tab-pane>
      </el-tabs>

      <div class="dispute-topbar__right">
        <el-radio-group v-model="activeStatus" size="small" @change="handleStatusChange">
          <el-radio-button label="todo">待办</el-radio-button>
          <el-radio-button label="done">已处理</el-radio-button>
          <el-radio-button label="all">全部</el-radio-button>
        </el-radio-group>
        <el-input
          v-model="keyword"
          clearable
          placeholder="订单号 / 客户"
          @keyup.enter="handleQuery"
          @clear="handleQuery"
        >
          <template #append>
            <el-button icon="Search" @click="handleQuery" />
          </template>
        </el-input>
        <el-button plain icon="Refresh" :loading="loading" @click="getList">刷新</el-button>
      </div>
    </div>

    <el-row :gutter="16">
      <el-col :xs="24" :sm="8" :md="7" :lg="6" :xl="5" class="dispute-left">
        <div class="left-list" v-loading="loading">
          <div class="left-header">
            <div class="left-header__title">{{ leftTitle }}</div>
            <el-button size="small" plain icon="Refresh" :loading="loading" @click="getList">刷新</el-button>
          </div>
          <el-empty v-if="!displayList.length && !loading" :description="emptyDescription" />
          <el-scrollbar v-else class="left-scroll">
            <div
              v-for="item in displayList"
              :key="item.taskId || item.orderId"
              class="dispute-card"
              :class="{ active: item.orderId === selectedOrderId }"
              @click="handleSelectRow(item)"
            >
              <div class="dispute-card__row">
                <div class="dispute-card__title">{{ item.orderCode || '-' }}</div>
                <div class="dispute-card__tags">
                  <el-tag v-if="item.status" size="small" :type="item.status === 'DONE' ? 'success' : 'warning'" effect="plain">
                    {{ item.status === 'DONE' ? '已处理' : '待办' }}
                  </el-tag>
                  <el-tag size="small" type="info" effect="plain">{{ item.taskName || '-' }}</el-tag>
                </div>
              </div>
              <div class="dispute-card__meta">
                <div class="dispute-card__meta-item">客户：{{ item.customerName || '-' }}</div>
                <div class="dispute-card__meta-item">
                  <span>创建：{{ formatTime(item.createTime) }}</span>
                  <span v-if="item.endTime" style="margin-left: 10px;">完成：{{ formatTime(item.endTime) }}</span>
                </div>
              </div>
            </div>
          </el-scrollbar>
        </div>
      </el-col>

      <el-col :xs="24" :sm="16" :md="17" :lg="18" :xl="19" class="dispute-right">
        <el-card shadow="never" class="right-card">
          <template #header>
            <div class="right-header">
              <div>
                <div class="right-title">{{ rightTitle }}</div>
                <div class="right-subtitle">
                  <span v-if="currentRow && currentRow.orderCode">当前：{{ currentRow.orderCode }}</span>
                  <span v-else>请选择左侧异议单据</span>
                </div>
              </div>
              <div class="right-actions">
                <el-button plain icon="Refresh" size="small" :loading="loading" @click="getList">刷新</el-button>
              </div>
            </div>
          </template>

          <div class="right-body">
            <el-empty v-if="!currentRow || !currentRow.orderId" description="← 请选择左侧异议列表" />
            <DisputeFlow
              v-else
              :order-id="currentRow.orderId"
              :order-code="currentRow.orderCode"
              :customer-id="currentRow.customerId"
              :customer-name="currentRow.customerName"
            />
          </div>
        </el-card>
      </el-col>
    </el-row>
</div>
</template>

<script setup>
import { computed, onActivated, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { listOrderDisputeTaskList } from '@/api/oa/orderDisputeFlow'
import DisputeFlow from '@/views/oms/order/panels/disputeFlow.vue'

const stepOptions = [
  { tab: 'all', stepKey: undefined, label: '全部' },
  { tab: 'acceptTask', stepKey: 'acceptTask', label: '异议接收' },
  { tab: 'physicalTask', stepKey: 'physicalTask', label: '实物确认' },
  { tab: 'analysisTask', stepKey: 'analysisTask', label: '原因分析' },
  { tab: 'planTask', stepKey: 'planTask', label: '处置方案' },
  { tab: 'visitTask', stepKey: 'visitTask', label: '闭环回访' }
]

const activeTab = ref('all')
const activeStatus = ref('todo')
const loading = ref(false)
const list = ref([])
const currentRow = ref(null)
const keyword = ref('')
const selectedOrderIdByTab = ref({})
const silentRefreshing = ref(false)
let fastRefreshTimers = []
let autoRefreshTimer = null
const inFlight = ref(false)
let pendingRefresh = false
let lastFetchKey = ''

const stepMeta = computed(() => stepOptions.find(item => item.tab === activeTab.value) || stepOptions[0])

const activeLabel = computed(() => stepMeta.value.label || '全部')

const selectedOrderId = computed(() => currentRow.value?.orderId)

const statusLabel = computed(() => {
  if (activeStatus.value === 'done') return '已处理'
  if (activeStatus.value === 'all') return '全部'
  return '待办'
})

const displayList = computed(() => {
  const kw = (keyword.value || '').trim().toLowerCase()
  if (!kw) return list.value
  return list.value.filter(item => {
    const orderCode = (item.orderCode || '').toLowerCase()
    const customerName = (item.customerName || '').toLowerCase()
    return orderCode.includes(kw) || customerName.includes(kw)
  })
})

const emptyDescription = computed(() => {
  const prefix = activeLabel.value === '全部' ? '' : activeLabel.value + ' '
  return `暂无${prefix}订单异议${statusLabel.value}`.trim()
})

const leftTitle = computed(() => {
  const prefix = activeLabel.value === '全部' ? '订单异议' : activeLabel.value
  return `${prefix}${statusLabel.value}`
})

const rightTitle = computed(() => {
  const prefix = activeLabel.value === '全部' ? '订单异议' : `订单异议 - ${activeLabel.value}`
  return `${prefix}（${statusLabel.value}）`
})

function formatTime(val) {
  if (!val) return '-'
  try {
    return new Date(val).toLocaleString()
  } catch (e) {
    return String(val)
  }
}

function handleQuery() {
  const nextList = displayList.value
  if (!nextList.length) {
    currentRow.value = null
    return
  }
  const selectedId = currentRow.value?.orderId
  if (selectedId && nextList.some(item => item.orderId === selectedId)) return
  currentRow.value = nextList[0]
  selectedOrderIdByTab.value = { ...selectedOrderIdByTab.value, [selectionKey()]: currentRow.value.orderId }
}

function fetchKey() {
  return `${activeTab.value}|${activeStatus.value}`
}

async function getList(options) {
  lastFetchKey = fetchKey()
  if (inFlight.value) {
    pendingRefresh = true
    return
  }

  const silent = options && options.silent
  if (silent) {
    if (silentRefreshing.value) return
    silentRefreshing.value = true
  } else {
    loading.value = true
  }
  inFlight.value = true
  const localFetchKey = lastFetchKey
  try {
    const res = await listOrderDisputeTaskList(stepMeta.value.stepKey, activeStatus.value, 200)
    if (localFetchKey !== fetchKey()) {
      return
    }
    list.value = res?.data || []
    restoreSelection()
  } finally {
    inFlight.value = false
    if (silent) {
      silentRefreshing.value = false
    } else {
      loading.value = false
    }
    if (pendingRefresh) {
      pendingRefresh = false
      getList({ silent: true })
    }
  }
}

function handleSelectRow(row) {
  currentRow.value = row
  selectedOrderIdByTab.value = { ...selectedOrderIdByTab.value, [selectionKey()]: row.orderId }
}

function selectionKey() {
  return `${activeTab.value}:${activeStatus.value}`
}

function restoreSelection() {
  const savedOrderId = selectedOrderIdByTab.value?.[selectionKey()]
  if (!list.value.length) {
    currentRow.value = null
    return
  }
  if (savedOrderId) {
    const exist = list.value.find(item => item.orderId === savedOrderId)
    if (exist) {
      currentRow.value = exist
      return
    }
  }
  const nextList = displayList.value
  currentRow.value = nextList[0] || list.value[0]
  if (currentRow.value?.orderId) {
    selectedOrderIdByTab.value = { ...selectedOrderIdByTab.value, [selectionKey()]: currentRow.value.orderId }
  }
}

function handleTabChange() {
  keyword.value = ''
  getList()
}

function handleStatusChange() {
  keyword.value = ''
  getList()
  startAutoRefresh()
}

function handleTaskChanged() {
  scheduleFastRefresh()
}

onMounted(() => {
  if (typeof window !== 'undefined') {
    window.addEventListener('order-dispute-task-changed', handleTaskChanged)
  }
  if (typeof document !== 'undefined') {
    document.addEventListener('visibilitychange', handleVisibilityChange)
  }
  getList()
  startAutoRefresh()
})

onActivated(() => {
  getList({ silent: true })
  startAutoRefresh()
})

onBeforeUnmount(() => {
  if (typeof window !== 'undefined') {
    window.removeEventListener('order-dispute-task-changed', handleTaskChanged)
  }
  if (typeof document !== 'undefined') {
    document.removeEventListener('visibilitychange', handleVisibilityChange)
  }
  stopAutoRefresh()
})

watch(keyword, () => {
  handleQuery()
})

function clearFastRefresh() {
  if (fastRefreshTimers && fastRefreshTimers.length) {
    fastRefreshTimers.forEach(id => clearTimeout(id))
  }
  fastRefreshTimers = []
}

function scheduleFastRefresh() {
  clearFastRefresh()
  getList({ silent: true })
  if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return
  fastRefreshTimers.push(setTimeout(() => getList({ silent: true }), 400))
  fastRefreshTimers.push(setTimeout(() => getList({ silent: true }), 1200))
  fastRefreshTimers.push(setTimeout(() => getList({ silent: true }), 2500))
}

function stopAutoRefresh() {
  if (autoRefreshTimer) {
    clearInterval(autoRefreshTimer)
    autoRefreshTimer = null
  }
}

function startAutoRefresh() {
  stopAutoRefresh()
  if (activeStatus.value !== 'todo') return
  if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return
  autoRefreshTimer = setInterval(() => {
    if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return
    getList({ silent: true })
  }, 3000)
}

function handleVisibilityChange() {
  startAutoRefresh()
}
</script>

<style scoped>
.dispute-page {
  height: calc(100vh - 110px);
}

.dispute-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}

.dispute-topbar__tabs {
  flex: 1;
  min-width: 360px;
}

.dispute-topbar__tabs :deep(.el-tabs__header) {
  margin: 0;
}

.dispute-topbar__right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.dispute-left,
.dispute-right {
  height: calc(100vh - 170px);
}

.left-list {
  border: 1px solid var(--el-border-color-light);
  border-radius: 6px;
  padding: 10px;
  background: #fff;
  height: 100%;
}

.left-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.left-header__title {
  font-weight: 600;
  color: #303133;
}

.left-scroll {
  height: 100%;
}

.dispute-card {
  border: 1px solid var(--el-border-color-light);
  border-radius: 6px;
  padding: 10px;
  margin-bottom: 10px;
  cursor: pointer;
  background: #fff;
}

.dispute-card.active {
  border-color: var(--el-color-primary);
  background: var(--el-color-primary-light-9);
}

.dispute-card__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.dispute-card__tags {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

.dispute-card__title {
  font-weight: 600;
  color: #303133;
  line-height: 20px;
  word-break: break-all;
}

.dispute-card__meta {
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: #606266;
  font-size: 12px;
}

.right-card {
  height: 100%;
}

.right-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.right-title {
  font-size: 18px;
  font-weight: 700;
  color: #303133;
}

.right-subtitle {
  margin-top: 4px;
  font-size: 12px;
  color: #909399;
}

.right-body {
  height: calc(100% - 8px);
  overflow: auto;
}
</style>
