<template>
    <PagingTable url="/series" :query="query" ref="table">
        <template #filter>
            <ElInput
                class="!w-52"
                placeholder="请输入"
                clearable
                v-model="query.title"
                @keyup.enter="table.refresh(true)"
            >
                <template #append>
                    <ElButton :icon="Search" @click="table.refresh(true)" />
                </template>
            </ElInput>
            <ElSelect v-model="query.categories" multiple clearable placeholder="筛选分类" collapse-tags>
                <ElOption v-for="item in categories" :key="item.id" :label="item.name" :value="item.id" />
            </ElSelect>
            <ElButton :icon="Plus" @click="onEdit()">添加</ElButton>
        </template>
        <ElTableColumn prop="id" label="#" width="80" />
        <ElTableColumn prop="title" label="剧名" min-width="120" />
        <ElTableColumn prop="cover" label="封面" width="120" align="center">
            <template #default="{ row }">
                <RImage style="width: 30px; height: 35px; vertical-align: middle" :src="row.cover" fit="cover" />
            </template>
        </ElTableColumn>
        <ElTableColumn prop="price" label="价格" width="150" />
        <ElTableColumn prop="createdAt" label="创建时间" :formatter="timeFormatter" width="150" />
        <ElTableColumn label="操作" align="center" width="180">
            <template #default="{ row }">
                <ElButton @click="onEdit(row)">编辑</ElButton>
                <ElButton type="primary" @click="onUploadEpisode(row)" style="margin-left: 8px">集数管理</ElButton>
            </template>
        </ElTableColumn>
    </PagingTable>
    <EditDialog v-model="showEditDialog" :model="model" :rules="rules" :on-submit="submit" @success="table.refresh()">
        <ElFormItem prop="title" label="剧名">
            <ElInput v-model="model.title" placeholder="请输入剧名" />
        </ElFormItem>
        <ElFormItem prop="description" label="描述">
            <ElInput v-model="model.description" placeholder="请输入描述" />
        </ElFormItem>
        <ElFormItem prop="cover" label="竖屏封面">
            <SingleUpload v-model="model.cover" />
        </ElFormItem>
        <ElFormItem prop="landscapeCover" label="横屏封面">
            <SingleUpload v-model="model.landscapeCover" />
        </ElFormItem>
        <ElFormItem prop="price" label="价格">
            <ElInput v-model="model.price" placeholder="请输入价格" />
        </ElFormItem>
        <ElFormItem prop="categories" label="分类">
            <ElSelect v-model="model.categories" value-key="id" multiple>
                <ElOption v-for="item in categories" :key="item.id" :label="item.name" :value="item" />
            </ElSelect>
        </ElFormItem>
    </EditDialog>
    <el-dialog v-model="showUploadDialog" title="集数管理" width="400px" class="episode-manage-dialog">
        <div style="min-height: 120px; position: relative; height: 390px">
            <div
                style="
                    height: 320px;
                    overflow-y: auto;
                    padding-right: 8px;
                    border-bottom: 1px solid #f0f0f0;
                    margin-bottom: 40px;
                "
            >
                <el-row :gutter="10" style="flex-wrap: wrap; margin-bottom: 0">
                    <el-col v-for="ep in episodes" :key="ep.id" :span="4" style="margin-bottom: 10px">
                        <div
                            @click="onEditEpisode(ep)"
                            style="
                                cursor: pointer;
                                border: 1px solid #dcdfe6;
                                border-radius: 6px;
                                padding: 12px 0 4px 0;
                                text-align: center;
                                background: #f5f7fa;
                                font-weight: bold;
                                font-size: 18px;
                                transition: 0.2s;
                                user-select: none;
                            "
                            :style="
                                editingEpisode && editingEpisode.id === ep.id
                                    ? 'border:2px solid #409EFF;background:#e6f7ff;'
                                    : ''
                            "
                        >
                            {{ ep.episodeNum }}
                            <div
                                v-if="ep.price !== undefined && ep.price !== null && ep.price !== ''"
                                style="font-size: 12px; color: #888; margin-top: 2px; font-weight: normal"
                            >
                                ${{ ep.price }}
                            </div>
                        </div>
                    </el-col>
                </el-row>
            </div>
            <el-button
                type="primary"
                style="
                    position: absolute;
                    right: 24px;
                    bottom: 8px;
                    z-index: 2;
                    min-width: 80px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                "
                @click="onAddEpisode"
            >
                新增
            </el-button>
        </div>
        <el-dialog
            v-model="showEpisodeFormDialog"
            :title="editingEpisode && editingEpisode.id ? '编辑集数' : '新增集数'"
            width="400px"
            append-to-body
        >
            <el-form :model="episodeForm" label-width="80px">
                <el-form-item label="集数" prop="episodeNum">
                    <el-input-number v-model="episodeForm.episodeNum" :min="1" />
                </el-form-item>
                <el-form-item label="视频文件" prop="video">
                    <el-upload
                        :action="uploadVideoUrl"
                        :headers="uploadHeaders"
                        :data="{ folder: episodeForm.folder }"
                        :show-file-list="false"
                        :on-success="handleVideoSuccess"
                        :before-upload="onBeforeVideoUpload"
                        accept="video/*"
                        name="video"
                        :disabled="uploadingVideo"
                    >
                        <el-button
                            :type="episodeForm.video ? 'success' : 'primary'"
                            :loading="uploadingVideo"
                            :disabled="uploadingVideo || !!episodeForm.video"
                        >
                            <template v-if="uploadingVideo">上传中</template>
                            <template v-else>{{ episodeForm.video ? '已上传' : '点击上传' }}</template>
                        </el-button>
                    </el-upload>
                </el-form-item>
                <el-form-item label="价格" prop="price">
                    <el-input v-model="episodeForm.price" placeholder="请输入价格" />
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button @click="showEpisodeFormDialog = false">取消</el-button>
                <el-button type="primary" @click="submitEpisode" :loading="uploading" :disabled="uploadingVideo"
                    >提交</el-button
                >
            </template>
        </el-dialog>
    </el-dialog>
</template>
<script setup>
import { onMounted, reactive, ref, computed, onBeforeUnmount } from 'vue'
import PagingTable from '@/components/PagingTable.vue'
import { useTimeFormatter } from '@/utils/formatter'
import { Plus, Search } from '@vicons/tabler'
import EditDialog from '@/components/EditDialog.vue'
import { setupEditDialog } from '@/utils/editDialog'
import EnumSelect from '@/components/EnumSelect.vue'
import { http } from '@/plugins/http'
import { ElMessage } from 'element-plus'
import { useClipboard } from '@vueuse/core'
import SingleUpload from '@/components/SingleUpload.vue'

const query = ref({ categories: [], title: '' })
const timeFormatter = useTimeFormatter()
const table = ref(null)
const model = ref({})
const rules = {
    title: [{ required: true, message: '请输入剧名', trigger: 'blur' }],
    cover: [{ required: true, message: '请上传封面', trigger: 'blur' }]
}
const { showEditDialog } = setupEditDialog(model)
async function onEdit(row) {
    if (!categories.value.length) {
        await fetchCategories()
    }
    model.value = row ? await http.get(`/series/${row.id}`) : {}
    if (Array.isArray(model.value.categories)) {
        const isIdArray = model.value.categories.length > 0 && typeof model.value.categories[0] !== 'object'
        if (isIdArray) {
            model.value.categories = model.value.categories
                .map((cid) => categories.value.find((c) => c.id === cid))
                .filter(Boolean)
        }
    }
    showEditDialog.value = true
}
async function submit() {
    const isHttpUrl = (val) => typeof val === 'string' && /^http/.test(val)
    const buildPayload = () => {
        const payload = { ...model.value }
        if (Array.isArray(model.value.categories)) {
            const original = model.value.categories
            const mapped = original
                .map((c) => (typeof c === 'object' ? c.id : c))
                .map((id) => (typeof id === 'string' ? id.trim() : id))
            const filtered = mapped.filter(
                (id) => id !== undefined && id !== null && id !== '' && id !== 'undefined' && id !== 'null'
            )
            const asNumbers = filtered.map((id) => Number(id))
            const finalIds = asNumbers.filter((id) => Number.isInteger(id) && id > 0)
            const finalObjects = finalIds.map((id) => ({ id }))
            payload.categories = finalObjects
        }
        if (model.value.cover === null) {
            payload.cover = null
        } else if (isHttpUrl(model.value.cover)) {
            delete payload.cover
        }
        if (model.value.landscapeCover === null) {
            payload.landscapeCover = null
        } else if (isHttpUrl(model.value.landscapeCover)) {
            delete payload.landscapeCover
        }
        return payload
    }

    const payload = buildPayload()

    if (model.value.id) {
        await http.put(`/series/${model.value.id}`, payload)
    } else {
        await http.post('/series', payload)
    }
    ElMessage.success('保存成功')
}
const categories = ref([])
async function fetchCategories() {
    try {
        const res = await http.get('/categories', { order: 'sort', pageSize: 1000 })
        categories.value = Array.isArray(res) ? res : res?.data || []
    } catch (e) {
        categories.value = []
    }
}
onMounted(() => {
    fetchCategories()
})
const showUploadDialog = ref(false)
const uploading = ref(false)
const uploadingVideo = ref(false)
const episodeForm = reactive({
    seriesId: null,
    episodeNum: 1,
    video: '',
    price: '',
    folder: ''
})
const episodes = ref([])
const showEpisodeFormDialog = ref(false)
const editingEpisode = ref(null)
// 拉取集数列表
async function fetchEpisodes(seriesId) {
    if (!seriesId) return
    const res = await http.get('/episodes', { seriesId, order: 'episodeNum', pageSize: 1000 })
    episodes.value = res.data || []
}
// 打开集数管理弹窗时，拉取集数
function onUploadEpisode(row) {
    episodeForm.seriesId = row.id
    episodeForm.episodeNum = 1
    episodeForm.video = ''
    episodeForm.price = ''
    episodeForm.folder = row.title || ''
    showUploadDialog.value = true
    fetchEpisodes(row.id)
}
// 新增集数
function onAddEpisode() {
    editingEpisode.value = null
    // 自动填写当前最大集数+1
    const maxNum = episodes.value.length > 0 ? Math.max(...episodes.value.map((e) => Number(e.episodeNum) || 0)) : 0
    episodeForm.episodeNum = maxNum + 1
    episodeForm.video = ''
    episodeForm.price = ''
    showEpisodeFormDialog.value = true
}
// 编辑集数
function onEditEpisode(ep) {
    editingEpisode.value = ep
    episodeForm.seriesId = ep.seriesId
    episodeForm.episodeNum = ep.episodeNum
    episodeForm.video = ep.video
    episodeForm.price = ep.price
    showEpisodeFormDialog.value = true
}
// 提交集数（新增/编辑）
async function submitEpisode() {
    // 只有新增时校验视频文件
    if (!editingEpisode.value && !episodeForm.video) {
        ElMessage.error('请上传视频文件')
        return
    }
    uploading.value = true
    try {
        if (editingEpisode.value && editingEpisode.value.id) {
            await http.put(`/episodes/${editingEpisode.value.id}`, {
                seriesId: episodeForm.seriesId,
                episodeNum: episodeForm.episodeNum,
                video: episodeForm.video,
                price: episodeForm.price
            })
            ElMessage.success('修改成功')
        } else {
            await http.post('/episodes', {
                seriesId: episodeForm.seriesId,
                episodeNum: episodeForm.episodeNum,
                video: episodeForm.video,
                price: episodeForm.price
            })
            ElMessage.success('上传成功')
        }
        showEpisodeFormDialog.value = false
        fetchEpisodes(episodeForm.seriesId)
    } catch (e) {
        ElMessage.error('操作失败')
    } finally {
        uploading.value = false
    }
}
const uploadVideoUrl = import.meta.env.VITE_API_BASE_URL + '/files/uploadVideo'
const uploadHeaders = { Authorization: `Bearer ${http.token?.value || ''}` }
function onBeforeVideoUpload() {
    uploadingVideo.value = true
}
function handleVideoSuccess(res) {
    episodeForm.video = res.url
    uploadingVideo.value = false
}
</script>
<style scoped>
.episode-manage-dialog .el-dialog {
    max-width: 400px;
    width: 400px;
}
.episode-manage-content {
    padding: 16px 24px 48px 24px;
    position: relative;
}
.episode-col {
    margin-bottom: 10px;
}
.episode-box {
    cursor: pointer;
    border: 1px solid #dcdfe6;
    border-radius: 6px;
    padding: 12px 0 4px 0;
    text-align: center;
    background: #f5f7fa;
    font-weight: bold;
    font-size: 18px;
    transition: 0.2s;
    user-select: none;
}
.episode-box.active {
    border: 2px solid #409eff;
    background: #e6f7ff;
}
.episode-price {
    font-size: 12px;
    color: #888;
    margin-top: 2px;
    font-weight: normal;
}
.episode-add-btn {
    position: absolute;
    right: 24px;
    bottom: 24px;
    z-index: 2;
    min-width: 80px;
    display: flex;
    align-items: center;
    justify-content: center;
}
@media (max-width: 700px) {
    .episode-manage-dialog .el-dialog {
        width: 100% !important;
        min-width: unset;
        max-width: 100vw;
    }
    .episode-manage-content {
        padding: 8px 4px 56px 4px;
    }
    .episode-add-btn {
        right: 8px;
        bottom: 8px;
        min-width: 60px;
    }
}
</style>
