<template>
    <el-main>
        <el-card shadow="never">
            <template #header>
                <div class="header-row">
                    <span>任务管理</span>
                    <el-button type="primary" @click="openCreate">新增任务</el-button>
                </div>
            </template>

            <el-table v-loading="loading" :data="list">
                <el-table-column prop="id" label="ID" width="80" />
                <el-table-column prop="title" label="标题" min-width="180" show-overflow-tooltip />
                <el-table-column prop="explain" label="说明" min-width="220" show-overflow-tooltip />
                <el-table-column label="类型" width="110" align="center">
                    <template #default="{ row }">
                        {{ taskTypeLabel(row.type) }}
                    </template>
                </el-table-column>
                <el-table-column label="标签" width="130" align="center">
                    <template #default="{ row }">
                        <el-tag v-if="taskLabelName(row)" size="small" type="info">{{ taskLabelName(row) }}</el-tag>
                        <span v-else>-</span>
                    </template>
                </el-table-column>
                <el-table-column prop="exp" label="经验值" width="100" align="center" />
                <el-table-column prop="total" label="总量" width="100" align="center" />
                <el-table-column label="等级" min-width="120" show-overflow-tooltip align="center">
                    <template #default="{ row }">
                        {{ taskGradeNameLabel(row.grade) }}
                    </template>
                </el-table-column>
                <el-table-column prop="kefu_id" label="客服ID" width="100" align="center" />
                <el-table-column prop="price" label="价格" width="110" />
                <el-table-column label="素材" min-width="180">
                    <template #default="{ row }">
                        <div v-if="row.materialDisplay.length">
                            <el-tag
                                v-for="(item, index) in row.materialDisplay"
                                :key="`${row.id}-${index}`"
                                size="small"
                                class="material-tag"
                            >
                                {{ item }}
                            </el-tag>
                        </div>
                        <span v-else>-</span>
                    </template>
                </el-table-column>
                <el-table-column label="状态" width="120">
                    <template #default="{ row }">
                        <el-switch
                            :model-value="Number(row.status)"
                            :active-value="1"
                            :inactive-value="0"
                            active-text="开启"
                            inactive-text="关闭"
                            inline-prompt
                            active-color="#13ce66"
                            inactive-color="#ff4949"
                            @change="(val) => changeStatus(row, val)"
                        />
                    </template>
                </el-table-column>
                <el-table-column prop="end_time" label="截稿日期" min-width="160">
                    <template #default="{ row }">
                        {{ formatTime(row.end_time) }}
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="200" fixed="right">
                    <template #default="{ row }">
                        <div class="table-row-actions">
                            <el-button type="primary" size="small" @click="openEdit(row)">编辑</el-button>
                            <el-button type="danger" size="small" plain @click="removeTask(row)">删除</el-button>
                        </div>
                    </template>
                </el-table-column>
            </el-table>

            <div class="pager">
                <el-pagination
                    background
                    layout="total, prev, pager, next, sizes"
                    :total="total"
                    :current-page="query.page"
                    :page-size="query.limit"
                    :page-sizes="[5, 10, 20, 50]"
                    @current-change="handlePageChange"
                    @size-change="handleSizeChange"
                />
            </div>
        </el-card>

        <el-dialog v-model="dialogVisible" :title="dialogTitle" width="640px" destroy-on-close>
            <el-form ref="formRef" :model="form" :rules="rules" label-width="90px">
                <el-form-item label="类型" prop="type">
                    <el-radio-group v-model="form.type">
                        <el-radio label="0">普通剪辑</el-radio>
                        <el-radio label="1">剪同款</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="标题" prop="title">
                    <el-input v-model="form.title" clearable maxlength="80" />
                </el-form-item>
                <el-form-item label="说明" prop="explain">
                    <el-input v-model="form.explain" type="textarea" :rows="4" />
                </el-form-item>
                <el-form-item label="标签" prop="label_id">
                    <el-select
                        v-model="form.label_id"
                        placeholder="请选择视频标签"
                        clearable
                        filterable
                        :loading="taskLabelLoading"
                        style="width: 100%;"
                    >
                        <el-option
                            v-for="item in taskLabelOptions"
                            :key="item.id"
                            :label="item.label"
                            :value="item.value"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item label="经验值" prop="exp">
                    <el-input v-model="form.exp" placeholder="完成任务可获得的经验值" clearable />
                </el-form-item>
                <el-form-item v-if="String(form.type) === '1'" label="封面视频" prop="coverVideoFiles">
                    <scUploadFile
                        v-model="form.coverVideoFiles"
                        :apiObj="$API.common.upload"
                        :multiple="false"
                        :limit="1"
                        accept="video/*"
                        tip="请上传封面视频，限制1个文件"
                        btnTxt="上传视频"
                    />
                </el-form-item>
                <el-form-item label="总量" prop="taskTotal">
                    <el-input v-model="form.taskTotal" placeholder="任务可领取或完成的总名额" clearable />
                </el-form-item>
                <el-form-item label="等级" prop="grade">
                    <el-select
                        v-model="form.grade"
                        placeholder="请选择用户等级"
                        clearable
                        filterable
                        :loading="levelLoading"
                        style="width: 100%;"
                    >
                        <el-option
                            v-for="item in levelOptions"
                            :key="item.id"
                            :label="item.label"
                            :value="item.value"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item label="素材" prop="materialFiles">
                    <scUploadFile
                        v-model="form.materialFiles"
                        :apiObj="$API.common.upload"
                        :multiple="true"
                        :limit="20"
                        tip="请上传素材文件，支持多文件，上传后自动写入素材链接"
                        btnTxt="上传素材"
                    />
                </el-form-item>
                <el-form-item label="价格" prop="price">
                    <el-input v-model="form.price" />
                </el-form-item>
                <el-form-item label="客服ID" prop="kefu_id">
                    <el-select
                        v-model="form.kefu_id"
                        placeholder="请选择客服"
                        clearable
                        filterable
                        :loading="kefuLoading"
                        style="width: 100%;"
                    >
                        <el-option
                            v-for="item in kefuOptions"
                            :key="item.id"
                            :label="item.label"
                            :value="item.value"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item label="截止时间" prop="endDate">
                    <el-date-picker
                        v-model="form.endDate"
                        type="datetime"
                        value-format="x"
                        placeholder="选择截止时间"
                        style="width: 100%;"
                    />
                </el-form-item>
                <el-form-item label="状态" prop="status">
                    <el-switch
                        v-model="form.status"
                        :active-value="1"
                        :inactive-value="0"
                        active-text="开启"
                        inactive-text="关闭"
                        inline-prompt
                        active-color="#13ce66"
                        inactive-color="#ff4949"
                    />
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button @click="dialogVisible = false">取消</el-button>
                <el-button type="primary" :loading="saving" @click="submitForm">保存</el-button>
            </template>
        </el-dialog>
    </el-main>
</template>

<script>
/** 与标签管理「视频标签」一致，对应接口 GET /cutter/label/list/3 */
const TASK_LABEL_LIST_TYPE = 3;

function formatMaterialLabels(material) {
    if (!Array.isArray(material) || !material.length) return [];
    return material
        .map((m) => {
            if (m == null) return "";
            if (typeof m === "string") return m.trim();
            return String(m.fileName || m.name || m.src || m.url || "").trim();
        })
        .filter(Boolean);
}

function normalizeMaterialFiles(material) {
    if (!Array.isArray(material) || !material.length) return [];
    return material
        .map((m) => {
            if (typeof m === "string") {
                const url = m.trim();
                if (!url) return null;
                const parts = url.split(/[/\\]/);
                return { name: parts[parts.length - 1] || url, url };
            }
            const src = String(m.src || m.url || "").trim();
            if (!src) return null;
            const fileName = String(m.fileName || m.name || "").trim();
            const name = fileName || src.split(/[/\\]/).pop() || src;
            return { name, url: src };
        })
        .filter(Boolean);
}

/** 列表接口 grade 为 null 或 { name, grade, icon, color } */
function taskGradeNameLabel(grade) {
    if (grade != null && typeof grade === "object") {
        const name = grade.name != null ? String(grade.name).trim() : "";
        return name || "-";
    }
    return "-";
}

/** 详情/保存表单：接口可能返回嵌套对象或纯等级数字 */
function normalizeTaskGradeForForm(grade) {
    if (grade == null || grade === "") return "";
    if (typeof grade === "object") {
        if (grade.grade != null && grade.grade !== "") return String(grade.grade);
        return "";
    }
    return String(grade);
}

function normalizeSingleUploadFile(fileValue) {
    if (!fileValue) return [];
    if (typeof fileValue === "string") {
        const url = fileValue.trim();
        if (!url) return [];
        const name = url.split(/[/\\]/).pop() || url;
        return [{ name, url }];
    }
    if (typeof fileValue === "object") {
        const url = String(fileValue.src || fileValue.url || "").trim();
        if (!url) return [];
        const name = String(fileValue.fileName || fileValue.name || "").trim() || url.split(/[/\\]/).pop() || url;
        return [{ name, url }];
    }
    return [];
}

function taskTypeLabel(type) {
    const val = String(type ?? "0");
    return val === "1" ? "剪同款" : "普通剪辑";
}

/** 列表接口 label 可能为 { id, label_name } */
function taskLabelName(row) {
    const label = row?.label;
    if (label != null && typeof label === "object") {
        const name = label.label_name != null ? String(label.label_name).trim() : "";
        return name || "";
    }
    return "";
}

export default {
    name: "taskList",
    data() {
        return {
            loading: false,
            saving: false,
            list: [],
            total: 0,
            kefuLoading: false,
            kefuOptions: [],
            levelLoading: false,
            levelOptions: [],
            taskLabelLoading: false,
            taskLabelOptions: [],
            query: {
                page: 1,
                limit: 15
            },
            dialogVisible: false,
            dialogTitle: "新增任务",
            form: this.getDefaultForm(),
            rules: {
                title: [{ required: true, message: "请输入标题", trigger: "blur" }],
                explain: [{ required: true, message: "请输入说明", trigger: "blur" }],
                type: [{ required: true, message: "请选择类型", trigger: "change" }],
                materialFiles: [
                    {
                        validator: (rule, value, callback) => {
                            if (Array.isArray(value) && value.length) callback();
                            else callback(new Error("请上传素材文件"));
                        },
                        trigger: "change"
                    }
                ],
                coverVideoFiles: [
                    {
                        validator: (rule, value, callback) => {
                            if (String(this.form.type) !== "1") {
                                callback();
                                return;
                            }
                            if (Array.isArray(value) && value.length && value[0]?.url) callback();
                            else callback(new Error("请上传封面视频"));
                        },
                        trigger: "change"
                    }
                ],
                price: [{ required: true, message: "请输入价格", trigger: "blur" }],
                exp: [{ required: true, message: "请输入经验值", trigger: "blur" }],
                taskTotal: [{ required: true, message: "请输入总量", trigger: "blur" }],
                grade: [{ required: true, message: "请选择等级", trigger: "change" }],
                label_id: [{ required: true, message: "请选择标签", trigger: "change" }],
                kefu_id: [{ required: true, message: "请选择客服", trigger: "change" }],
                endDate: [{ required: true, message: "请选择截止时间", trigger: "change" }]
            }
        };
    },
    created() {
        this.getKefuOptions();
        this.getLevelOptions();
        this.getTaskLabelOptions();
        this.getList();
    },
    methods: {
        getDefaultForm() {
            return {
                id: "",
                title: "",
                explain: "",
                type: "0",
                coverVideoFiles: [],
                cover_video: "",
                materialFiles: [],
                price: "",
                exp: "",
                taskTotal: "",
                grade: "",
                kefu_id: "",
                label_id: "",
                endDate: "",
                end_time: "",
                status: 1
            };
        },
        formatTime(ts) {
            if (!ts) return "-";
            const num = Number(ts);
            if (!num) return ts;
            return this.$TOOL.getTime(Math.floor(num / 1000), "YYYY-MM-DD HH:mm:ss");
        },
        taskGradeNameLabel,
        taskTypeLabel,
        taskLabelName,
        async getList() {
            this.loading = true;
            try {
                const res = await this.$API.task.list.get(this.query);
                if (res.code !== 1) {
                    this.$message.error(res.msg || "获取任务列表失败");
                    return;
                }
                const data = res.data || {};
                const rawList = data.data || data.list || [];
                this.list = rawList.map((item) => ({
                    ...item,
                    materialDisplay: formatMaterialLabels(item.material),
                    // 后端字段为 pirce，这里统一映射给表格展示
                    price: item.price || item.pirce || ""
                }));
                this.total = Number(data.count || data.total || this.list.length || 0);
            } finally {
                this.loading = false;
            }
        },
        async getKefuOptions() {
            this.kefuLoading = true;
            try {
                const res = await this.$API.kefu.list.get({ page: 1, limit: 200 });
                if (res.code !== 1) {
                    this.$message.error(res.msg || "获取客服列表失败");
                    return;
                }
                const data = res.data || {};
                const rawList = data.data || data.list || [];
                this.kefuOptions = rawList.map((item) => ({
                    id: item.id,
                    value: String(item.id),
                    label: item.name ? `${item.name}（id:${item.id}）` : String(item.id)
                }));
            } finally {
                this.kefuLoading = false;
            }
        },
        async getLevelOptions() {
            this.levelLoading = true;
            try {
                const res = await this.$API.user.levelList.get();
                if (res.code !== 1) {
                    this.$message.error(res.msg || "获取用户等级列表失败");
                    return;
                }
                const raw = res.data || {};
                const rawList = Array.isArray(raw) ? raw : raw.list || raw.data || [];
                const sorted = rawList.slice().sort((a, b) => Number(a.grade) - Number(b.grade));
                this.levelOptions = sorted.map((item) => ({
                    id: item.id,
                    value: String(item.grade ?? ""),
                    label: item.name
                        ? `${item.name}（等级 ${item.grade}）`
                        : `等级 ${item.grade}`
                }));
            } finally {
                this.levelLoading = false;
            }
        },
        async getTaskLabelOptions() {
            this.taskLabelLoading = true;
            try {
                const res = await this.$API.cutter.labelList.get(TASK_LABEL_LIST_TYPE);
                if (res.code !== 1) {
                    this.$message.error(res.msg || "获取标签列表失败");
                    return;
                }
                const raw = res.data;
                const rawList = Array.isArray(raw) ? raw : raw?.list || raw?.data || [];
                this.taskLabelOptions = rawList.map((item) => ({
                    id: item.id,
                    value: String(item.id),
                    label: item.label_name ?? item.name ?? String(item.id)
                }));
            } finally {
                this.taskLabelLoading = false;
            }
        },
        handlePageChange(page) {
            this.query.page = page;
            this.getList();
        },
        handleSizeChange(limit) {
            this.query.limit = limit;
            this.query.page = 1;
            this.getList();
        },
        openCreate() {
            this.dialogTitle = "新增任务";
            this.form = this.getDefaultForm();
            this.dialogVisible = true;
        },
        async openEdit(row) {
            this.dialogTitle = "编辑任务";
            this.form = this.getDefaultForm();
            this.dialogVisible = true;
            const res = await this.$API.task.info.get(row.id);
            if (res.code !== 1) {
                this.$message.error(res.msg || "获取任务详情失败");
                return;
            }
            const info = res.data || {};
            const materialFiles = normalizeMaterialFiles(
                Array.isArray(info.material) ? info.material : []
            );
            const endTime = info.end_time ? Number(info.end_time) * 1000 : "";
            this.form = {
                id: info.id || row.id,
                title: info.title || "",
                explain: info.explain || "",
                type: String(info.type ?? "0"),
                coverVideoFiles: normalizeSingleUploadFile(info.cover_video),
                cover_video: String(info.cover_video || ""),
                materialFiles,
                price: info.price || info.pirce || "",
                exp: info.exp != null && info.exp !== "" ? String(info.exp) : "",
                taskTotal: info.total != null && info.total !== "" ? String(info.total) : "",
                grade: normalizeTaskGradeForForm(info.grade),
                kefu_id: String(info.kefu_id || ""),
                label_id:
                    info.label_id != null && info.label_id !== ""
                        ? String(info.label_id)
                        : "",
                endDate: endTime ? String(endTime) : "",
                end_time: String(info.end_time || ""),
                status: Number(info.status ?? 1)
            };
        },
        async submitForm() {
            this.$refs.formRef.validate(async (valid) => {
                if (!valid) return false;
                this.saving = true;
                try {
                    const material = (this.form.materialFiles || []).map((f) => ({
                        fileName: f.name || "",
                        src: f.url || ""
                    })).filter((m) => m.src);
                    const coverVideo = (this.form.coverVideoFiles || [])[0]?.url || "";
                    const endTimeSec = this.form.endDate ? Math.floor(Number(this.form.endDate) / 1000) : "";
                    const payload = {
                        title: this.form.title,
                        explain: this.form.explain,
                        type: String(this.form.type),
                        cover_video: coverVideo,
                        material,
                        price: this.form.price,
                        exp: this.form.exp,
                        total: this.form.taskTotal,
                        grade: this.form.grade,
                        label_id: this.form.label_id,
                        end_time: String(endTimeSec),
                        kefu_id: this.form.kefu_id,
                        status: String(this.form.status)
                    };
                    if (this.form.id) payload.id = this.form.id;
                    const res = await this.$API.task.save.post(payload);
                    if (res.code !== 1) {
                        this.$message.error(res.msg || "保存失败");
                        return false;
                    }
                    this.$message.success(res.msg || "保存成功");
                    this.dialogVisible = false;
                    this.getList();
                } finally {
                    this.saving = false;
                }
            });
        },
        async removeTask(row) {
            const confirm = await this.$confirm("确认删除该任务吗？", "提示", {
                type: "warning",
                confirmButtonText: "删除",
                confirmButtonClass: "el-button--danger"
            }).catch(() => {});
            if (confirm !== "confirm") return;
            const res = await this.$API.task.del.delete(row.id);
            if (res.code !== 1) {
                this.$message.error(res.msg || "删除失败");
                return;
            }
            this.$message.success(res.msg || "删除成功");
            this.getList();
        },
        async changeStatus(row, status) {
            const res = await this.$API.task.setStatus.get(row.id, status);
            if (res.code !== 1) {
                this.$message.error(res.msg || "状态更新失败");
                this.getList();
                return;
            }
            this.$message.success(res.msg || "状态更新成功");
            row.status = status;
        }
    }
};
</script>

<style scoped>
.header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.pager {
    margin-top: 16px;
    display: flex;
    justify-content: flex-end;
}

.material-tag {
    margin-right: 6px;
    margin-bottom: 4px;
}

</style>