<template>
    <div class="qywx-customer-page p-4">
        <el-card shadow="never" class="mb-4">
            <template #header>
                <div class="flex items-center justify-between">
                    <span class="text-lg font-semibold">企业微信客户管理</span>
                    <div class="flex gap-2">
                        <el-button type="success" plain @click="openArrivalDrawer">
                            <template #icon><DataLine /></template>
                            今日进入明细
                        </el-button>
                        <el-button type="warning" plain @click="openTagDrawer">
                            <template #icon><CollectionTag /></template>
                            标签维度
                        </el-button>
                        <el-button type="primary" :loading="syncing" @click="syncCustomers()">
                            <template #icon><Refresh /></template>
                            立即同步
                        </el-button>
                        <el-button @click="showSyncSettings = true">
                            <template #icon><Setting /></template>
                            同步设置
                        </el-button>
                    </div>
                </div>
            </template>
            
            <el-alert
                title="功能说明"
                type="info"
                :closable="false"
                class="mb-4"
            >
                <div class="text-sm">
                    <p>自动从企业微信同步外部联系人（客户）信息，包括客户基本信息、跟进人等。</p>
                    <p class="mt-1">同步后的数据可用于患者信息匹配和自动关联。</p>
                </div>
            </el-alert>

            <div class="grid grid-cols-4 gap-4 mb-4">
                <el-card shadow="hover">
                    <div class="text-gray-500 text-sm mb-1">总客户数</div>
                    <div class="text-2xl font-bold text-primary">{{ stats.total }}</div>
                </el-card>
                <el-card shadow="hover" class="today-arrival-card cursor-pointer" @click="openArrivalDrawer">
                    <div class="flex items-center justify-between mb-1">
                        <span class="text-gray-500 text-sm">今日新增</span>
                        <span v-if="arrival.recent_time" class="text-xs text-gray-400">
                            最近 {{ formatHm(arrival.recent_time) }}
                        </span>
                    </div>
                    <div class="flex items-end gap-2">
                        <div class="text-2xl font-bold text-success leading-none">{{ stats.today }}</div>
                        <div class="text-xs text-gray-400 pb-1">人</div>
                    </div>
                    <!-- 24 小时分布迷你柱：高度相对今日峰值等比 -->
                    <div class="hourly-bars mt-2" :title="hourlyTooltip">
                        <div
                            v-for="(c, h) in arrival.hourly"
                            :key="h"
                            class="hourly-bar"
                            :class="{
                                'is-empty': c === 0,
                                'is-current': h === currentHour
                            }"
                            :style="{ height: barHeight(c) }"
                        />
                    </div>
                    <div class="mt-2 pt-2 border-t border-gray-100">
                        <div class="text-gray-500 text-xs mb-0.5">今日跟进人合计</div>
                        <div class="text-lg font-semibold text-gray-800">{{ stats.today_follow_staff }}</div>
                    </div>
                </el-card>
                <el-card shadow="hover">
                    <div class="text-gray-500 text-sm mb-1">最后同步</div>
                    <div class="text-sm font-medium">{{ stats.lastSync || '未同步' }}</div>
                </el-card>
                <el-card shadow="hover">
                    <div class="text-gray-500 text-sm mb-1">同步状态</div>
                    <el-tag :type="syncStatusTagType" size="small">
                        {{ stats.syncStatusText }}
                    </el-tag>
                </el-card>
            </div>
        </el-card>

        <el-card shadow="never">
            <el-form :model="queryParams" inline class="mb-4">
                <el-form-item label="客户名称">
                    <el-input
                        v-model="queryParams.name"
                        placeholder="搜索客户名称"
                        clearable
                        @keyup.enter="resetPage"
                    />
                </el-form-item>
                <el-form-item label="跟进人">
                    <el-input
                        v-model="queryParams.follow_user"
                        placeholder="跟进人姓名"
                        clearable
                        @keyup.enter="resetPage"
                    />
                </el-form-item>
                <el-form-item label="添加时间">
                    <el-date-picker
                        v-model="addTimeRange"
                        type="daterange"
                        value-format="YYYY-MM-DD"
                        start-placeholder="开始日期"
                        end-placeholder="结束日期"
                        clearable
                        class="!w-[280px]"
                        @change="onAddTimeRangeChange"
                    />
                </el-form-item>
                <el-form-item label="标签">
                    <el-select
                        v-model="queryParams.tag_ids"
                        multiple
                        collapse-tags
                        collapse-tags-tooltip
                        clearable
                        filterable
                        placeholder="按标签筛选（可多选，命中任一即返回）"
                        :loading="tagStatsLoading"
                        style="min-width: 320px"
                        @change="resetPage"
                    >
                        <el-option-group
                            v-for="g in tagStats.groups"
                            :key="g.group_name || '_'"
                            :label="(g.group_name || '（未分组）') + ' · ' + g.customer_count"
                        >
                            <el-option
                                v-for="t in g.tags"
                                :key="t.tag_id"
                                :value="t.tag_id"
                                :label="t.tag_name"
                            >
                                <span class="flex items-center justify-between gap-3">
                                    <span>{{ t.tag_name }}</span>
                                    <span class="text-xs text-gray-400">{{ t.customer_count }} 人</span>
                                </span>
                            </el-option>
                        </el-option-group>
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="resetPage">查询</el-button>
                    <el-button @click="handleReset">重置</el-button>
                </el-form-item>
            </el-form>

            <el-table v-loading="pager.loading" :data="pager.lists" stripe>
                <el-table-column label="客户信息" min-width="200">
                    <template #default="{ row }">
                        <div class="flex items-center gap-2">
                            <el-avatar :size="40" :src="row.avatar" />
                            <div>
                                <div class="font-medium">{{ row.name }}</div>
                                <div class="text-xs text-gray-400">{{ row.external_userid }}</div>
                            </div>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column label="类型" width="80">
                    <template #default="{ row }">
                        <el-tag size="small">{{ row.type === 1 ? '微信' : '企微' }}</el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="性别" width="60">
                    <template #default="{ row }">
                        {{ row.gender === 1 ? '男' : row.gender === 2 ? '女' : '未知' }}
                    </template>
                </el-table-column>
                <el-table-column label="跟进人" min-width="150">
                    <template #default="{ row }">
                        <div v-if="row.follow_users && row.follow_users.length">
                            <el-tooltip
                                v-for="(user, idx) in row.follow_users"
                                :key="(user.userid || '') + '-' + idx"
                                :disabled="!followStaffTooltip(user)"
                                :content="followStaffTooltip(user)"
                                placement="top"
                            >
                                <el-tag size="small" class="mr-1 mb-1">
                                    {{ formatFollowUser(user) }}
                                </el-tag>
                            </el-tooltip>
                        </div>
                        <span v-else class="text-gray-400">—</span>
                    </template>
                </el-table-column>
                <el-table-column label="标签" min-width="180">
                    <template #default="{ row }">
                        <div v-if="row.tags && row.tags.length">
                            <el-tag
                                v-for="t in row.tags"
                                :key="t.tag_id"
                                size="small"
                                effect="light"
                                type="warning"
                                class="mr-1 mb-1 cursor-pointer"
                                @click="addTagToFilter(t.tag_id)"
                            >
                                {{ t.tag_name }}
                                <span v-if="t.group_name" class="ml-1 text-gray-400 text-xs">
                                    {{ t.group_name }}
                                </span>
                            </el-tag>
                        </div>
                        <span v-else class="text-gray-400">—</span>
                    </template>
                </el-table-column>
                <el-table-column label="添加时间" width="160">
                    <template #default="{ row }">
                        {{ formatTime(firstExternalAddTime(row)) }}
                    </template>
                </el-table-column>
                <el-table-column label="更新时间" width="160">
                    <template #default="{ row }">
                        {{ formatTime(row.update_time) }}
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="120" fixed="right">
                    <template #default="{ row }">
                        <el-button type="primary" link @click="viewDetail(row)">查看详情</el-button>
                    </template>
                </el-table-column>
            </el-table>

            <div class="flex justify-end mt-4">
                <pagination v-model="pager" @change="getLists" />
            </div>
        </el-card>

        <!-- 同步设置对话框 -->
        <el-dialog
            v-model="showSyncSettings"
            title="同步设置"
            width="500px"
        >
            <el-form :model="syncSettings" label-width="120px">
                <el-form-item label="自动同步">
                    <el-switch v-model="syncSettings.auto_sync" />
                    <div class="text-xs text-gray-400 mt-1">
                        开启后将定时自动同步企业微信客户数据
                    </div>
                </el-form-item>
                <el-form-item label="同步间隔">
                    <el-select v-model="syncSettings.interval" :disabled="!syncSettings.auto_sync">
                        <el-option label="每小时" :value="3600" />
                        <el-option label="每2小时" :value="7200" />
                        <el-option label="每4小时" :value="14400" />
                        <el-option label="每6小时" :value="21600" />
                        <el-option label="每12小时" :value="43200" />
                        <el-option label="每天" :value="86400" />
                    </el-select>
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button @click="showSyncSettings = false">取消</el-button>
                <el-button type="primary" @click="saveSyncSettings">保存</el-button>
            </template>
        </el-dialog>

        <!-- 今日进入明细（事件流水零误差口径） -->
        <el-drawer
            v-model="showArrival"
            title="今日进入明细"
            direction="rtl"
            size="520px"
            :destroy-on-close="false"
        >
            <template #header>
                <div class="flex items-center justify-between w-full pr-4">
                    <div class="flex items-center gap-3">
                        <span class="text-base font-semibold">今日进入明细</span>
                        <el-tag type="success" effect="plain">共 {{ arrivalList.total }} 人</el-tag>
                    </div>
                    <el-button link type="primary" :loading="arrivalListLoading" @click="loadArrival(true)">
                        <template #icon><Refresh /></template>
                        刷新
                    </el-button>
                </div>
            </template>
            <div class="px-1">
                <el-alert
                    type="info"
                    :closable="false"
                    class="mb-3"
                    show-icon
                >
                    <template #title>
                        <span class="text-xs">
                            一次推送 = 一个人进来；数据来源为企微回调流水表（INSERT IGNORE 幂等），与客户同步解耦，数字零误差。
                        </span>
                    </template>
                </el-alert>

                <div v-if="arrival.by_state?.length" class="mb-3">
                    <div class="text-xs text-gray-500 mb-1">今日推广渠道 Top</div>
                    <div class="flex flex-wrap gap-1">
                        <el-tag
                            v-for="it in arrival.by_state"
                            :key="it.state || '_'"
                            size="small"
                            effect="light"
                            type="success"
                        >
                            {{ it.state || '（无 state）' }} · {{ it.count }}
                        </el-tag>
                    </div>
                </div>

                <el-timeline v-if="arrivalList.lists.length" class="mt-2">
                    <el-timeline-item
                        v-for="row in arrivalList.lists"
                        :key="row.id"
                        :timestamp="formatHms(row.event_time)"
                        placement="top"
                        type="success"
                        :hollow="false"
                    >
                        <div class="flex items-start gap-2">
                            <el-avatar
                                :size="32"
                                :src="row.customer_avatar || undefined"
                            >
                                {{ (row.customer_name || '?').slice(0, 1) }}
                            </el-avatar>
                            <div class="flex-1 min-w-0">
                                <div class="text-sm font-medium truncate">
                                    {{ row.customer_name || row.external_userid || '（未知客户）' }}
                                </div>
                                <div class="text-xs text-gray-500 mt-0.5">
                                    <span>接待：{{ row.admin_name || row.user_id || '—' }}</span>
                                    <span v-if="row.state" class="ml-2">
                                        渠道：<el-tag size="small" type="info" effect="plain">{{ row.state }}</el-tag>
                                    </span>
                                    <span v-if="row.welcome_code" class="ml-2 text-emerald-500">欢迎语</span>
                                </div>
                            </div>
                        </div>
                    </el-timeline-item>
                </el-timeline>
                <el-empty v-else description="今天还没有人进入" :image-size="80" />

                <div
                    v-if="arrivalList.total > arrivalList.lists.length"
                    class="mt-3 text-center"
                >
                    <el-button
                        :loading="arrivalListLoading"
                        size="small"
                        @click="loadMoreArrival"
                    >
                        加载更多（还剩 {{ arrivalList.total - arrivalList.lists.length }}）
                    </el-button>
                </div>
            </div>
        </el-drawer>

        <!-- 标签维度面板 -->
        <el-drawer
            v-model="showTagDrawer"
            title="标签维度统计"
            direction="rtl"
            size="560px"
            :destroy-on-close="false"
        >
            <template #header>
                <div class="flex items-center justify-between w-full pr-4">
                    <div class="flex items-center gap-3">
                        <span class="text-base font-semibold">标签维度统计</span>
                        <el-tag type="warning" effect="plain">
                            {{ tagStats.groups.length }} 组 · {{ tagStats.total_tags }} 标签
                        </el-tag>
                    </div>
                    <el-button link type="primary" :loading="tagStatsLoading" @click="loadTagStats(true)">
                        <template #icon><Refresh /></template>
                        刷新
                    </el-button>
                </div>
            </template>

            <div class="px-1">
                <div class="grid grid-cols-3 gap-2 mb-3">
                    <el-card shadow="never" body-class="!p-3">
                        <div class="text-xs text-gray-500">已打标签客户</div>
                        <div class="text-xl font-bold text-warning">{{ tagStats.total_tagged_customers }}</div>
                    </el-card>
                    <el-card shadow="never" body-class="!p-3">
                        <div class="text-xs text-gray-500">标签数</div>
                        <div class="text-xl font-bold">{{ tagStats.total_tags }}</div>
                    </el-card>
                    <el-card shadow="never" body-class="!p-3">
                        <div class="text-xs text-gray-500">关系总数</div>
                        <div class="text-xl font-bold">{{ tagStats.total_relations }}</div>
                    </el-card>
                </div>

                <el-input
                    v-model="tagSearchKw"
                    placeholder="筛选标签名 / 分组名"
                    clearable
                    size="small"
                    class="mb-3"
                />

                <el-empty
                    v-if="filteredTagGroups.length === 0"
                    :description="tagStatsLoading ? '加载中…' : '暂无标签数据'"
                    :image-size="64"
                />

                <el-collapse v-else v-model="tagDrawerActiveGroups">
                    <el-collapse-item
                        v-for="g in filteredTagGroups"
                        :key="g.group_name || '_'"
                        :name="g.group_name || '_'"
                    >
                        <template #title>
                            <div class="flex items-center gap-2 w-full">
                                <span class="font-medium">{{ g.group_name || '（未分组）' }}</span>
                                <el-tag size="small" effect="plain">{{ g.tags.length }}</el-tag>
                                <span class="ml-auto text-xs text-gray-500">
                                    最热 {{ g.customer_count }} 人
                                </span>
                            </div>
                        </template>
                        <el-table :data="g.tags" size="small" stripe>
                            <el-table-column label="标签" min-width="160">
                                <template #default="{ row }">
                                    <span class="font-medium">{{ row.tag_name }}</span>
                                    <div class="text-xs text-gray-400 truncate">{{ row.tag_id }}</div>
                                </template>
                            </el-table-column>
                            <el-table-column label="客户数" width="100" align="right">
                                <template #default="{ row }">
                                    <span class="text-warning font-bold">{{ row.customer_count }}</span>
                                </template>
                            </el-table-column>
                            <el-table-column label="操作" width="80" align="center">
                                <template #default="{ row }">
                                    <el-button link type="primary" size="small" @click="filterByTag(row.tag_id)">
                                        筛选
                                    </el-button>
                                </template>
                            </el-table-column>
                        </el-table>
                    </el-collapse-item>
                </el-collapse>
            </div>
        </el-drawer>

        <!-- 客户详情对话框 -->
        <el-dialog
            v-model="showDetail"
            title="客户详情"
            width="600px"
        >
            <el-descriptions v-if="currentCustomer" :column="2" border>
                <el-descriptions-item label="客户名称">{{ currentCustomer.name }}</el-descriptions-item>
                <el-descriptions-item label="External ID">{{ currentCustomer.external_userid }}</el-descriptions-item>
                <el-descriptions-item label="性别">
                    {{ currentCustomer.gender === 1 ? '男' : currentCustomer.gender === 2 ? '女' : '未知' }}
                </el-descriptions-item>
                <el-descriptions-item label="类型">
                    {{ currentCustomer.type === 1 ? '微信用户' : '企业微信用户' }}
                </el-descriptions-item>
                <el-descriptions-item label="企业名称" :span="2">
                    {{ currentCustomer.corp_name || '—' }}
                </el-descriptions-item>
                <el-descriptions-item label="职位" :span="2">
                    {{ currentCustomer.position || '—' }}
                </el-descriptions-item>
                <el-descriptions-item label="添加时间" :span="2">
                    {{ formatTime(firstExternalAddTime(currentCustomer)) }}
                </el-descriptions-item>
                <el-descriptions-item label="更新时间" :span="2">
                    {{ formatTime(currentCustomer.update_time) }}
                </el-descriptions-item>
                <el-descriptions-item label="跟进人" :span="2">
                    <div v-if="currentCustomer.follow_users?.length">
                        <el-tooltip
                            v-for="(user, idx) in currentCustomer.follow_users"
                            :key="(user.userid || '') + '-' + idx"
                            :disabled="!followStaffTooltip(user)"
                            :content="followStaffTooltip(user)"
                            placement="top"
                        >
                            <el-tag size="small" class="mr-1 mb-1">
                                {{ formatFollowUser(user) }}
                            </el-tag>
                        </el-tooltip>
                    </div>
                    <span v-else class="text-gray-400">—</span>
                </el-descriptions-item>
                <el-descriptions-item label="标签" :span="2">
                    <div v-if="currentCustomer.tags?.length">
                        <el-tag
                            v-for="t in currentCustomer.tags"
                            :key="t.tag_id"
                            size="small"
                            effect="light"
                            type="warning"
                            class="mr-1 mb-1"
                        >
                            {{ t.tag_name }}
                            <span v-if="t.group_name" class="ml-1 text-gray-400 text-xs">
                                {{ t.group_name }}
                            </span>
                        </el-tag>
                    </div>
                    <span v-else class="text-gray-400">—</span>
                </el-descriptions-item>
            </el-descriptions>
        </el-dialog>
    </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
import { Refresh, Setting, DataLine, CollectionTag } from '@element-plus/icons-vue'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import { 
    qywxCustomerLists, 
    qywxCustomerSync, 
    qywxCustomerStats,
    qywxSyncSettingsGet,
    qywxSyncSettingsSave,
    qywxCustomerTodayArrival,
    qywxCustomerTodayArrivalList,
    qywxCustomerTagStats
} from '@/api/qywx'

const syncing = ref(false)
const showSyncSettings = ref(false)
const showDetail = ref(false)
const currentCustomer = ref<any>(null)

const stats = reactive({
    total: 0,
    today: 0,
    today_follow_staff: 0,
    lastSync: '',
    syncStatus: 'idle',
    syncStatusText: '未同步'
})

const syncStatusTagType = computed(() => {
    switch (stats.syncStatus) {
        case 'success':
            return 'success'
        case 'syncing':
            return 'warning'
        case 'failed':
            return 'danger'
        default:
            return 'info'
    }
})

const syncSettings = reactive({
    auto_sync: false,
    interval: 3600
})

const queryParams = reactive<{
    name: string
    follow_user: string
    tag_ids: string[]
    add_time_start: string
    add_time_end: string
}>({
    name: '',
    follow_user: '',
    tag_ids: [],
    add_time_start: '',
    add_time_end: ''
})

/** 与列表「添加时间」列口径一致（库内 external_first_add_time / create_time） */
const addTimeRange = ref<[string, string] | null>(null)

function onAddTimeRangeChange(val: [string, string] | null) {
    if (val && val.length === 2 && val[0] && val[1]) {
        queryParams.add_time_start = val[0]
        queryParams.add_time_end = val[1]
    } else {
        queryParams.add_time_start = ''
        queryParams.add_time_end = ''
    }
    resetPage()
}

// ── 标签维度（筛选下拉 + 抽屉面板共用同一份数据） ──────────────────────────
interface TagItem {
    tag_id: string
    tag_name: string
    customer_count: number
}
interface TagGroup {
    group_name: string
    customer_count: number
    tags: TagItem[]
}
interface TagStatsPayload {
    total_tags: number
    total_relations: number
    total_tagged_customers: number
    groups: TagGroup[]
}

const tagStats = reactive<TagStatsPayload>({
    total_tags: 0,
    total_relations: 0,
    total_tagged_customers: 0,
    groups: []
})
const tagStatsLoading = ref(false)
const showTagDrawer = ref(false)
const tagSearchKw = ref('')
const tagDrawerActiveGroups = ref<string[]>([])

const filteredTagGroups = computed<TagGroup[]>(() => {
    const kw = tagSearchKw.value.trim().toLowerCase()
    if (!kw) return tagStats.groups
    const result: TagGroup[] = []
    for (const g of tagStats.groups) {
        const groupHit = (g.group_name || '').toLowerCase().includes(kw)
        const tags = g.tags.filter((t) => groupHit || (t.tag_name || '').toLowerCase().includes(kw))
        if (tags.length) {
            result.push({ ...g, tags })
        }
    }
    return result
})

async function loadTagStats(showFeedback = false) {
    tagStatsLoading.value = true
    try {
        const res: any = await qywxCustomerTagStats()
        if (res && typeof res === 'object') {
            tagStats.total_tags = Number(res.total_tags ?? 0)
            tagStats.total_relations = Number(res.total_relations ?? 0)
            tagStats.total_tagged_customers = Number(res.total_tagged_customers ?? 0)
            tagStats.groups = Array.isArray(res.groups) ? res.groups : []
        }
        if (showFeedback) feedback.msgSuccess('已刷新')
    } catch (e: any) {
        if (showFeedback) feedback.msgError(e?.message || '加载标签统计失败')
        console.error('加载标签统计失败', e)
    } finally {
        tagStatsLoading.value = false
    }
}

function openTagDrawer() {
    showTagDrawer.value = true
    // 默认展开第 1 组（最热门）；其余折叠避免首屏太长
    tagDrawerActiveGroups.value = tagStats.groups[0]?.group_name ? [tagStats.groups[0].group_name] : []
    if (tagStats.groups.length === 0) {
        loadTagStats()
    }
}

/** 列表上点击 tag 徽章 → 把这个 tag 加入筛选并重查 */
function addTagToFilter(tagId: string) {
    if (!tagId) return
    if (!queryParams.tag_ids.includes(tagId)) {
        queryParams.tag_ids.push(tagId)
        resetPage()
    }
}

/** 抽屉里点「筛选」→ 用这个 tag 替换当前筛选 + 关闭抽屉 */
function filterByTag(tagId: string) {
    if (!tagId) return
    queryParams.tag_ids = [tagId]
    showTagDrawer.value = false
    resetPage()
}

// ── 今日进入分布 / 明细（事件流水零误差口径） ──────────────────────────────
interface ArrivalStats {
    total: number
    recent_time: number
    hourly: number[]
    by_state: { state: string; count: number }[]
}
interface ArrivalItem {
    id: number
    event_time: number
    user_id: string
    admin_name: string
    external_userid: string
    customer_name: string
    customer_avatar: string
    state: string
    welcome_code: number
}

const arrival = reactive<ArrivalStats>({
    total: 0,
    recent_time: 0,
    hourly: new Array(24).fill(0),
    by_state: []
})
const showArrival = ref(false)
const arrivalListLoading = ref(false)
const arrivalList = reactive<{ total: number; page_no: number; page_size: number; lists: ArrivalItem[] }>({
    total: 0,
    page_no: 1,
    page_size: 20,
    lists: []
})
const currentHour = new Date().getHours()
const hourlyMax = computed(() => Math.max(1, ...arrival.hourly))
function barHeight(c: number) {
    // 柱图容器高度 32px；0 值保留一条 2px 的底线让用户知道"这个小时有格子"
    if (c <= 0) return '2px'
    const ratio = c / hourlyMax.value
    return Math.max(4, Math.round(ratio * 32)) + 'px'
}
const hourlyTooltip = computed(() => {
    const parts: string[] = []
    arrival.hourly.forEach((c, h) => {
        if (c > 0) parts.push(`${String(h).padStart(2, '0')}:00 · ${c}`)
    })
    return parts.length ? parts.join('  ') : '今天还没有人进入'
})

async function loadArrival(refreshList = false) {
    try {
        const res: any = await qywxCustomerTodayArrival()
        if (res) {
            arrival.total = Number(res.total ?? 0)
            arrival.recent_time = Number(res.recent_time ?? 0)
            arrival.hourly = Array.isArray(res.hourly) && res.hourly.length === 24
                ? res.hourly.map((n: any) => Number(n) || 0)
                : new Array(24).fill(0)
            arrival.by_state = Array.isArray(res.by_state) ? res.by_state : []
        }
    } catch (e) {
        console.error('加载今日进入分布失败', e)
    }
    if (refreshList && showArrival.value) {
        arrivalList.page_no = 1
        arrivalList.lists = []
        await fetchArrivalPage()
    }
}

async function fetchArrivalPage() {
    arrivalListLoading.value = true
    try {
        const res: any = await qywxCustomerTodayArrivalList({
            page_no: arrivalList.page_no,
            page_size: arrivalList.page_size
        })
        if (res) {
            arrivalList.total = Number(res.total ?? 0)
            const rows: ArrivalItem[] = Array.isArray(res.lists) ? res.lists : []
            if (arrivalList.page_no === 1) {
                arrivalList.lists = rows
            } else {
                arrivalList.lists.push(...rows)
            }
        }
    } catch (e) {
        console.error('加载今日进入明细失败', e)
    } finally {
        arrivalListLoading.value = false
    }
}

async function openArrivalDrawer() {
    showArrival.value = true
    arrivalList.page_no = 1
    arrivalList.lists = []
    // 分布和明细一起刷新，确保抽屉里看到的数字和外面卡片一致
    await Promise.all([loadArrival(false), fetchArrivalPage()])
}

async function loadMoreArrival() {
    if (arrivalList.lists.length >= arrivalList.total) return
    arrivalList.page_no += 1
    await fetchArrivalPage()
}

function formatHm(ts: number) {
    if (!ts || ts <= 0) return ''
    const d = new Date(ts < 1e12 ? ts * 1000 : ts)
    return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`
}
function formatHms(ts: number) {
    if (!ts || ts <= 0) return '—'
    const d = new Date(ts < 1e12 ? ts * 1000 : ts)
    return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')}`
}

let syncTimer: number | null = null
/** 后台同步完成后轮询统计，直到非「同步中」 */
let pollSyncTimer: number | null = null

function stopPollSync() {
    if (pollSyncTimer !== null) {
        clearInterval(pollSyncTimer)
        pollSyncTimer = null
    }
}

async function fetchLists(params: Record<string, unknown>) {
    return qywxCustomerLists(params)
}

const { pager, getLists, resetPage, resetParams } = usePaging({
    fetchFun: fetchLists,
    params: queryParams
})

function handleReset() {
    queryParams.name = ''
    queryParams.follow_user = ''
    queryParams.tag_ids = []
    queryParams.add_time_start = ''
    queryParams.add_time_end = ''
    addTimeRange.value = null
    resetParams()
}

function startPollSyncUntilIdle() {
    stopPollSync()
    let ticks = 0
    pollSyncTimer = window.setInterval(async () => {
        ticks += 1
        await loadStats()
        await getLists()
        if (stats.syncStatus !== 'syncing' || ticks >= 120) {
            stopPollSync()
            syncing.value = false
            if (ticks >= 120 && stats.syncStatus === 'syncing') {
                feedback.msgWarning('长时间仍为「同步中」，请刷新页面或查看服务器 runtime/log/qywx_sync.log（可能未安装 CLI php 或禁用了 exec）')
            } else if (stats.syncStatus === 'failed') {
                feedback.msgError('同步失败，请查看服务器 runtime/log/qywx_sync.log 或后台同步状态')
            }
        }
    }, 3000)
}

async function syncCustomers(options?: { silent?: boolean }) {
    const silent = options?.silent === true
    syncing.value = true
    try {
        const res: any = await qywxCustomerSync()
        if (!silent) {
            feedback.msgSuccess(res?.message || '操作成功')
        }
        await loadStats()
        await getLists()
        if (res?.background) {
            startPollSyncUntilIdle()
        } else {
            syncing.value = false
        }
    } catch (e: any) {
        const msg = e?.message || e?.msg || '同步失败'
        if (!silent || !String(msg).includes('正在执行')) {
            feedback.msgError(msg)
        }
        syncing.value = false
    }
}

async function loadStats() {
    try {
        const res: any = await qywxCustomerStats()
        if (res && typeof res === 'object') {
            Object.assign(stats, res)
        }
    } catch (e) {
        console.error('加载统计失败', e)
    }
}

async function loadSyncSettings() {
    try {
        const res: any = await qywxSyncSettingsGet()
        if (res && typeof res === 'object') {
            Object.assign(syncSettings, res)
        }
        
        // 如果开启了自动同步，启动定时器
        if (syncSettings.auto_sync) {
            startSyncTimer()
        }
    } catch (e) {
        console.error('加载同步设置失败', e)
    }
}

async function saveSyncSettings() {
    try {
        await qywxSyncSettingsSave(syncSettings)
        feedback.msgSuccess('保存成功')
        showSyncSettings.value = false
        
        // 重新启动定时器
        stopSyncTimer()
        if (syncSettings.auto_sync) {
            startSyncTimer()
        }
    } catch (e: any) {
        feedback.msgError(e?.message || '保存失败')
    }
}

function startSyncTimer() {
    if (syncTimer) return
    
    syncTimer = window.setInterval(() => {
        syncCustomers({ silent: true })
    }, syncSettings.interval * 1000)
}

function stopSyncTimer() {
    if (syncTimer) {
        clearInterval(syncTimer)
        syncTimer = null
    }
}

function viewDetail(row: any) {
    currentCustomer.value = row
    showDetail.value = true
}

/** 列表接口会写入 admin_name（admin.work_wechat_userid = userid） */
function formatFollowUser(user: Record<string, any>) {
    const adminName = String(user?.admin_name ?? '').trim()
    const id = String(user?.userid ?? '').trim()
    const name = String(user?.name ?? '').trim()
    if (adminName) return adminName
    if (name && id) return `${name}（${id}）`
    if (name) return name
    if (id) return id
    return '—'
}

function followStaffTooltip(user: Record<string, any>) {
    const adminName = String(user?.admin_name ?? '').trim()
    const id = String(user?.userid ?? '').trim()
    const parts: string[] = []
    if (adminName) parts.push('后台：' + adminName)
    if (id) parts.push('企微：' + id)
    return parts.join('｜')
}

/**
 * 添加时间：优先接口字段 external_first_add_time（同步写入 + 列表对未回填行按 JSON 兜底）；
 * 再解析 follow_users；最后退回 create_time
 */
function firstExternalAddTime(row: Record<string, any> | null | undefined): number | string | null {
    if (!row) return null
    const fromApi = Number(row.external_first_add_time ?? 0)
    if (fromApi > 0) return fromApi
    const users = row.follow_users
    if (Array.isArray(users) && users.length > 0) {
        let min = 0
        for (const u of users) {
            const t = Number(u?.createtime ?? 0)
            if (t > 0 && (min === 0 || t < min)) min = t
        }
        if (min > 0) return min
    }
    return row.create_time ?? null
}

function formatTime(timestamp: number | string | null | undefined) {
    if (timestamp === '' || timestamp === null || timestamp === undefined) return '—'
    const n = Number(timestamp)
    const isNumericString = typeof timestamp === 'string' && /^\d+$/.test(timestamp.trim())
    let ms: number
    if (typeof timestamp === 'number') {
        ms = timestamp < 1e12 ? timestamp * 1000 : timestamp
    } else if (!Number.isNaN(n) && isNumericString) {
        ms = n < 1e12 ? n * 1000 : n
    } else {
        ms = new Date(timestamp).getTime()
    }
    if (Number.isNaN(ms)) return '—'
    return new Date(ms).toLocaleString('zh-CN')
}

/** 今日进入分布 30s 轮询：回调一到，事件流水立刻能反映在卡片上 */
let arrivalPollTimer: number | null = null
function startArrivalPolling() {
    if (arrivalPollTimer !== null) return
    arrivalPollTimer = window.setInterval(() => {
        loadStats()
        loadArrival(showArrival.value)
    }, 30000)
}
function stopArrivalPolling() {
    if (arrivalPollTimer !== null) {
        clearInterval(arrivalPollTimer)
        arrivalPollTimer = null
    }
}

onMounted(() => {
    getLists()
    loadStats()
    loadSyncSettings()
    loadArrival(false)
    loadTagStats()
    startArrivalPolling()
})

onUnmounted(() => {
    stopSyncTimer()
    stopPollSync()
    stopArrivalPolling()
})
</script>

<style scoped lang="scss">
.qywx-customer-page {
    max-width: 1400px;
    margin: 0 auto;
}

.today-arrival-card {
    transition: transform 0.15s ease, box-shadow 0.15s ease;

    &:hover {
        transform: translateY(-1px);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    }
}

.hourly-bars {
    display: grid;
    grid-template-columns: repeat(24, 1fr);
    align-items: end;
    gap: 2px;
    height: 32px;

    .hourly-bar {
        background: var(--el-color-success);
        border-radius: 2px 2px 0 0;
        min-height: 2px;
        transition: height 0.3s ease;

        &.is-empty {
            background: var(--el-border-color-lighter);
        }

        &.is-current {
            outline: 1px solid var(--el-color-success-dark-2);
            outline-offset: -1px;
        }
    }
}
</style>
