<template>
    <!--
        校车点名页面（临时从班主任点名复制）
        功能：后续将改为校车点名首页与流程入口
    -->
    <view class="page-container">
        
        <!-- 固定头部区域 不在考勤时间段、摘要模式时不显示 -->
        <view class="fixed-header" v-if="!isNotInTime && !isSummaryMode"> 
            <!-- 筛选条件区域 -->
            <view class="filter-area">
                <view class="full-form" style="position: relative;z-index: 1000;">
                    <Form :rules="fieldConfigs" v-model="formData" ref="formRef">
                        <up-table>
                            <up-tr>
                                <up-th>车牌号</up-th>
                                <Td field="carNo">
                                    <view class="readonly-field">
                                        <text class="readonly-text">{{ formData.carNo }}</text>
                                    </view>
                                </Td>
                            </up-tr>
                            <up-tr>
                                <up-th>日期</up-th>
                                <Td field="rq">
                                    <SsDatetimePicker v-model="formData.rq" mode="date" :max-date="maxDate"
                                        :z-index="99999" placeholder="请选择日期" @change="onDateChange" :disabled="true" />
                                    <text v-if="weekdayText" class="weekday-text">{{ weekdayText }}</text>
                                </Td>
                            </up-tr>
                            <up-tr>
                                <up-th>节次</up-th>
                                <Td field="jc">
                                    <view class="onoff-button-group">
                                        <SsOnoffButton v-model="formData.jc" name="jc" label="上午" value="1" :disabled="true" />
                                        <SsOnoffButton v-model="formData.jc" name="jc" label="下午" value="2" :disabled="true" />
                                    </view>
                                </Td>
                            </up-tr>
                        </up-table>
                    </Form>
                </view>
            </view>

            <!-- 站点进度（mock，固定7个点，第4个永远是中心点） -->
            <view class="stop-progress" catchtouchmove="true" @touchstart.stop="handleStopTouchStart"
                @touchmove.stop="handleStopTouchMove" @touchend.stop="handleStopTouchEnd"
                @touchcancel.stop="handleStopTouchEnd">
            <view class="stop-track">
                <template v-for="slot in 7" :key="slot">
                    <view class="stop-node" :class="{ center: slot === 4 }"
                        @tap.stop="handleStopTap(slot - 1)">
                        <view class="stop-dot" :class="getStopDotClass(slot - 1)"></view>
                    </view>
                    <view v-if="slot < 7" class="stop-line" :class="getStopLineClass(slot - 1)"></view>
                </template>
            </view>
            <view class="stop-label-row">
                <text class="stop-label-side stop-label-prev">{{ prevStopName }}</text>
                <text class="stop-label-current">{{ currentStopName }}</text>
                <text class="stop-label-side stop-label-next">{{ nextStopName }}</text>
            </view>
        </view>

            <!-- 考勤统计（临时展示） -->
            <view class="stats-area" v-if="!isSummaryMode && !isNotInTime">
                <view class="stats-left">
                    <text class="stat-parent">家长请假:</text>
                    <text>{{ parentLeaveCount }}人</text>
                </view>
                <view class="stats-right">{{ rollcallProgressText }}</view>
            </view>

        </view>

        
        <!-- 不在时间范围 -->
        <view v-else-if="isNotInTime" class="isNotInTime">
            <view class="isNotInTime-title">
                <Icon name="icon-naoling" size="97" color="#ff7e00" />
                当前不在校车接送时段！
            </view>

            <view class="isNotInTime-content">
                <!-- <view class="isNotInTime-content-title">接送时段</view>
                <view v-if="notInTimeMsg" class="isNotInTime-content-tip">{{ notInTimeMsg }}</view> -->
                <view v-for="item in NotInTime" class="isNotInTime-content-item">
                    <view class="isNotInTime-content-item-icon">
                        <Icon :name="item.icon" :size="item.iconSize" :color="item.iconColor" />
                    </view>
                    <view>
                        <view>{{ item.title }}</view>
                        <view>{{ item.range }}</view>
                    </view>
                </view>
            </view>
        </view>

        <!-- 提交后摘要显示（仅显示缺勤/请假人数） -->
        <view v-if="isSummaryMode" class="summary-area">

            <view class="stats-section">
                <view class="stat-item">
                    <text class="stat-label">点名情况:</text>
                    <text class="stat-value absent">已点名</text>
                </view>
                <view class="stat-item">
                    <text class="stat-label">点名人数:</text>
                    <text class="stat-value absent">{{ summaryJsrs }}人</text>
                </view>
                <view class="stat-item">
                    <text class="stat-label">请假:</text>
                    <text class="stat-value leave">{{ summaryQjrs }}人</text>
                </view>
                <view class="stat-item">
                    <text class="stat-label">未上车:</text>
                    <text class="stat-value absent">{{ summaryOffCount }}人</text>
                </view>
            </view>
        </view>

        <!-- 学生列表区域 -->
        <view v-else class="student-table-wrapper" :style="studentTableWrapperStyle">
            <view class="student-table">
                <!-- 表头（固定，不随列表滚动） -->
                <view class="table-header">
                    <text class="col-name">姓名</text>
                    <text class="col-class">班级</text>
                    <text class="col-status">状态</text>
                </view>

                <!-- 学生行（滚动区域） -->
                <scroll-view class="student-list-area" scroll-y :scroll-into-view="scrollIntoViewId"
                    :scroll-with-animation="true" @scroll="handleStudentListScroll" @click="closeAllSwipeStates">
                    <view v-for="(student, index) in displayZdcyList" :key="student.zdryid" class="row-wrapper"
                        :id="'row_' + student.zdryid" :class="{ swiped: swipeStates[student.zdryid] }"
                        :style="{ '--actions-width': actionWidth(student) + 'rpx' }"
                        @touchstart="handleTouchStart($event, student.zdryid)"
                        @touchmove.stop="handleTouchMove($event, student.zdryid)"
                        @touchend="handleTouchEnd($event, student.zdryid)"
                        @touchcancel="handleTouchEnd($event, student.zdryid)">
                        <view class="table-row" :class="getRowClass(student)" @tap="handleStudentTap(student)">
                            <text class="col-name">{{ student.xm }}</text>
                            <text class="col-class">{{ student.bjid }}</text>
                            <text class="col-status">{{ getStatusText(student) }}</text>
                            <view class="drag-indicator" :style="getDragIndicatorStyle(student)"></view>
                        </view>

                        <view class="swipe-actions" :style="{ width: actionWidth(student) + 'rpx' }">
                            <view v-if="shouldShowException(student)" class="action-btn exception-btn"
                                @click.stop="handleException(student)">异常登记</view>
                            <view class="action-btn phone-btn" @click.stop="handleCallParent(student)">家长电话</view>
                        </view>
                    </view>
                </scroll-view>
            </view>
        </view>

        <!-- 底部按钮（保存） -->
        <SsBottom :buttons="bottomButtons" @button-click="handleBottomAction" v-if="!isSummaryMode && !isNotInTime" />

        <!-- 二次确认弹窗（取消“已上车”） -->
        <SsConfirm v-model:visible="showConfirm" width="90%" height="34vh" :bottom-buttons="confirmButtons"
            @button-click="handleConfirmAction" @close="handleConfirmClose">
            <view class="confirm-message">
                <image class="confirm-icon" src="/static/images/warning.gif" mode="aspectFit" />
                <view class="confirm-text">{{ confirmTextLine1 }}</view>
                <view class="confirm-text">{{ confirmTextLine2 }}</view>
            </view>
        </SsConfirm>
    </view>
</template>

<script setup>
/**
 * 校车点名页面（临时从班主任点名复制）
 *
 * 主要功能：
 * 1. 筛选条件管理（班级、日期、节次）
 * 2. 学生表格显示和状态管理
 * 3. 三行变一行的下拉切换
 * 4. 学生考勤状态管理
 * 5. 考勤数据保存和提交
 */

import { ref, computed, nextTick, getCurrentInstance, defineExpose, watch } from 'vue'
import Form from '@/components/Form/index.vue'
import Td from '@/components/Td/index.vue'
import SsDatetimePicker from '@/components/SsDatetimePicker/index.vue'
import SsOnoffButton from '@/components/SsOnoffButton/index.vue'
import SsBottom from '@/components/SsBottom/index.vue'
import SsConfirm from '@/components/SsConfirm/index.vue'
import { xcdmApi } from '@/api/xcdm'
import { formatDate as utilFormatDate } from '@/utils/date'

import Icon from '@/components/icon/index.vue';

// ==================== 数据定义 ====================

/**
 * 表单数据
 * @property {string} rq - 日期
 * @property {string} jc - 节次 (1-上午, 2-下午)
 */
const formData = ref({
    carNo: '粤A88888',
    rq: '', // 将在初始化时设置为今天
    jc: '', // 将根据当前时间自动设置
})

// 校车点名类别码（接口返回 xcdmlbm）：1=接，51=送
const xcdmlbm = ref(1)
// 当前站点序号（接口返回 curZdxh，1-based）
const curZdxh = ref(1)
// 接口返回：校车ID、接送时间段
const xcid = ref('')
const jskssj = ref('')
const jsjssj = ref('')

// 日期相关数据
const maxDate = ref(new Date()) // 最大日期为今天，禁止选择今天之后的
const weekdayText = ref('') // 星期几的显示文本

/**
 * 页面状态管理
 * @property {Array} zdcyList - 成员列表数据
 */
const isSummaryMode = ref(false) // 是否为提交后的摘要模式
const isNotInTime = ref(false)
// 提交后摘要（接口返回 jsrs/qjrs/ycrs）
const summaryJsrs = ref(0)
const summaryQjrs = ref(0)
const summaryYcrs = ref(0)
const NotInTime = ref([
    {
        icon: 'icon-shangwu',
        iconColor: '#1296db',
        iconSize: 97,
        title: '上午',
        range:'7:40~12:00'
    },
    {
        icon: 'icon-xiawu',
        iconColor: '#dd9900',
        iconSize: 97,
        title: '下午',
        range:'13:40~16:00'
    }
])
const notInTimeMsg = ref('')
const zdcyList = ref([]) // 成员列表（接口返回 zdcyList）
// 列表展示：按站点顺序排序（送时站点倒序）
const displayZdcyList = computed(() => {
    const list = Array.isArray(zdcyList.value) ? zdcyList.value : []
    return [...list].sort((a, b) => {
        const ao = getOrderIndexByZdxh(a?.zdxh)
        const bo = getOrderIndexByZdxh(b?.zdxh)
        if (ao !== bo) return ao - bo
        return Number(a?.zdryid || 0) - Number(b?.zdryid || 0)
    })
})

const bottomButtons = [
    { text: '保存并提交', action: 'save' }
]


// 确认弹窗相关
const showConfirm = ref(false) // 是否显示确认弹窗

/**
 * 计算统计（校车点名）
 */
const stats = computed(() => {
    const leave = zdcyList.value.filter(s => isLeave(s)).length
    const wait = zdcyList.value.filter(s => isWait(s)).length
    const on = zdcyList.value.filter(s => isSuccess(s)).length
    const off = zdcyList.value.filter(s => isUnboard(s)).length
    return { leave, wait, on, off }
})

const parentLeaveCount = computed(() => stats.value.leave)

const totalCount = computed(() => zdcyList.value.length)

const boardedCount = computed(() => stats.value.on)

const rollcallProgressText = computed(() => {
    const left = String(boardedCount.value).padStart(2, '0')
    const right = String(totalCount.value).padStart(2, '0')
    return `${left}/${right} 人`
})

const summaryOffCount = computed(() => (isSummaryMode.value ? summaryYcrs.value : stats.value.off))

/**
 * 计算学生列表区域的样式
 */
const studentTableWrapperStyle = computed(() => {
    const headerPaddingAdjustRpx = 20 // 约 10px，微调顶部间距
    return {
        paddingTop: Math.max(0, headerHeight.value - headerPaddingAdjustRpx) + 'rpx'
    }
})

// 站点列表（接口返回 zdList：[{xh,mc,jc}]）
const zdList = ref([
    { xh: 1, mc: '学校', jc: 'A' },
    { xh: 2, mc: '莲花山头', jc: 'B' },
    { xh: 3, mc: '北塘四环公交站', jc: 'C' },
    { xh: 4, mc: '莲花山(山尾)', jc: 'D' },
    { xh: 5, mc: '碧桂园天玺山', jc: 'E' },
    { xh: 6, mc: '锦城花园', jc: 'F' },
    { xh: 7, mc: '华大路口', jc: 'G' },
    { xh: 8, mc: '海丰中专1站', jc: 'H' },
    { xh: 9, mc: '海丰中专2站', jc: 'I' },
    { xh: 10, mc: '结束点', jc: 'J' },
])

// 送（xcdmlbm=51）时，站点展示倒序（不改后端字段本身）
const displayZdList = computed(() => {
    const list = Array.isArray(zdList.value) ? zdList.value : []
    return xcdmlbm.value === 51 ? [...list].reverse() : list
})

const getOrderIndexByZdxh = (zdxh) => {
    const idx = displayZdList.value.findIndex(z => Number(z?.xh) === Number(zdxh))
    return idx >= 0 ? idx : 0
}

const getStopIndexByZdxh = (zdxh) => getOrderIndexByZdxh(zdxh)

// 实际当前站（由 curZdxh 决定），centerStopIndex 是站点条中间（第4个点）的那个
const actualStopIndex = computed(() => getStopIndexByZdxh(curZdxh.value))
const centerStopIndex = ref(0)

const clampIndex = (idx, max) => Math.min(max, Math.max(0, idx))

const slotStopIndices = computed(() => {
    const stops = displayZdList.value
    if (!stops.length) return Array.from({ length: 7 }).map(() => -1)
    const center = clampIndex(centerStopIndex.value, stops.length - 1)
    return Array.from({ length: 7 }).map((_, slotIdx) => center + (slotIdx - 3))
})

const getStopDotClass = (slotIdx) => {
    const stops = displayZdList.value
    const actual = clampIndex(actualStopIndex.value, Math.max(0, stops.length - 1))
    const stopIndex = slotStopIndices.value[slotIdx]
    const exists = stopIndex >= 0 && stopIndex < stops.length
    const isCenterSlot = slotIdx === 3

    if (!exists) return 'dot-empty'
    if (isCenterSlot) {
        if (stopIndex === actual) return 'dot-current'
        if (stopIndex < actual) return 'dot-focus-past'
        return 'dot-focus-future'
    }
    if (stopIndex === actual) return 'dot-actual'
    if (stopIndex < actual) return 'dot-past'
    return 'dot-future'
}

const currentStopName = computed(() => {
    const stops = displayZdList.value
    if (!stops.length) return ''
    const center = clampIndex(centerStopIndex.value, stops.length - 1)
    return stops[center]?.mc || ''
})

const prevStopName = computed(() => {
    const stops = displayZdList.value
    if (!stops.length) return ''
    const center = clampIndex(centerStopIndex.value, stops.length - 1)
    return stops[center - 1]?.mc || ''
})

const nextStopName = computed(() => {
    const stops = displayZdList.value
    if (!stops.length) return ''
    const center = clampIndex(centerStopIndex.value, stops.length - 1)
    return stops[center + 1]?.mc || ''
})

const getStopLineClass = (slotIdx) => {
    const stops = displayZdList.value
    const a = slotStopIndices.value[slotIdx]
    const b = slotStopIndices.value[slotIdx + 1]
    const aExists = a >= 0 && a < stops.length
    const bExists = b >= 0 && b < stops.length
    if (!aExists || !bExists) return 'line-empty'
    return ''
}

// 站点条左右滑动切换当前站
const stopTouchStartX = ref(0)
const stopTouchStartY = ref(0)
const stopSwipeHandled = ref(false)

const handleStopTouchStart = (event) => {
    stopTouchStartX.value = event.touches[0].clientX
    stopTouchStartY.value = event.touches[0].clientY
    stopSwipeHandled.value = false
}

const handleStopTouchMove = (event) => {
    if (stopSwipeHandled.value) return
    const deltaX = event.touches[0].clientX - stopTouchStartX.value
    const deltaY = event.touches[0].clientY - stopTouchStartY.value
    if (Math.abs(deltaX) <= Math.abs(deltaY) || Math.abs(deltaX) < 35) return

    const maxIndex = Math.max(0, displayZdList.value.length - 1)
    // 横向滑动时拦截，避免触发外层 swiper
    try { event.preventDefault && event.preventDefault() } catch (e) { }
    if (deltaX < 0) centerStopIndex.value = Math.min(maxIndex, centerStopIndex.value + 1)
    else centerStopIndex.value = Math.max(0, centerStopIndex.value - 1)
    stopSwipeHandled.value = true
}

const handleStopTouchEnd = () => {
    stopSwipeHandled.value = false
}

const handleStopTap = (slotIdx) => {
    const stops = displayZdList.value
    const stopIndex = slotStopIndices.value[slotIdx]
    const exists = stopIndex >= 0 && stopIndex < stops.length
    if (!exists) return
    centerStopIndex.value = stopIndex
    console.log('[mock] centerStopIndex', centerStopIndex.value, 'curZdxh', curZdxh.value)
}

// ==================== 站点条 ↔ 学生列表联动 ====================
const rowHeightPx = ref(0)
const listViewportHeightPx = ref(0)
const syncingFromListScroll = ref(false)
const suppressListScrollSyncUntil = ref(0)

const measureRowHeightPx = () => {
    nextTick(() => {
        uni.createSelectorQuery()
            .in(instance)
            .select('.row-wrapper')
            .boundingClientRect((rect) => {
                if (rect?.height) rowHeightPx.value = rect.height
            })
            .exec()
    })
}

const measureListViewportHeightPx = () => {
    nextTick(() => {
        uni.createSelectorQuery()
            .in(instance)
            .select('.student-list-area')
            .boundingClientRect((rect) => {
                if (rect?.height) listViewportHeightPx.value = rect.height
            })
            .exec()
    })
}

const scrollListToCenterStop = ({ animate = true } = {}) => {
    const stopIndex = centerStopIndex.value
    const zdxh = displayZdList.value[stopIndex]?.xh
    const target = displayZdcyList.value.find(s => Number(s.zdxh) === Number(zdxh))
    if (!target) return
    suppressListScrollSyncUntil.value = Date.now() + 500
    // scroll-into-view 无法动态控制动画开关，这里仅通过节流避免回流抖动
    scrollIntoViewId.value = ''
    nextTick(() => {
        scrollIntoViewId.value = `row_${target.zdryid}`
    })
}

watch(centerStopIndex, () => {
    if (syncingFromListScroll.value) return
    scrollListToCenterStop({ animate: true })
})

const handleStudentListScroll = (e) => {
    if (showConfirm.value) return
    if (Date.now() < suppressListScrollSyncUntil.value) return
    if (!rowHeightPx.value) return
    const scrollTop = e?.detail?.scrollTop ?? 0
    const scrollHeight = e?.detail?.scrollHeight ?? 0
    const viewport = listViewportHeightPx.value || 0
    const edgeThresholdPx = 6

    // 顶部/底部兜底：解决“滚动到极限但 floor 计算不到最后一项”
    if (scrollTop <= edgeThresholdPx) {
        const first = displayZdcyList.value[0]
        const nextCenter = first ? getStopIndexByZdxh(first.zdxh) : centerStopIndex.value
        if (first && nextCenter !== centerStopIndex.value) {
            syncingFromListScroll.value = true
            centerStopIndex.value = nextCenter
            nextTick(() => { syncingFromListScroll.value = false })
        }
        return
    }
    if (scrollHeight && viewport && scrollTop + viewport >= scrollHeight - edgeThresholdPx) {
        const last = displayZdcyList.value[displayZdcyList.value.length - 1]
        const nextCenter = last ? getStopIndexByZdxh(last.zdxh) : centerStopIndex.value
        if (last && nextCenter !== centerStopIndex.value) {
            syncingFromListScroll.value = true
            centerStopIndex.value = nextCenter
            nextTick(() => { syncingFromListScroll.value = false })
        }
        return
    }

    const idx = Math.max(0, Math.min(displayZdcyList.value.length - 1, Math.floor(scrollTop / rowHeightPx.value)))
    const student = displayZdcyList.value[idx]
    if (!student) return
    const nextCenter = getStopIndexByZdxh(student.zdxh)
    if (nextCenter === centerStopIndex.value) return

    syncingFromListScroll.value = true
    centerStopIndex.value = nextCenter
    nextTick(() => {
        syncingFromListScroll.value = false
    })
}



// ==================== 确认弹窗配置 ====================

/**
 * 确认弹窗按钮配置
 */
const confirmButtons = ref([
    { text: '取消', action: 'cancel', type: 'default' },
    { text: '确认', action: 'confirm', type: 'primary' }
])

const confirmTextLine1 = ref('') 
const confirmTextLine2 = ref('')

// ==================== 表单配置 ====================

/**
 * 表单字段校验配置
 * 定义各个字段的校验规则
 */
const fieldConfigs = computed(() => {
    const configs = {
        rq: {
            rules: [{ required: true, message: '日期不能为空' }]
        },
        jc: {
            rules: [{ required: true, message: '请选择节次' }]
        }
    }

    return configs
})
/**
 * 表单引用
 * 用于表单校验和数据提交
 */
const formRef = ref(null)

/**
 * 初始化表单默认值
 */
const initFormDefaults = () => {
    // 设置默认日期为今天
    const today = new Date()
    const year = today.getFullYear()
    const month = String(today.getMonth() + 1).padStart(2, '0')
    const day = String(today.getDate()).padStart(2, '0')
    formData.value.rq = `${year}-${month}-${day}`

    // 更新星期几显示
    updateWeekdayText(formData.value.rq)

    // 根据当前时间设置默认节次 - 使用国际通用标准
    const currentTime = new Date()
    const currentHour = currentTime.getHours()

    let jcValue = '1'

    if (currentHour >= 0 && currentHour < 12) {
        jcValue = '1'
    } else {
        jcValue = '2'
    }

    formData.value.jc = jcValue
    
}

/**
 * 更新星期几显示文本
 */
const updateWeekdayText = (dateStr) => {
    if (!dateStr) {
        weekdayText.value = ''
        return
    }

    try {
        const date = new Date(dateStr)
        const weekdays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
        weekdayText.value = weekdays[date.getDay()]
    } catch (error) {
        console.error('解析日期失败:', error)
        weekdayText.value = ''
    }
}

/**
 * 日期选择变化处理
 */
const onDateChange = (value) => {
    //  console.log('日期选择变化:', value)
    updateWeekdayText(value)
}

// ==================== 校车点名初始化（接口） ====================
const loadXcdmInit = async () => {
    try {
        const params = {
            rq: formData.value.rq,
            jc: formData.value.jc,
            carNo: formData.value.carNo,
        }
        const res = await xcdmApi.mp_xcdmHomep_load(params)
        console.log('mp_xcdmHomep_load:', res)

        // 先只看返回结构，后续再接字段映射
        if (res?.data?.xcdmlbm != null) {
            xcdmlbm.value = Number(res.data.xcdmlbm) || 1
            // 节次：接=上午(1)，送=下午(2)
            formData.value.jc = xcdmlbm.value === 51 ? '2' : '1'
        }
        // 车牌号回显：优先 xcList[0].mc，其次接口 carNo
        const apiCarNo = res?.data?.xcList?.[0]?.mc || res?.data?.carNo
        if (apiCarNo) formData.value.carNo = apiCarNo
        if (res?.data?.xcid != null) xcid.value = String(res.data.xcid)
        if (res?.data?.jskssj != null) jskssj.value = utilFormatDate(String(res.data.jskssj), 'yyyy-MM-dd HH:mm:ss')
        if (res?.data?.jsjssj != null) jsjssj.value = utilFormatDate(String(res.data.jsjssj), 'yyyy-MM-dd HH:mm:ss')
        if (res?.data?.curZdxh != null) curZdxh.value = Number(res.data.curZdxh) || 1
        if (Array.isArray(res?.data?.zdList) && res.data.zdList.length) {
            zdList.value = res.data.zdList
        }
        if (Array.isArray(res?.data?.zdcyList)) {
            zdcyList.value = res.data.zdcyList
        }
        // 初始化时把中心点对齐到当前站
        centerStopIndex.value = actualStopIndex.value
        // 已点名摘要：只要返回 jsrs 就视为已点名（qjrs/ycrs 可能任何时候都会返回）
        if (res?.data?.jsrs !== undefined && res?.data?.jsrs !== null) {
            isSummaryMode.value = true
            summaryJsrs.value = Number(res.data.jsrs || 0)
            summaryQjrs.value = Number(res.data.qjrs || 0)
            summaryYcrs.value = Number(res.data.ycrs || 0)
            // 摘要模式不展示列表
            zdcyList.value = []
        } else {
            isSummaryMode.value = false
            summaryJsrs.value = 0
            summaryQjrs.value = 0
            summaryYcrs.value = 0
        }
        const msg = res?.data?.msg ? String(res.data.msg) : ''
        notInTimeMsg.value = ''
        if (msg.includes('不在校车接送时段') || msg.includes('不在点名时段')) {
            isNotInTime.value = true
            notInTimeMsg.value = msg
            if (res?.data?.swsjd && NotInTime.value[0]) NotInTime.value[0].range = String(res.data.swsjd)
            if (res?.data?.xwsjd && NotInTime.value[1]) NotInTime.value[1].range = String(res.data.xwsjd)
        }
        return res
    } catch (e) {
        console.warn('mp_xcdmHomep_load failed:', e)
        return null
    }
}

// ==================== 事件处理方法 ====================

// ==================== 状态码工具（上午接/下午送） ====================
const getModeLabels = () => {
    return xcdmlbm.value === 51
        ? { base: '已上车', success: '已送达', unboard: '未上车' }
        : { base: '待上车', success: '已上车', unboard: '未上车' }
}

const isLeave = (student) => Number(student?.rcid || 0) > 0
const isUnboard = (student) => [11, 61].includes(Number(student?.xcjslbm))
const isSuccess = (student) => [1, 51].includes(Number(student?.xcjslbm))
const isWait = (student) => Number(student?.xcjslbm) === 0 && !isLeave(student)

const getStatusText = (student) => {
    if (isLeave(student)) return '请假'
    const code = Number(student?.xcjslbm)
    const labels = getModeLabels()
    if (code === 0) return labels.base
    if (code === 1 || code === 51) return labels.success
    if (code === 11 || code === 61) return labels.unboard
    return labels.base
}

const shouldShowException = (student) => {
    if (!student) return false
    if (isLeave(student)) return false
    // 待上车/已上车时可异常登记；未上车不显示异常登记
    return Number(student.xcjslbm) === 0 || isSuccess(student)
}

// ==================== 状态切换接口（mp_xcdmHomep_swState） ====================
const callSwState = async ({ student, xcjslbm, sm }) => {
    const payload = {
        xcid: xcid.value,
        xcdmlbm: xcdmlbm.value,
        jskssj: jskssj.value,
        jsjssj: jsjssj.value,
        zdryid: student?.zdryid,
        xcjslbm,
    }
    if (Number(xcjslbm) === 0 && student?.xcjsjlid != null) payload.xcjsjlid = student.xcjsjlid
    if (sm) payload.sm = sm
    const res = await xcdmApi.mp_xcdmHomep_swState(payload)
    console.log('mp_xcdmHomep_swState:', payload, res)
    return res
}

/**
 * 加载学生数据
 * 当前无接口：使用前端 mock 数据
 */
const loadStudentData = async ({ syncScrollToCenter = false } = {}) => {
    try {
        isSummaryMode.value = false
        isNotInTime.value = false

        // 初始化接口（先打印返回，后续再把返回映射到页面字段）
        await loadXcdmInit()
        if (isNotInTime.value) return
        if (isSummaryMode.value) return

        nextTick(() => {
            measureHeaderHeight()
            measureRowHeightPx()
            measureListViewportHeightPx()
            if (syncScrollToCenter) scrollListToCenterStop({ animate: true })
        })
    } catch (error) {
        console.error('加载学生数据失败:', error)
        uni.showToast({
            title: '加载学生数据失败',
            icon: 'none'
        })
    }
}
/**
 * 处理学生点击
 * 切换学生的考勤状态
 * @param {Object} student - 被点击的学生对象
 */
const handleStudentClick = async (student) => {
    //  console.log('点击学生:', student)

    if (isLeave(student)) return

    const code = Number(student?.xcjslbm)
    const labels = getModeLabels()

    // 已上车/已送达 -> 取消回到 0；未上车 -> 确认回到 0
    if (isSuccess(student)) {
        closeAllSwipeStates()
        pendingStatusChange.value = { zdryid: student.zdryid, to: 0 }
        confirmTextLine1.value = `“${labels.success}”消息已发送至家长`
        confirmTextLine2.value = `是否取消“${labels.success}”？`
        showConfirm.value = true
        return
    }
    if (isUnboard(student)) {
        closeAllSwipeStates()
        pendingStatusChange.value = { zdryid: student.zdryid, to: 0 }
        confirmTextLine1.value = `当前状态：${labels.unboard}`
        confirmTextLine2.value = `是否改为“${labels.base}”？`
        showConfirm.value = true
        return
    }

    // 0 -> 1(上午接) / 51(下午送)
    if (code === 0) {
        const nextCode = xcdmlbm.value === 51 ? 51 : 1
        const targetStudent = zdcyList.value.find(s => Number(s.zdryid) === Number(student.zdryid))
        if (targetStudent) {
            try {
                await callSwState({ student: targetStudent, xcjslbm: nextCode })
                targetStudent.xcjslbm = nextCode
            } catch (e) {
                console.warn('mp_xcdmHomep_swState failed:', e)
                uni.showToast({ title: '切换失败', icon: 'none' })
            }
        }
    }
}

const handleBottomAction = ({ action }) => {
    if (action === 'save') handleSave()
}

const handleSave = async () => {
    try {
        if (!xcid.value || !jskssj.value || !jsjssj.value) {
            uni.showToast({ title: '缺少校车信息', icon: 'none' })
            return
        }
        const qjrs = zdcyList.value.filter(s => isLeave(s)).length
        const ycrs = zdcyList.value.filter(s => isUnboard(s)).length
        const jsrs = Math.max(0, zdcyList.value.length - qjrs)

        const payload = {
            xcid: xcid.value,
            jskssj: jskssj.value,
            jsjssj: jsjssj.value,
            jsrs,
            qjrs,
            ycrs,
        }
        const res = await xcdmApi.mp_xcdmHomep_subm(payload)
        console.log('mp_xcdmHomep_subm:', payload, res)
        uni.showToast({ title: '提交成功', icon: 'success' })
        // 提交后重新拉取一次，刷新为“已点名”摘要
        await loadStudentData({ syncScrollToCenter: false })
    } catch (e) {
        console.error('提交失败:', e)
        uni.showToast({ title: '提交失败', icon: 'none' })
    }
}


// 左滑状态管理（参考 todo_list.vue）
const swipeStates = ref({})
const touchStartX = ref(0)
const touchStartY = ref(0)
const isSwiping = ref(false)

const actionWidth = (student) => {
    // 待上车 / 已上车：异常登记+家长电话；未上车/请假：仅家长电话
    return shouldShowException(student) ? 320 : 160
}

const closeAllSwipeStates = () => {
    Object.keys(swipeStates.value).forEach(key => {
        swipeStates.value[key] = false
    })
}

const handleTouchStart = (event, itemId) => {
    if (showConfirm.value) return
    touchStartX.value = event.touches[0].clientX
    touchStartY.value = event.touches[0].clientY
}

const handleTouchMove = (event, itemId) => {
    if (showConfirm.value) return
    const deltaX = event.touches[0].clientX - touchStartX.value
    const deltaY = event.touches[0].clientY - touchStartY.value

    if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 30) {
        isSwiping.value = true
        event.preventDefault()
        if (deltaX < -50) {
            closeAllSwipeStates()
            swipeStates.value[itemId] = true
        } else if (deltaX > 50) {
            swipeStates.value[itemId] = false
        }
    }
}

const handleTouchEnd = () => {
    if (showConfirm.value) return
    // 延迟清理，避免 touchend 后立刻触发 tap
    setTimeout(() => {
        isSwiping.value = false
    }, 50)
}

const handleStudentTap = (student) => {
    if (isSwiping.value) return
    handleStudentClick(student)
}

const pendingStatusChange = ref(null)

const scrollIntoViewId = ref('')

const handleCallParent = (student) => {
    // 保存校车电话记录（不阻塞拨号）
    try {
        if (xcid.value && jskssj.value && jsjssj.value) {
            xcdmApi.mp_xcdmHomep_saveXcdhjl({
                xcid: xcid.value,
                jskssj: jskssj.value,
                jsjssj: jsjssj.value,
                xcdmlbm: xcdmlbm.value,
                zdryid: student.zdryid,
            }).then((res) => {
                console.log('mp_xcdmHomep_saveXcdhjl:', res)
            }).catch((e) => {
                console.warn('mp_xcdmHomep_saveXcdhjl failed:', e)
            })
        }
    } catch (e) { }
    console.log('[mock] makePhoneCall', { zdryid: student.zdryid, phoneNumber: student.jzdh })
    uni.makePhoneCall({ phoneNumber: student.jzdh })
}

const handleException = (student) => {
    closeAllSwipeStates()
    const mode = xcdmlbm.value
    const site = zdList.value.find(z => Number(z.xh) === Number(student.zdxh))?.mc || ''
    uni.navigateTo({
        url: `/pages/xcdm/exception?zdryid=${encodeURIComponent(student.zdryid)}&xm=${encodeURIComponent(student.xm)}&site=${encodeURIComponent(site)}&xcdmlbm=${encodeURIComponent(String(mode))}&xcid=${encodeURIComponent(String(xcid.value || ''))}&jskssj=${encodeURIComponent(String(jskssj.value || ''))}&jsjssj=${encodeURIComponent(String(jsjssj.value || ''))}`
    })
}

/**
 * 获取表格行的样式类
 * @param {string} status - 状态
 * @returns {string} CSS类名
 */
const getRowClass = (student) => {
    const classes = []
    const curOrder = getOrderIndexByZdxh(curZdxh.value)
    const stuOrder = getOrderIndexByZdxh(student?.zdxh)
    const stage = stuOrder < curOrder ? 'past' : stuOrder === curOrder ? 'current' : 'future'
    if (stage === 'past') classes.push('row-site-past')
    else if (stage === 'current') classes.push('row-site-current')
    else classes.push('row-site-future')

    if (isLeave(student)) {
        classes.push('row-status-leave')
        if (stage === 'current') classes.push('row-leave-current')
    } else if (isUnboard(student)) {
        classes.push('row-status-off')
    } else if (isSuccess(student)) {
        classes.push('row-status-on')
    }

    return classes.join(' ')
}

const getDragIndicatorStyle = (student) => {
    let backgroundColor = '#357cdf'
    if (isUnboard(student)) return { backgroundColor: '#ff0000' }
    const curOrder = getOrderIndexByZdxh(curZdxh.value)
    const stuOrder = getOrderIndexByZdxh(student?.zdxh)
    const stage = stuOrder < curOrder ? 'past' : stuOrder === curOrder ? 'current' : 'future'
    if (stage === 'past') backgroundColor = '#999999'
    if (stage === 'future') backgroundColor = '#6b9ce0'
    if (stage === 'current') backgroundColor = '#357cdf'
    return { backgroundColor }
}

const headerHeight = ref(300) // 固定头部高度（rpx），初始值设大一点避免遮挡

// 获取当前组件实例（用于 SelectorQuery）
const instance = getCurrentInstance()

/**
 * 测量并更新头部高度
 * @param {number} retryCount - 重试次数
 */
const measureHeaderHeight = (retryCount = 0) => {
    nextTick(() => {
        uni.createSelectorQuery()
            .in(instance) // 指定在当前组件实例中查询
            .select('.fixed-header')
            .boundingClientRect((rect) => {
                if (rect && rect.height > 0) {
                    const headerHeightRpx = rect.height * 2 // px转rpx
                    headerHeight.value = headerHeightRpx
                    console.log('更新头部高度:', rect.height, 'px =', headerHeightRpx, 'rpx')
                } else if (retryCount < 5) {
                    // 如果获取失败且重试次数未达到上限，延迟后重试
                    console.log('头部高度获取失败，第', retryCount + 1, '次重试...', 'rect:', rect)
                    setTimeout(() => {
                        measureHeaderHeight(retryCount + 1)
                    }, 100)
                }
            })
            .exec()
    })
}

/**
 * 确认弹窗按钮点击处理
 */
const handleConfirmAction = async (data) => {
    //  console.log('确认弹窗按钮点击:', data)

    switch (data.action) {
        case 'cancel':
            showConfirm.value = false
            pendingStatusChange.value = null
            break
        case 'confirm':
            showConfirm.value = false
            if (pendingStatusChange.value?.zdryid) {
                const { zdryid, to } = pendingStatusChange.value
                const targetStudent = zdcyList.value.find(s => Number(s.zdryid) === Number(zdryid))
                if (targetStudent && !isLeave(targetStudent)) {
                    try {
                        await callSwState({ student: targetStudent, xcjslbm: Number(to) })
                        targetStudent.xcjslbm = Number(to)
                    } catch (e) {
                        console.warn('mp_xcdmHomep_swState failed:', e)
                        uni.showToast({ title: '切换失败', icon: 'none' })
                    }
                }
            }
            pendingStatusChange.value = null
            break
    }
}

/**
 * 确认弹窗关闭处理
 */
const handleConfirmClose = () => {
    //  console.log('确认弹窗关闭')
    showConfirm.value = false
    pendingStatusChange.value = null
}

// ==================== 页面初始化 ====================

/**
 * 页面挂载时的初始化
 */
// onMounted(() => {
//     // 初始化表单默认值
//     initFormDefaults()

//     // 加载班级选项
//     loadClassOptions()

//     // 加载学生数据
//     // loadStudentData()

//     // 多次尝试获取固定头部的高度，确保准确
//     const measureHeader = () => {
//         uni.createSelectorQuery().select('.fixed-header').boundingClientRect((rect) => {
//             if (rect && rect.height > 0) {
//                 initialFilterHeight.value = rect.height
//                 const headerHeightRpx = rect.height * 2 // px转rpx
//                 headerHeight.value = headerHeightRpx
//                 //  console.log('固定头部高度:', rect.height, 'px =', headerHeightRpx, 'rpx')
//             } else {
//                 // 如果还没获取到，再试一次
//                 setTimeout(measureHeader, 50)
//             }
//         }).exec()
//     }

//     // 立即尝试测量，然后延迟再测量一次确保准确
//     measureHeader()
//     setTimeout(measureHeader, 200)
//     // 如有需要，可在此初始化更多 mock 数据
// })


// ============== 暴露给主容器的生命周期（供 pages/main/index.vue 调用） ==============
// 避免重复初始化的标记

function onLoad() {
    initFormDefaults()
    loadStudentData({ syncScrollToCenter: true })
}

function onShow() {
    // 每次切到该页时都刷新数据
    // 头部高度会在 loadStudentData 完成后自动测量
    initFormDefaults()
    loadStudentData({ syncScrollToCenter: false })
}

function onHide() {
    // 可按需做暂存处理
}

function onUnload() {
    // 可按需做清理处理
}

defineExpose({ onLoad, onShow, onHide, onUnload })


// 预留：后续如需全局滚动处理再接入

</script>

<style lang="scss" scoped>
.page-container {
    display: flex;
    flex-direction: column;
    height: 100vh;
    background-color: #f2f3f4;
    position: relative;
}

.fixed-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100;
    background-color: #f2f3f4;
}

.filter-area {
    // background-color: #fff;
    transition: all 0.3s ease;
    // border-bottom: 1rpx solid #eceded;

    .full-form {
        padding: 18rpx 0 18rpx;
    }
}

.stop-progress {
    width: 100%;
    height: 120rpx; // 约 60px
    background: #f2f3f4;
    border-bottom: 1rpx solid #eceded;
    display: flex;
    flex-direction: column;
    justify-content: center;
    box-sizing: border-box;
    padding: 0 24rpx 36rpx;
    overflow: visible;
}

.stop-track {
    display: flex;
    align-items: center;
}

.stop-node {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 36rpx; // 18px
    height: 36rpx; // 18px
}

.stop-node.center {
    width: 56rpx; // 28px
    height: 56rpx; // 28px
}

.stop-dot {
    width: 100%;
    height: 100%;
    border-radius: 9999rpx;
}

.dot-past {
    background: #c3c7cb;
}

.dot-future {
    background: #fff;
    border: 2rpx solid #c3c7cb; // 约 1px
    box-sizing: border-box;
}

.dot-actual {
    background: #e59f40;
}

.dot-current {
    background: #e59f40;
}

.dot-focus-future {
    background: #fff;
    border: 2rpx solid #e59f40;
    box-sizing: border-box;
}

.dot-focus-past {
    background: #c3c7cb;
    border: 2rpx solid #e59f40;
    box-sizing: border-box;
}

.dot-empty {
    background: transparent;
    opacity: 0;
}

.stop-line {
    flex: 1;
    height: 4rpx; // 约 2px
    background: #c3c7cb;
}

.line-empty {
    background: transparent;
    opacity: 0;
}

.stop-label-row {
    margin-top: 8rpx;
    position: relative;
    overflow: visible;
    height: 52rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 24rpx;
}

.stop-label-current {
    font-size: 44rpx; // 约 22px
    color: #000;
    font-weight: 700;
    text-align: center;
    white-space: nowrap;
    overflow: visible;
    line-height: 1.1;
    z-index: 2;
    flex-shrink: 0;
}

.stop-label-side {
    font-size: 32rpx;
    color: #999;
    font-weight: 400;
    white-space: nowrap;
    overflow: hidden;
    z-index: 1;
    flex: 1;
}

.stop-label-prev {
    text-align: right;
}

.stop-label-next {
    text-align: left;
}

.onoff-button-group {
    display: flex;
    flex-wrap: wrap;
    gap: 20rpx;
    align-items: flex-start;
}

.stats-area {
    background-color: #fff;
    padding: 24rpx;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .stat-parent {
        color: #e59f40;
        margin-right: 8rpx;
    }

    .stats-left {
        font-size: 28rpx;
        font-weight: 500;
        display: flex;
        align-items: center;
    }

    .stats-right {
        font-size: 30rpx;
        font-weight: 600;
        color: #333;
    }
}

.student-list-area {
    background-color: #ffffff;
    
    flex: 1;
    height: 0; // 配合 flex: 1，让 scroll-view 正确计算剩余空间
}

.student-table-wrapper {
    flex: 1;
    height: 0;
    display: flex;
    flex-direction: column;
    padding-bottom: 120rpx; // 给底部按钮留出空间
    background-color: #fff;
}

.student-table {
    width: calc(100% - 32rpx);
    margin: 0 auto;
    border: 1rpx solid #d2d2d2;
    background-color: #fff;
    display: flex;
    flex-direction: column;
    flex: 1;
    height: 0;
    
    .row-wrapper {
        position: relative;
        overflow: hidden;
    }

    .row-wrapper:last-child .table-row {
        border-bottom: none;
    }

    .swipe-actions {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        display: flex;
        align-items: stretch;
        z-index: 1;
        box-sizing: border-box;

        .action-btn {
            width: 160rpx;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 30rpx;
            font-weight: 600;
            color: #fff;
        }

        .exception-btn {
            background-color: #ff0000;
        }

        .phone-btn {
            background-color: #357cdf;
        }
    }

    .table-header {
        display: flex;
        background-color: #efefef;
        border-bottom: 1rpx solid #d2d2d2;
        padding: 20rpx;
        align-items: center;
        // margin-bottom: 10rpx;
        .col-name {
            width: 240rpx;
            font-size: 28rpx;
            font-weight: bold;
            color: #333;
        }

        .col-class {
            flex: 1;
            font-size: 28rpx;
            font-weight: bold;
            color: #333;
        }

        .col-status {
            width: 160rpx;
            font-size: 28rpx;
            font-weight: bold;
            color: #333;
            text-align: left;
        }
    }

    .table-row {
        display: flex;
        padding: 20rpx;
        transition: background-color 0.3s ease;
        position: relative;
        z-index: 2;
        transition: transform 0.2s ease, background-color 0.3s ease;
        border-bottom: 1rpx solid #d2d2d2;

       

        &:active {
            background-color: #f0f0f0;
        }

        .col-name {
            width: 240rpx;
            font-size: 32rpx;
            color: #000;
        }

        .col-class {
            flex: 1;
            font-size: 32rpx;
            color: #000;
        }

        .col-status {
            width: 160rpx;
            text-align: left;
            font-size: 32rpx;
            color: #000;
        }

        .drag-indicator {
            position: absolute;
            right: 0;
            top: 0;
            bottom: 0;
            width: 8rpx; // 约 4px
            height: 100%;
            opacity: 0.9;
        }

        // 状态行样式
        &.row-site-past {
            background-color: #d4f8d4;
            .col-name,
            .col-class,
            .col-status {
                color: #666;
            }
        }

        &.row-site-current {
            background-color: #e59f40;
            font-weight: 700;
            .col-name,
            .col-class,
            .col-status {
                color: #000;
                font-weight: 700;
            }
        }

        &.row-site-future {
            background-color: #fff;
            .col-name,
            .col-class,
            .col-status {
                color: #666;
            }
        }

        &.row-status-on {
            background-color: #d4f8d4;
            .col-name,
            .col-class,
            .col-status {
                color: #666;
                font-weight: 400;
            }
        }

        &.row-status-leave {
            background-color: #c7e0ff;
            .col-name,
            .col-class,
            .col-status {
                color: #000;
                font-weight: 400;
            }
        }

        &.row-leave-current {
            .col-name,
            .col-class,
            .col-status {
                font-weight: 700;
            }
        }

        &.row-status-off {
            background-color: #eb6100;
            .col-name,
            .col-class,
            .col-status {
                color: #fff;
                font-weight: 400;
            }
        }
    }

    .row-wrapper.swiped .table-row {
        transform: translateX(calc(-1 * var(--actions-width)));
    }

    .row-wrapper.swiped .drag-indicator {
        display: none;
    }
}

// 星期几显示样式
.weekday-text {
    font-size: 32rpx;
    color: #333;
    position: absolute;
    right: 100rpx;
    top: 50%;
    transform: translateY(-50%);
    padding-bottom: 6rpx;
}

// ==================== 确认弹窗样式 ====================

// 统计信息样式
.stats-section {
    padding: 40rpx;
    display: flex;
    flex-direction: column;
    gap: 20rpx;

    .stat-item {
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 34rpx;
        color: #333;

        .stat-label {

            text-align: right;
            flex: 1;
            margin-right: 20rpx;
        }

        .stat-value {
            flex: 1;


        }
    }
}

.confirm-message {
    height: calc(100% - 100rpx);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16rpx;
    padding: 24rpx;
    box-sizing: border-box;
    text-align: center;
}

.confirm-icon {
    width: 120rpx;
    height: 120rpx;
}

.confirm-text {
    font-size: 32rpx;
    color: #333;
    font-weight: 400;
}

// 只读班级名称样式
.readonly-field {
    width: 100%;
    min-height: 60rpx;
    display: flex;
    align-items: center;
}

.readonly-text {
    font-size: 32rpx;
}

// 晚自习模式相关样式
.select-group {
    width: 100%;
}

.mt-10 {
    margin-top: 10rpx;
}

.summary-area{
    margin-top:40vh
}




.isNotInTime{
    width: calc(100% - 40rpx);
    height: calc(100% - 40rpx);
    background: #fff;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
    border-radius: 4rpx;
    border: 2rpx solid #ebecec;
    display: flex;
    flex-direction: column;
    padding: 20rpx;
    box-sizing: border-box;

    .isNotInTime-title{
        color: #333;
        font-weight: 500;
        font-size: 38rpx;
        text-align: center;
        flex: 3;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 30rpx;
    }

    .isNotInTime-content{
        flex: 7;
        border-radius: 4rpx;
        background:  #f9fafb;
        padding: 0 30rpx;

        .isNotInTime-content-title{ 
            font-size: 36rpx;
            color: #333333;
            font-weight: 400;
            margin: 30rpx 0;
            
        }
        .isNotInTime-content-tip{
            font-size: 26rpx;
            color: #999;
            font-weight: 400;
            margin-top: -14rpx;
            margin-bottom: 22rpx;
        }
        .isNotInTime-content-item{ 
            font-size: 36rpx;
            color: #333333;
            font-weight: 400;
            display: flex;
            align-items: center;
            justify-content: flex-start;
            background: #fff;
            padding:20rpx 30rpx;
            box-sizing: border-box;
            border-radius: 4rpx;
            margin-bottom: 30rpx;
            gap: 30rpx;

            .isNotInTime-content-item-icon{
                width: 120rpx;
                text-align: center;
            }
        }
    }
}
</style>
