<template>
    <div class="guahao-list">
        <el-card class="!border-none" shadow="never">
            <el-form class="mb-[-16px]" :model="queryParams" :inline="true" @submit.prevent>
                <el-form-item label="预约日期">
                    <daterange-picker
                        v-model:startTime="queryParams.start_date"
                        v-model:endTime="queryParams.end_date"
                    />
                </el-form-item>
                <el-form-item label="患者姓名">
                    <el-input
                        v-model="queryParams.patient_name"
                        placeholder="模糊搜索"
                        clearable
                        class="!w-[160px]"
                        @keyup.enter="resetPage"
                    />
                </el-form-item>
                <el-form-item label="医生">
                    <el-input
                        v-model="queryParams.doctor_name"
                        placeholder="模糊搜索"
                        clearable
                        class="!w-[140px]"
                        @keyup.enter="resetPage"
                    />
                </el-form-item>
                <el-form-item label="医助">
                    <el-select
                        v-model="queryParams.assistant_id"
                        placeholder="全部"
                        clearable
                        filterable
                        class="!w-[180px]"
                    >
                        <el-option
                            v-for="a in assistantOptions"
                            :key="a.id"
                            :label="a.name + (a.account ? ` (${a.account})` : '')"
                            :value="a.id"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item label="状态">
                    <el-select v-model="queryParams.status" placeholder="全部" clearable class="!w-[130px]">
                        <el-option label="已预约" :value="1" />
                        <el-option label="已取消" :value="2" />
                        <el-option label="已完成" :value="3" />
                        <el-option label="已过号" :value="4" />
                    </el-select>
                </el-form-item>
                <el-form-item label="渠道">
                    <el-select
                        v-model="queryParams.channel_source"
                        placeholder="全部"
                        clearable
                        filterable
                        class="!w-[200px]"
                    >
                        <el-option
                            v-for="item in channelOptions"
                            :key="String(item.value)"
                            :label="item.name"
                            :value="item.value"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="resetPage">查询</el-button>
                    <el-button @click="resetFilter">重置</el-button>
                </el-form-item>
            </el-form>
        </el-card>

        <el-card class="!border-none mt-4" shadow="never">
            <div class="flex flex-wrap items-center gap-3 mb-4">
                <el-button
                    v-perms="['doctor.appointment/edit']"
                    type="primary"
                    :disabled="selectedRows.length === 0"
                    @click="openBatchChannelDialog"
                >
                    批量修改渠道
                </el-button>
                <span v-if="selectedRows.length > 0" class="text-sm text-gray-500">
                    已选 {{ selectedRows.length }} 条
                </span>
            </div>
            <el-table
                ref="tableRef"
                v-loading="pager.loading"
                row-key="id"
                :data="pager.lists"
                size="large"
                stripe
                @selection-change="onSelectionChange"
            >
                <el-table-column type="selection" width="48" align="center" reserve-selection />
                <el-table-column label="ID" prop="id" width="72" align="center" />
                <el-table-column label="诊单/患者" min-width="140">
                    <template #default="{ row }">
                        <div class="text-sm">
                            <div class="font-medium">{{ row.patient_name || '—' }}</div>
                            <div class="text-gray-500">{{ maskPhone(row.patient_phone) }}</div>
                            <div class="text-xs text-gray-400">诊单 #{{ row.diagnosis_id ?? row.patient_id }}</div>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column label="医生" prop="doctor_name" width="100" show-overflow-tooltip />
                <el-table-column label="医助" prop="assistant_name" width="100" show-overflow-tooltip />
                <el-table-column label="预约时间" min-width="128">
                    <template #default="{ row }">
                        <div>{{ row.appointment_date }}</div>
                        <div class="text-gray-500">{{ formatHm(row.appointment_time) }} · {{ row.period_desc }}</div>
                    </template>
                </el-table-column>
                <el-table-column label="类型" prop="appointment_type_desc" width="100" />
                <el-table-column label="渠道" min-width="130" show-overflow-tooltip>
                    <template #default="{ row }">
                        <div class="text-sm">{{ row.channel_source_desc || '—' }}</div>
                        <div v-if="row.channel_source_detail" class="text-xs text-gray-400 truncate">
                            {{ row.channel_source_detail }}
                        </div>
                    </template>
                </el-table-column>
                <el-table-column label="状态" width="96" align="center">
                    <template #default="{ row }">
                        <el-tag
                            :type="
                                row.status === 1 ? 'success' : row.status === 2 ? 'info' : row.status === 3 ? 'primary' : 'danger'
                            "
                            size="small"
                            effect="light"
                        >
                            {{ row.status_desc }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="备注" prop="remark" min-width="120" show-overflow-tooltip />
                <el-table-column label="操作" width="100" fixed="right" align="center">
                    <template #default="{ row }">
                        <el-button v-perms="['doctor.appointment/edit']" type="primary" link @click="openEdit(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="editVisible" title="编辑挂号" width="560px" destroy-on-close @closed="resetEditForm">
            <el-form :model="editForm" label-width="96px">
                <el-form-item label="预约日期" required>
                    <el-date-picker
                        v-model="editForm.appointment_date"
                        type="date"
                        value-format="YYYY-MM-DD"
                        placeholder="选择日期"
                        class="!w-full"
                    />
                </el-form-item>
                <el-form-item label="预约时间" required>
                    <el-time-picker
                        v-model="editForm.appointment_time"
                        format="HH:mm"
                        value-format="HH:mm"
                        placeholder="时间"
                        class="!w-full"
                    />
                </el-form-item>
                <el-form-item label="时段" required>
                    <el-radio-group v-model="editForm.period">
                        <el-radio-button label="morning">上午</el-radio-button>
                        <el-radio-button label="afternoon">下午</el-radio-button>
                        <el-radio-button label="all">全天</el-radio-button>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="问诊类型" required>
                    <el-select v-model="editForm.appointment_type" class="!w-full">
                        <el-option label="视频问诊" value="video" />
                        <el-option label="图文问诊" value="text" />
                        <el-option label="电话问诊" value="phone" />
                    </el-select>
                </el-form-item>
                <el-form-item label="渠道来源" required>
                    <el-select
                        v-model="editForm.channel_source"
                        placeholder="请选择渠道来源"
                        filterable
                        class="!w-full"
                        @change="onChannelSourceChange"
                    >
                        <el-option
                            v-for="item in channelOptions"
                            :key="String(item.value)"
                            :label="item.name"
                            :value="item.value"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item v-if="needsChannelSourceDetail" label="自媒体补充" required>
                    <el-input
                        v-model="editForm.channel_source_detail"
                        maxlength="128"
                        show-word-limit
                        placeholder="请输入自媒体相关补充内容"
                        clearable
                        class="!w-full"
                    />
                </el-form-item>
                <el-form-item label="状态" required>
                    <el-select v-model="editForm.status" class="!w-full">
                        <el-option label="已预约" :value="1" />
                        <el-option label="已取消" :value="2" />
                        <el-option label="已完成" :value="3" />
                        <el-option label="已过号" :value="4" />
                    </el-select>
                </el-form-item>
                <el-form-item label="挂号医助">
                    <el-select
                        v-model="editForm.assistant_id"
                        placeholder="不修改可留空"
                        clearable
                        filterable
                        class="!w-full"
                    >
                        <el-option
                            v-for="a in assistantOptions"
                            :key="a.id"
                            :label="a.name + (a.account ? ` (${a.account})` : '')"
                            :value="a.id"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item label="备注">
                    <el-input v-model="editForm.remark" type="textarea" :rows="3" maxlength="500" show-word-limit />
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button @click="editVisible = false">取消</el-button>
                <el-button type="primary" :loading="editSaving" @click="submitEdit">保存</el-button>
            </template>
        </el-dialog>

        <el-dialog
            v-model="batchChannelVisible"
            title="批量修改渠道"
            width="520px"
            destroy-on-close
            @closed="resetBatchChannelForm"
        >
            <p class="text-sm text-gray-600 mb-4">将对已选 {{ selectedRows.length }} 条挂号写入同一渠道来源（仅改渠道，不改其它字段）。</p>
            <el-form :model="batchChannelForm" label-width="96px">
                <el-form-item label="渠道来源" required>
                    <el-select
                        v-model="batchChannelForm.channel_source"
                        placeholder="请选择渠道来源"
                        filterable
                        class="!w-full"
                        @change="onBatchChannelSourceChange"
                    >
                        <el-option
                            v-for="item in channelOptions"
                            :key="String(item.value)"
                            :label="item.name"
                            :value="item.value"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item v-if="needsBatchChannelSourceDetail" label="自媒体补充" required>
                    <el-input
                        v-model="batchChannelForm.channel_source_detail"
                        maxlength="128"
                        show-word-limit
                        placeholder="请输入自媒体相关补充内容"
                        clearable
                        class="!w-full"
                    />
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button @click="batchChannelVisible = false">取消</el-button>
                <el-button type="primary" :loading="batchChannelSaving" @click="submitBatchChannel">确定</el-button>
            </template>
        </el-dialog>
    </div>
</template>

<script lang="ts" setup name="consumerPrescriptionGuahao">
import DaterangePicker from '@/components/daterange-picker/index.vue'
import { getDictData } from '@/api/app'
import { appointmentAdminEdit, appointmentBatchEditChannel, appointmentLists } from '@/api/doctor'
import { getAssistants } from '@/api/tcm'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'

const queryParams = reactive({
    start_date: '',
    end_date: '',
    patient_name: '',
    doctor_name: '',
    assistant_id: undefined as number | undefined,
    status: '' as number | '',
    channel_source: '' as string
})

const queryInit = {
    start_date: '',
    end_date: '',
    patient_name: '',
    doctor_name: '',
    assistant_id: undefined as number | undefined,
    status: '' as number | '',
    channel_source: ''
}

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

const assistantOptions = ref<Array<{ id: number; name: string; account?: string }>>([])

const tableRef = ref<{ clearSelection?: () => void } | null>(null)
const selectedRows = ref<Record<string, unknown>[]>([])

function onSelectionChange(rows: Record<string, unknown>[]) {
    selectedRows.value = rows
}

/** 与诊单预约弹窗一致：这些字典 name 需填「自媒体补充」 */
const CHANNEL_NAMES_REQUIRING_SELF_MEDIA_DETAIL = new Set([
    '自媒体4H',
    '自媒体3Q',
    '自媒体3H',
    '自媒体2H',
    '自媒体2Q'
])

function channelNameRequiresSelfMediaDetail(name: string) {
    return CHANNEL_NAMES_REQUIRING_SELF_MEDIA_DETAIL.has(String(name ?? '').trim())
}

const channelOptions = ref<Array<{ name: string; value: string }>>([])

const selectedChannelDictName = computed(() => {
    const v = editForm.channel_source
    if (v === '' || v == null) return ''
    const row = channelOptions.value.find((item: { value: string }) => String(item.value) === String(v))
    return row ? String(row.name ?? '').trim() : ''
})

const needsChannelSourceDetail = computed(() => channelNameRequiresSelfMediaDetail(selectedChannelDictName.value))

const batchSelectedChannelDictName = computed(() => {
    const v = batchChannelForm.channel_source
    if (v === '' || v == null) return ''
    const row = channelOptions.value.find((item: { value: string }) => String(item.value) === String(v))
    return row ? String(row.name ?? '').trim() : ''
})

const needsBatchChannelSourceDetail = computed(() =>
    channelNameRequiresSelfMediaDetail(batchSelectedChannelDictName.value)
)

function onBatchChannelSourceChange(val: string) {
    const row = channelOptions.value.find((item: { value: string }) => String(item.value) === String(val))
    const name = row ? String(row.name ?? '').trim() : ''
    if (!channelNameRequiresSelfMediaDetail(name)) {
        batchChannelForm.channel_source_detail = ''
    }
}

const batchChannelVisible = ref(false)
const batchChannelSaving = ref(false)
const batchChannelForm = reactive({
    channel_source: '' as string,
    channel_source_detail: '' as string
})

function openBatchChannelDialog() {
    if (selectedRows.value.length === 0) {
        feedback.msgWarning('请先勾选挂号记录')
        return
    }
    batchChannelForm.channel_source = ''
    batchChannelForm.channel_source_detail = ''
    batchChannelVisible.value = true
}

function resetBatchChannelForm() {
    batchChannelForm.channel_source = ''
    batchChannelForm.channel_source_detail = ''
}

async function submitBatchChannel() {
    if (selectedRows.value.length === 0) {
        feedback.msgWarning('请先勾选挂号记录')
        return
    }
    if (!batchChannelForm.channel_source) {
        feedback.msgError('请选择渠道来源')
        return
    }
    if (needsBatchChannelSourceDetail.value && !batchChannelForm.channel_source_detail.trim()) {
        feedback.msgError('请填写自媒体补充说明')
        return
    }
    batchChannelSaving.value = true
    try {
        const ids = selectedRows.value.map((r) => Number(r.id))
        await appointmentBatchEditChannel({
            ids,
            channel_source: batchChannelForm.channel_source,
            channel_source_detail: batchChannelForm.channel_source_detail.trim()
        })
        feedback.msgSuccess('批量修改成功')
        batchChannelVisible.value = false
        tableRef.value?.clearSelection?.()
        selectedRows.value = []
        getLists()
    } finally {
        batchChannelSaving.value = false
    }
}

function onChannelSourceChange(val: string) {
    const row = channelOptions.value.find((item: { value: string }) => String(item.value) === String(val))
    const name = row ? String(row.name ?? '').trim() : ''
    if (!channelNameRequiresSelfMediaDetail(name)) {
        editForm.channel_source_detail = ''
    }
}

const editVisible = ref(false)
const editSaving = ref(false)
const editForm = reactive({
    id: 0,
    appointment_date: '',
    appointment_time: '' as string,
    period: 'morning' as 'morning' | 'afternoon' | 'all',
    appointment_type: 'video',
    status: 1,
    remark: '',
    assistant_id: undefined as number | undefined,
    channel_source: '' as string,
    channel_source_detail: '' as string
})

function maskPhone(phone?: string) {
    const p = String(phone || '')
    if (p.length >= 11) {
        return p.slice(0, 3) + '****' + p.slice(-4)
    }
    return p || '—'
}

function formatHm(t?: string) {
    const s = String(t || '')
    return s.length >= 5 ? s.slice(0, 5) : s || '—'
}

function resetFilter() {
    Object.assign(queryParams, queryInit)
    resetPage()
}

function rowPeriod(row: Record<string, unknown>): 'morning' | 'afternoon' | 'all' {
    const v = String(row.period ?? row.type ?? 'morning')
    if (v === 'afternoon' || v === 'all') {
        return v
    }
    return 'morning'
}

async function loadAssistants() {
    try {
        const res: any = await getAssistants()
        assistantOptions.value = res?.lists ?? res ?? []
    } catch {
        assistantOptions.value = []
    }
}

async function loadChannelOptions() {
    try {
        const data: any = await getDictData({ type: 'channels' })
        const rows = (data?.channels || []).filter((row: { status?: number }) => row.status !== 0)
        rows.sort((a: { sort?: number; id?: number }, b: { sort?: number; id?: number }) => {
            const ds = Number(b?.sort ?? 0) - Number(a?.sort ?? 0)
            if (ds !== 0) return ds
            return Number(b?.id ?? 0) - Number(a?.id ?? 0)
        })
        channelOptions.value = rows
    } catch {
        channelOptions.value = []
    }
}

function openEdit(row: Record<string, unknown>) {
    editForm.id = Number(row.id)
    editForm.appointment_date = String(row.appointment_date || '')
    editForm.appointment_time = formatHm(String(row.appointment_time || ''))
    editForm.period = rowPeriod(row)
    editForm.appointment_type = String(row.appointment_type || 'video')
    editForm.status = Number(row.status)
    editForm.remark = String(row.remark || '')
    const raw = row.appointment_assistant_id
    editForm.assistant_id =
        raw !== undefined && raw !== null && raw !== '' ? Number(raw) : undefined
    editForm.channel_source = String(row.channel_source ?? row.channels ?? '')
    editForm.channel_source_detail = String(row.channel_source_detail ?? '')
    editVisible.value = true
}

function resetEditForm() {
    editForm.id = 0
    editForm.appointment_date = ''
    editForm.appointment_time = ''
    editForm.period = 'morning'
    editForm.appointment_type = 'video'
    editForm.status = 1
    editForm.remark = ''
    editForm.assistant_id = undefined
    editForm.channel_source = ''
    editForm.channel_source_detail = ''
}

async function submitEdit() {
    if (!editForm.appointment_date) {
        feedback.msgError('请选择预约日期')
        return
    }
    if (!editForm.appointment_time) {
        feedback.msgError('请选择预约时间')
        return
    }
    if (!editForm.channel_source) {
        feedback.msgError('请选择渠道来源')
        return
    }
    if (needsChannelSourceDetail.value && !editForm.channel_source_detail.trim()) {
        feedback.msgError('请填写自媒体补充说明')
        return
    }
    editSaving.value = true
    try {
        const payload: Record<string, unknown> = {
            id: editForm.id,
            appointment_date: editForm.appointment_date,
            appointment_time: editForm.appointment_time,
            period: editForm.period,
            appointment_type: editForm.appointment_type,
            status: editForm.status,
            remark: editForm.remark,
            assistant_id: editForm.assistant_id ?? '',
            channel_source: editForm.channel_source,
            channel_source_detail: editForm.channel_source_detail.trim()
        }
        await appointmentAdminEdit(payload)
        feedback.msgSuccess('保存成功')
        editVisible.value = false
        getLists()
    } finally {
        editSaving.value = false
    }
}

onMounted(() => {
    loadAssistants()
    loadChannelOptions()
})

onActivated(() => {
    getLists()
})

getLists()
</script>
