<template>
    <el-dialog v-model="dialogVisible" title="派单调度" width="900px" top="5vh" destroy-on-close append-to-body>
        <div class="dispatch-dialog-content">
            <!-- Top: Order Info (OrderDispatch Style) -->
            <div class="dispatch-order-info" v-if="localOrder">
                <div class="list-card order-card" style="margin:0; box-shadow:none; cursor:default; border:none;">
                    <div class="card-left">
                        <div class="type-tag" :class="localOrder.typeCode">
                            {{ getShortType(localOrder.typeCode) }}
                        </div>
                    </div>
                    <div class="card-main">
                        <template v-if="localOrder.typeCode === 'transport'">
                            <div class="row-addr" :title="localOrder.pickAddr">
                                <span class="tag pick">取</span> {{ localOrder.pickAddr }}
                            </div>
                            <div class="row-addr" :title="localOrder.dropAddr">
                                <span class="tag drop">送</span> {{ localOrder.dropAddr }}
                            </div>
                        </template>
                        <template v-else>
                            <div class="row-addr" :title="localOrder.address">
                                <span class="tag home">址</span> {{ localOrder.address }}
                            </div>
                        </template>
                        <div class="row-time" style="margin-top: 4px;">
                            <el-icon>
                                <Clock />
                            </el-icon> {{ localOrder.time }}
                            <span class="days-tag" v-if="localOrder.daysLater">{{ localOrder.daysLater }}</span>
                        </div>
                        <div class="row-remark" style="margin-top: 4px; font-size: 13px; color: #606266;">
                            备注: {{ localOrder.remark || '-' }}
                        </div>
                    </div>
                    <!-- 新增右侧按钮组 -->
                    <div class="card-right"
                        style="display: flex; flex-direction: column; align-items: flex-end; justify-content: center; gap: 8px; padding-left: 20px;">
                        <div style="display: flex; gap: 10px;">
                            <el-button type="primary" size="small" plain round icon="User" @click="openCustomerDetail"
                                :loading="orderInfoLoading">用户档案</el-button>
                            <el-button type="success" size="small" plain round @click="openPetDetail"
                                :loading="orderInfoLoading" style="margin-left: 0;">宠物档案</el-button>
                        </div>
                        <el-button type="warning" size="small" plain disabled
                            style="width: 100%; border-color: #f3d19e; color: #e6a23c; opacity: 1; cursor: default; justify-content: center;">
                            团购套餐: {{ localOrder.groupPurchasePackageName || '-' }}
                        </el-button>
                    </div>
                </div>
            </div>

            <!-- Current Rider Info (If Exists) -->
            <div class="current-rider-section" v-if="currentRider">
                <div class="select-header" style="margin-bottom:8px;">
                    <span class="tit">当前派单履约者</span>
                </div>
                <div class="list-card rider-card"
                    style="margin-bottom: 20px; border: 1px solid #e4e7ed; background:#fafafa; cursor:default;">
                    <div class="card-left relative">
                        <el-avatar :src="currentRider.avatarUrl || currentRider.avatar" :size="40" />
                    </div>
                    <div class="card-main">
                        <div class="row-1"
                            style="justify-content: space-between; align-items: flex-start; display: flex;">
                            <div style="display:flex; align-items:baseline; gap:8px;">
                                <span class="r-name">{{ currentRider.name || '--' }}</span>
                                <span class="r-phone">{{ currentRider.phone || '--' }}</span>
                                <dict-tag :options="sys_user_sex" :value="currentRider.gender" />
                                <el-tag v-if="currentRider.status" size="small"
                                    :type="getStatusType(currentRider.status)" effect="plain">
                                    {{ getStatusText(currentRider.status) }}
                                </el-tag>
                            </div>
                        </div>

                        <div class="row-2 categories-row"
                            style="margin-top: 6px; display:flex; gap:4px; flex-wrap:wrap;">
                            <el-tag
                                v-for="typeId in (currentRider.serviceTypes ? String(currentRider.serviceTypes).split(',') : [])"
                                :key="typeId" size="small" type="primary" effect="plain">{{ getServiceTypeText(typeId)
                                }}</el-tag>
                        </div>
                        <div class="row-3 time-row" style="margin-top: 4px;">
                            <span class="last-time">下一单: {{ currentRider.nextOrderTime || '-' }}</span>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Middle: Rider Selection -->
            <div class="dispatch-rider-select">
                <div class="select-header">
                    <span class="tit">选择履约者</span>
                    <el-input v-model="dispatchSearchQuery" placeholder="搜索履约者姓名/手机号" prefix-icon="Search" clearable
                        style="width: 240px" />
                </div>

                <div class="rider-grid-wrapper">
                    <el-scrollbar class="rider-scroll">
                        <div class="rider-grid">
                            <div v-for="rider in filteredDispatchRiders" :key="rider.id"
                                class="list-card rider-card select-card"
                                :class="{ active: selectedRiderId === rider.id }" @click="selectedRiderId = rider.id">
                                <!-- Reusing Rider Card Layout -->
                                <div class="card-left relative">
                                    <el-avatar :src="rider.avatarUrl || rider.avatar" :size="40" />
                                </div>
                                <div class="card-main">
                                    <div class="row-1"
                                        style="justify-content: space-between; align-items: flex-start; display: flex;">
                                        <div style="display:flex; align-items:baseline; gap:8px;">
                                            <span class="r-name">{{ rider.name || '--' }}</span>
                                            <span class="r-phone">{{ rider.phone || '--' }}</span>
                                            <dict-tag :options="sys_user_sex" :value="rider.gender" />
                                        </div>
                                        <el-tag v-if="rider.status" size="small" :type="getStatusType(rider.status)"
                                            effect="plain">
                                            {{ getStatusText(rider.status) }}
                                        </el-tag>
                                    </div>

                                    <div class="row-2 categories-row"
                                        style="margin-top: 6px; display:flex; gap:4px; flex-wrap:wrap;">
                                        <el-tag
                                            v-for="typeId in (rider.serviceTypes ? String(rider.serviceTypes).split(',') : [])"
                                            :key="typeId" size="small" type="primary" effect="plain">{{
                                            getServiceTypeText(typeId)
                                            }}</el-tag>
                                    </div>
                                    <div class="row-3 time-row" style="margin-top: 4px">
                                        <span class="last-time">下一单: {{ rider.nextOrderTime || '-' }}</span>
                                    </div>
                                </div>

                                <!-- Selected Check -->
                                <div class="selected-mark" v-if="selectedRiderId === rider.id">
                                    <el-icon>
                                        <Check />
                                    </el-icon>
                                </div>
                            </div>

                            <div v-if="filteredDispatchRiders.length === 0" class="empty-text">暂无符合条件的履约者</div>
                        </div>
                    </el-scrollbar>
                </div>

                <div class="rider-pagination" style="margin-top: 20px;">
                    <el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize"
                        :page-sizes="[10, 20, 50]" layout="total, sizes, prev, pager, next" :total="total"
                        @current-change="loadRiders" @size-change="handlePageSizeChange" />
                </div>
            </div>

            <div class="dispatch-footer">
                <div class="fee-inputs" style="display: flex; align-items: center;">
                    <div class="fee-input">
                        <span class="label">履约佣金：</span>
                        <el-input-number v-model="dispatchFee" :min="0" :precision="2" :step="10" placeholder="请输入"
                            style="width: 130px;" />
                        <span class="unit">元</span>
                    </div>
                    <div class="fee-input" style="margin-left: 20px;">
                        <span class="label">订单佣金：</span>
                        <el-input-number v-model="orderCommission" :min="0" :precision="2" :step="10" placeholder="请输入"
                            style="width: 130px;" />
                        <span class="unit">元</span>
                    </div>
                </div>
                <div class="btns">
                    <el-button @click="dialogVisible = false">取消</el-button>
                    <el-button type="primary" :disabled="!canSubmit" @click="handleDispatchSubmit">确认派单</el-button>
                </div>
            </div>
        </div>
    </el-dialog>

    <CustomerDetailDrawer v-model:visible="customerDialogVisible" :customer-id="customerId"
        :area-station-list="areaStationList" />
    <PetDetailDrawer v-model:visible="petDialogVisible" :pet-id="petId" />
</template>

<script setup>
import { ref, computed, watch, getCurrentInstance, toRefs } from 'vue'
import { ElMessage } from 'element-plus'
import { pageFulfillerOnOrder } from '@/api/fulfiller/pool'
import { listAllTag } from '@/api/fulfiller/tag'
import { getSubOrderInfo } from '@/api/order/subOrder/index'
import { listAllService } from '@/api/service/list/index'
import { listAreaStation } from '@/api/system/areaStation/index'
import { dispatchSubOrder } from '@/api/order/subOrder/index'
import { getFulfiller } from '@/api/fulfiller/fulfiller/index'
import CustomerDetailDrawer from '@/components/CustomerDetailDrawer/index.vue'
import PetDetailDrawer from '@/components/PetDetailDrawer/index.vue'

const props = defineProps({
    visible: Boolean,
    order: Object
})
const emit = defineEmits(['update:visible', 'success'])

const { proxy } = getCurrentInstance();
const { sys_user_sex } = toRefs(proxy.useDict('sys_user_sex'));

const dialogVisible = computed({
    get: () => props.visible,
    set: (val) => emit('update:visible', val)
})

const ridersList = ref([])
const total = ref(0)
const pageNum = ref(1)
const pageSize = ref(10)

const allTags = ref([])
const tagMap = computed(() => {
    const map = {}
    for (const t of (allTags.value || [])) {
        if (t && t.id !== undefined && t.id !== null) map[t.id] = t
    }
    return map
})

const currentRider = ref(null)
const dispatchSearchQuery = ref('')
const selectedRiderId = ref(null)
const dispatchFee = ref(0)
const orderCommission = ref(0)
const localOrder = ref(null)

const customerDialogVisible = ref(false)
const petDialogVisible = ref(false)
const customerId = ref(null)
const petId = ref(null)
const orderInfoLoading = ref(false)

const loadAllTags = async () => {
    if (allTags.value && allTags.value.length > 0) return
    try {
        const res = await listAllTag({ category: 'fulfiller' })
        allTags.value = res?.data || []
    } catch {
        allTags.value = []
    }
}

const serviceOptions = ref([])
const loadServiceOptions = async () => {
    if (serviceOptions.value.length > 0) return
    try {
        const res = await listAllService()
        serviceOptions.value = res?.data || []
    } catch { /* ignore */ }
}

const areaStationList = ref([])
const loadAreaStationList = async () => {
    if (areaStationList.value.length > 0) return
    try {
        const res = await listAreaStation()
        areaStationList.value = res.data || []
    } catch { /* ignore */ }
}

const getServiceTypeText = (id) => {
    const s = serviceOptions.value.find(item => String(item.id) === String(id))
    return s ? s.name : String(id)
}

const loadRiders = async () => {
    try {
        const res = await pageFulfillerOnOrder({
            content: dispatchSearchQuery.value || undefined,
            pageNum: pageNum.value,
            pageSize: pageSize.value,
            service: localOrder.value?.service,
            orderId: localOrder.value?.id
        })
        const list = res?.rows || []
        ridersList.value = list.map(r => ({
            ...r,
            nextOrderTime: r.nextOrderTime || '-',
            gender: r.gender ?? r.sex
        }))
        total.value = res?.total || 0

        if (localOrder.value?.riderId) {
            const found = ridersList.value.find(r => r.id === localOrder.value.riderId)
            if (found) {
                currentRider.value = { ...found }
            }
        }
    } catch {
        ridersList.value = []
        total.value = 0
    }
}

const handlePageSizeChange = (size) => {
    pageSize.value = size
    pageNum.value = 1
    loadRiders()
}

watch(() => props.visible, async (val) => {
    if (val && props.order) {
        // 1. 初始化 localOrder，处理模型转换逻辑 @Author: Antigravity
        const raw = { ...props.order }

        // 确保基本属性存在，如果不完整则从 props.order 推导 (统一两个页面的逻辑)
        const isTransport = raw.mode === 1 || raw.mode === '1' || raw.type === 'transport' || raw.typeCode === 'transport'
        if (!raw.typeCode) raw.typeCode = isTransport ? 'transport' : 'feeding'

        const toAddr = raw.toAddress || raw.address || ''
        if (isTransport) {
            if (!raw.pickAddr) raw.pickAddr = raw.fromAddress || toAddr
            if (!raw.dropAddr) raw.dropAddr = toAddr
        } else {
            if (!raw.address) raw.address = toAddr
        }

        if (!raw.time) raw.time = raw.serviceTime || raw.appointTime || raw.createTime
        if (!raw.service && raw.serviceId) raw.service = raw.serviceId
        if (!raw.riderId && raw.fulfiller) raw.riderId = raw.fulfiller

        localOrder.value = raw

        currentRider.value = null
        dispatchSearchQuery.value = ''
        selectedRiderId.value = null

        // 金额单位转换
        dispatchFee.value = localOrder.value?.fulfillmentCommission ? Number((localOrder.value.fulfillmentCommission / 100).toFixed(2)) : 0
        orderCommission.value = localOrder.value?.orderCommission ? Number((localOrder.value.orderCommission / 100).toFixed(2)) : 0

        if (localOrder.value?.riderId) {
            currentRider.value = {
                id: localOrder.value.riderId,
                gender: localOrder.value.riderGender ?? localOrder.value.riderSex
            }
        }

        pageNum.value = 1
        loadAllTags()
        await loadServiceOptions() // 等待加载以便后面 getServiceTypeText 准确
        loadAreaStationList()
        loadRiders()

        // 2. 获取订单详细信息
        customerId.value = null
        petId.value = null
        orderInfoLoading.value = true
        getSubOrderInfo(localOrder.value.id).then((res) => {
            if (res.data) {
                const info = res.data
                customerId.value = info.usrCustomer?.id || info.usrCustomer
                petId.value = info.usrPet?.id || info.usrPet

                // 详情覆盖
                if (info.fulfillmentCommission !== undefined) {
                    dispatchFee.value = Number((info.fulfillmentCommission / 100).toFixed(2))
                }
                if (info.orderCommission !== undefined) {
                    orderCommission.value = Number((info.orderCommission / 100).toFixed(2))
                }

                // 再次修正 typeCode
                const detailIsTransport = info.mode === 1 || info.mode === '1'
                const serviceName = getServiceTypeText(info.service)
                const typeCode = detailIsTransport ? 'transport' : (serviceName?.includes('洗') ? 'washing' : 'feeding')

                localOrder.value = {
                    ...localOrder.value,
                    ...info,
                    typeCode,
                    time: info.serviceTime || localOrder.value.time,
                    pickAddr: (detailIsTransport ? (info.fromAddress || info.pickAddr) : undefined) || localOrder.value.pickAddr,
                    dropAddr: (detailIsTransport ? (info.toAddress || info.dropAddr) : undefined) || localOrder.value.dropAddr,
                    address: (!detailIsTransport ? (info.address || info.toAddress) : undefined) || localOrder.value.address
                }

                // 显式补全当前履约者信息 (同步两个页面的显示) @Author: Antigravity
                const fId = info.fulfiller || info.riderId || info.fulfillerId
                if (fId) {
                    getFulfiller(fId).then(riderRes => {
                        if (riderRes.data) {
                            const r = riderRes.data
                            currentRider.value = {
                                id: fId,
                                name: r.name || info.fulfillerName,
                                phone: r.phone || info.fulfillerPhone,
                                avatar: r.avatarUrl || r.avatar || info.fulfillerAvatar,
                                gender: r.gender ?? r.sex ?? (info.fulfillerGender ?? info.fulfillerSex),
                                status: r.status || info.fulfillerStatus,
                                serviceTypes: r.serviceTypes || info.fulfillerServiceTypes,
                                nextOrderTime: r.nextOrderTime || '-'
                            }
                        }
                    })
                }
            }
        }).catch((e) => {
            console.error('获取订单详细信息失败', e)
        }).finally(() => {
            orderInfoLoading.value = false
        })
    }
})

const openCustomerDetail = () => {
    if (!customerId.value) {
        ElMessage.warning('未能获取到用户信息')
        return
    }
    customerDialogVisible.value = true
}

const openPetDetail = () => {
    if (!petId.value) {
        ElMessage.warning('未能获取到宠物信息')
        return
    }
    petDialogVisible.value = true
}

const getTagText = (tagId) => {
    const t = tagMap.value?.[tagId]
    return t?.name || String(tagId)
}

const getTagType = (tagId) => {
    const t = tagMap.value?.[tagId]
    const type = t?.colorType
    if (type === 'success' || type === 'warning' || type === 'danger' || type === 'info') return type
    return ''
}

watch(dispatchSearchQuery, () => {
    pageNum.value = 1
    loadRiders()
})

const getShortType = (code) => {
    const map = { 'transport': '接送', 'feeding': '喂遛', 'washing': '洗护' }
    return map[code] || '订单'
}

const getStatusText = (status) => {
    const statusMap = {
        resting: '休息',
        busy: '接单中',
        disabled: '禁用'
    }
    return statusMap[status] || status
}

const getStatusType = (status) => {
    const typeMap = {
        resting: 'info',
        busy: 'success',
        disabled: 'danger'
    }
    return typeMap[status] || 'info'
}

const filteredDispatchRiders = computed(() => {
    return ridersList.value || []
})

const canSubmit = computed(() => {
    return !!selectedRiderId.value && !!dispatchFee.value
})

const handleDispatchSubmit = async () => {
    if (!selectedRiderId.value) {
        ElMessage.warning('请选择履约者')
        return
    }
    if (!dispatchFee.value) {
        ElMessage.warning('请输入服务费用')
        return
    }

    try {
        const payload = {
            orderId: localOrder.value.id,
            fulfiller: selectedRiderId.value,
            fulfillmentCommission: Math.round(dispatchFee.value * 100),
            orderCommission: Math.round(orderCommission.value * 100)
        }
        await dispatchSubOrder(payload)
        ElMessage.success('派单成功')
        emit('success')
        dialogVisible.value = false
    } catch (e) {
        // 请求拦截器已处理异常，如需特殊处理可在此增加
    }
}
</script>

<style scoped>
/* Dispatch Dialog Styles */
.list-card {
    background: #fff;
    border: 1px solid #ebeef5;
    border-radius: 8px;
    padding: 12px;
    margin-bottom: 10px;
    display: flex;
    align-items: stretch;
    gap: 12px;
    transition: all 0.2s;
    cursor: pointer;
}

.list-card:hover {
    border-color: #c6e2ff;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.card-left {
    flex-shrink: 0;
    display: flex;
    align-items: center;
}

.order-card .type-tag {
    width: 40px;
    height: 40px;
    border-radius: 8px;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: bold;
}

.type-tag.transport {
    background: #e6a23c;
}

.type-tag.feeding {
    background: #67c23a;
}

.type-tag.washing {
    background: #409eff;
}

.card-main {
    flex: 1;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
}

.row-addr {
    font-size: 13px;
    color: #303133;
    display: flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.5;
}

.row-addr .tag {
    font-size: 11px;
    color: #fff;
    padding: 1px 4px;
    border-radius: 4px;
    flex-shrink: 0;
    transform: scale(0.9);
}

.tag.pick {
    background: #409eff;
}

.tag.drop {
    background: #e6a23c;
}

.tag.home {
    background: #67c23a;
}

.row-time {
    font-size: 12px;
    color: #909399;
    display: flex;
    align-items: center;
    gap: 4px;
}

.days-tag {
    color: #f56c6c;
    background: #fef0f0;
    padding: 0 4px;
    border-radius: 4px;
    font-size: 11px;
    border: 1px solid #fde2e2;
    transform: scale(0.95);
}

.dispatch-order-info {
    background: #f5f7fa;
    padding: 10px;
    border-radius: 4px;
    margin-bottom: 20px;
    border: 1px solid #e4e7ed;
    display: block;
}

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

.dispatch-rider-select .tit {
    font-weight: bold;
    font-size: 14px;
}

.rider-scroll {
    max-height: 45vh;
}

.rider-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
    padding-right: 10px;
}

.rider-pagination {
    margin-top: 10px;
}

.rider-card.select-card {
    cursor: pointer;
    border: 1px solid #dcdfe6;
    position: relative;
    transition: all 0.2s;
    margin-bottom: 0;
}

.rider-card.select-card:hover {
    border-color: #409eff;
}

.rider-card.select-card.active {
    border-color: #409eff;
    background-color: #ecf5ff;
}

.selected-mark {
    position: absolute;
    top: 0;
    right: 0;
    background: #409eff;
    color: #fff;
    border-bottom-left-radius: 6px;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
}

.rider-card .card-left .dot {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 2px solid #fff;
}

.dot.online {
    background: #67c23a;
}

.dot.busy {
    background: #409eff;
}

.dot.offline {
    background: #909399;
}

.r-name {
    font-weight: bold;
    font-size: 14px;
    color: #303133;
    margin-right: 8px;
}

.r-phone {
    font-size: 12px;
    color: #909399;
}

.status-badge {
    font-size: 11px;
    padding: 2px 6px;
    border-radius: 4px;
    display: inline-block;
    font-weight: bold;
}

.status-badge.online {
    background: #f0f9eb;
    color: #67c23a;
}

.status-badge.busy {
    background: #ecf5ff;
    color: #409eff;
}

.status-badge.offline {
    background: #f4f4f5;
    color: #909399;
}

.cat-tag {
    background: #f4f4f5;
    color: #909399;
    font-size: 10px;
    padding: 1px 4px;
    border-radius: 2px;
    margin-right: 4px;
}

.cat-tag.cat-transport {
    background: #e6f7ff;
    color: #1890ff;
    border: 1px solid #91d5ff;
}

.cat-tag.cat-feeding {
    background: #f6ffed;
    color: #52c41a;
    border: 1px solid #b7eb8f;
}

.cat-tag.cat-washing {
    background: #fff0f6;
    color: #eb2f96;
    border: 1px solid #ffadd2;
}

.last-time {
    font-size: 11px;
    color: #999;
}

.empty-text {
    text-align: center;
    color: #909399;
    padding: 20px;
    width: 100%;
    grid-column: span 2;
}

.dispatch-footer {
    margin-top: 20px;
    padding-top: 20px;
    border-top: 1px solid #ebeef5;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.dispatch-footer .fee-input {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
}
</style>
