<template>
    <el-main>
        <el-card shadow="never">
            <template #header>
                <div class="header-row">
                    <span class="card-title">用户等级</span>
                    <div class="header-actions">
                        <el-button type="primary"  @click="openCreate">添加等级</el-button>
                    </div>
                </div>
            </template>

            <el-table v-loading="loading" :data="list" stripe class="level-table">
                <el-table-column prop="id" label="ID" width="88" />
                <el-table-column prop="name" label="名称" min-width="120" show-overflow-tooltip />
                <el-table-column prop="grade" label="等级" width="88" align="center" />
                <el-table-column prop="exp_num" label="所需经验" width="110" align="right" />
                <el-table-column label="图标" width="88" align="center">
                    <template #default="{ row }">
                        <el-image
                            v-if="row.icon"
                            class="level-icon"
                            :src="row.icon"
                            fit="contain"
                            :preview-src-list="[row.icon]"
                            preview-teleported
                        />
                        <span v-else>-</span>
                    </template>
                </el-table-column>
                <el-table-column label="背景图" width="88" align="center">
                    <template #default="{ row }">
                        <el-image
                            v-if="row.background"
                            class="level-icon"
                            :src="row.background"
                            fit="contain"
                            :preview-src-list="[row.background]"
                            preview-teleported
                        />
                        <span v-else>-</span>
                    </template>
                </el-table-column>
                <el-table-column label="颜色" min-width="140" show-overflow-tooltip>
                    <template #default="{ row }">
                        {{ rowColorSummary(row) }}
                    </template>
                </el-table-column>
                <el-table-column prop="explain" label="说明" min-width="200" show-overflow-tooltip />
                <el-table-column label="显示" width="120" align="center">
                    <template #default="{ row }">
                        <el-switch
                            :model-value="Number(row.is_show)"
                            :active-value="1"
                            :inactive-value="0"
                            inline-prompt
                            active-text="显示"
                            inactive-text="隐藏"
                            active-color="#13ce66"
                            inactive-color="#909399"
                            @change="(val) => changeShow(row, val)"
                        />
                    </template>
                </el-table-column>
                <el-table-column label="创建时间" min-width="170" show-overflow-tooltip>
                    <template #default="{ row }">
                        {{ formatTime(row.created_at) }}
                    </template>
                </el-table-column>
                <el-table-column label="更新时间" min-width="170" show-overflow-tooltip>
                    <template #default="{ row }">
                        {{ formatTime(row.updated_at) }}
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="248" fixed="right">
                    <template #default="{ row }">
                        <div class="table-row-actions">
                            <el-button type="info" size="small" @click="showDetail(row)">详情</el-button>
                            <el-button type="primary" size="small" @click="openEdit(row)">编辑</el-button>
                            <el-button type="danger" size="small" @click="removeRow(row)">删除</el-button>
                        </div>
                    </template>
                </el-table-column>
            </el-table>
        </el-card>

        <el-dialog v-model="detailDialog" title="等级详情" width="560px" destroy-on-close>
            <el-descriptions :column="1" border>
                <el-descriptions-item label="ID">{{ detail.id ?? "-" }}</el-descriptions-item>
                <el-descriptions-item label="名称">{{ detail.name ?? "-" }}</el-descriptions-item>
                <el-descriptions-item label="等级">{{ detail.grade ?? "-" }}</el-descriptions-item>
                <el-descriptions-item label="所需经验">{{ detail.exp_num ?? "-" }}</el-descriptions-item>
                <el-descriptions-item label="说明">{{ detail.explain ?? "-" }}</el-descriptions-item>
                <el-descriptions-item label="显示">
                    <el-tag :type="Number(detail.is_show) === 1 ? 'success' : 'info'" size="small">
                        {{ Number(detail.is_show) === 1 ? "显示" : "隐藏" }}
                    </el-tag>
                </el-descriptions-item>
                <el-descriptions-item label="图标">
                    <el-image
                        v-if="detail.icon"
                        class="detail-icon"
                        :src="detail.icon"
                        fit="cover"
                        :preview-src-list="[detail.icon]"
                        preview-teleported
                    />
                    <span v-else>-</span>
                </el-descriptions-item>
                <el-descriptions-item label="背景图">
                    <el-image
                        v-if="detail.background"
                        class="detail-bg"
                        :src="detail.background"
                        fit="cover"
                        :preview-src-list="[detail.background]"
                        preview-teleported
                    />
                    <span v-else>-</span>
                </el-descriptions-item>
                <el-descriptions-item label="颜色">
                    <template v-if="detailColorTags.length">
                        <el-tag v-for="(c, i) in detailColorTags" :key="i" size="small" class="color-tag">{{ c }}</el-tag>
                    </template>
                    <span v-else>-</span>
                </el-descriptions-item>
                <el-descriptions-item label="创建时间">{{ formatTime(detail.created_at) }}</el-descriptions-item>
                <el-descriptions-item label="更新时间">{{ formatTime(detail.updated_at) }}</el-descriptions-item>
            </el-descriptions>
        </el-dialog>

        <el-dialog v-model="editDialog" :title="editTitle" width="580px" destroy-on-close @closed="resetEditForm">
            <el-form ref="formRef" :model="form" :rules="rules" label-width="96px">
                <el-form-item label="名称" prop="name">
                    <el-input v-model="form.name" clearable maxlength="64" placeholder="如 Lv1" />
                </el-form-item>
                <el-form-item label="等级" prop="grade">
                    <el-input-number v-model="form.grade" :min="0" :max="9999" :step="1" controls-position="right" class="w-full-num" />
                </el-form-item>
                <el-form-item label="所需经验" prop="exp_num">
                    <el-input-number v-model="form.exp_num" :min="0" :max="999999999" :step="1" controls-position="right" class="w-full-num" />
                </el-form-item>
                <el-form-item label="图标" prop="icon">
                    <div class="icon-field">
                        <sc-upload v-model="form.icon" title="上传" :api-obj="$API.common.upload" />
                        <el-input v-model="form.icon" placeholder="或填写图片地址" clearable />
                    </div>
                </el-form-item>
                <el-form-item label="背景图" prop="background">
                    <div class="icon-field">
                        <sc-upload v-model="form.background" title="上传" :api-obj="$API.common.upload" />
                        <el-input v-model="form.background" placeholder="或填写背景图地址" clearable />
                    </div>
                </el-form-item>
                <el-form-item label="颜色" prop="colorList">
                    <div class="color-palette-field">
                        <p v-if="!form.colorList.length" class="palette-hint">点击「添加颜色」，用取色器选择</p>
                        <div v-for="(_, index) in form.colorList" :key="'palette-row-' + index" class="palette-row">
                            <el-color-picker
                                :model-value="form.colorList[index]"
                                color-format="hex"
                                :show-alpha="false"
                                @update:model-value="(v) => updatePaletteColor(index, v)"
                            />
                            <span class="palette-hex">{{ form.colorList[index] }}</span>
                            <el-button type="danger" link size="small" @click="removePaletteColor(index)">移除</el-button>
                        </div>
                        <el-button size="small" type="primary" plain @click="addPaletteColor">添加颜色</el-button>
                    </div>
                </el-form-item>
                <el-form-item label="说明" prop="explain">
                    <el-input v-model="form.explain" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="等级说明" />
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button @click="editDialog = false">取消</el-button>
                <el-button type="primary" :loading="saving" @click="submitForm">保存</el-button>
            </template>
        </el-dialog>
    </el-main>
</template>

<script>
function defaultLevelForm() {
    return {
        id: "",
        name: "",
        grade: 1,
        exp_num: 0,
        icon: "",
        background: "",
        colorList: [],
        explain: ""
    };
}

/** 规范为六位小写 #rrggbb，供接口 ["#000000"] 格式 */
function normalizeHex(val) {
    if (val == null || val === "") return "#000000";
    let s = String(val).trim();
    if (!s.startsWith("#")) s = `#${s}`;
    if (s.length === 9 && /^#[0-9a-fA-F]{8}$/.test(s)) s = s.slice(0, 7);
    if (s.length === 4 && /^#[0-9a-fA-F]{3}$/.test(s)) {
        s = `#${s[1]}${s[1]}${s[2]}${s[2]}${s[3]}${s[3]}`;
    }
    if (!/^#[0-9a-fA-F]{6}$/.test(s)) return "#000000";
    return s.toLowerCase();
}

/** 将接口里的 color（一维字符串数组；兼容历史 JSON 字符串或逗号分隔）解析为字符串数组 */
function parseColorList(val) {
    if (val == null || val === "") return [];
    if (Array.isArray(val)) return val.map(String).filter(Boolean);
    if (typeof val === "string") {
        const s = val.trim();
        if (!s) return [];
        try {
            const parsed = JSON.parse(s);
            if (Array.isArray(parsed)) return parsed.map(String).filter(Boolean);
        } catch (_) {
            /* 非 JSON 时按分隔符拆分 */
        }
        return s.split(/[,，]/).map((x) => x.trim()).filter(Boolean);
    }
    return [];
}

export default {
    name: "UserLevelList",
    computed: {
        detailColorTags() {
            return parseColorList(this.detail?.color);
        }
    },
    data() {
        return {
            loading: false,
            saving: false,
            list: [],
            detailDialog: false,
            detail: {},
            editDialog: false,
            editTitle: "添加等级",
            form: defaultLevelForm(),
            rules: {
                name: [{ required: true, message: "请输入名称", trigger: "blur" }],
                grade: [{ required: true, message: "请输入等级", trigger: "change" }],
                exp_num: [{ required: true, message: "请输入所需经验", trigger: "change" }],
                icon: [{ required: true, message: "请上传或填写图标地址", trigger: "blur" }],
                explain: [{ required: true, message: "请输入说明", trigger: "blur" }]
            }
        };
    },
    created() {
        this.getList();
    },
    methods: {
        rowColorSummary(row) {
            const arr = parseColorList(row?.color);
            if (!arr.length) return "-";
            return arr.join("、");
        },
        addPaletteColor() {
            this.form.colorList.push("#409eff");
        },
        removePaletteColor(index) {
            this.form.colorList.splice(index, 1);
        },
        updatePaletteColor(index, val) {
            if (val == null || val === "") {
                this.form.colorList.splice(index, 1);
                return;
            }
            const hex = normalizeHex(val);
            this.form.colorList.splice(index, 1, hex);
        },
        formatTime(val) {
            if (val === undefined || val === null || val === "") return "-";
            if (typeof val === "string" && /^\d{4}-\d{2}-\d{2}/.test(val.trim())) return val.trim();
            const num = Number(val);
            if (!Number.isFinite(num) || num <= 0) return String(val);
            const sec = num > 1e12 ? Math.floor(num / 1000) : num;
            return this.$TOOL.getTime(sec, "YYYY-MM-DD HH:mm:ss");
        },
        async getList() {
            this.loading = true;
            try {
                const res = await this.$API.user.levelList.get();
                if (res.code !== 1) {
                    this.$message.error(res.msg || "获取用户等级列表失败");
                    return;
                }
                const raw = res.data || {};
                this.list = Array.isArray(raw) ? raw : raw.list || raw.data || [];
            } finally {
                this.loading = false;
            }
        },
        async showDetail(row) {
            const id = row?.id;
            if (id == null) return;
            const res = await this.$API.user.levelInfo.get(id);
            if (res.code !== 1) {
                this.$message.error(res.msg || "获取详情失败");
                return;
            }
            this.detail = res.data || {};
            this.detailDialog = true;
        },
        openCreate() {
            this.editTitle = "添加等级";
            this.form = defaultLevelForm();
            this.editDialog = true;
            this.$nextTick(() => this.$refs.formRef?.clearValidate());
        },
        openEdit(row) {
            this.editTitle = "编辑等级";
            this.form = {
                id: row.id != null ? String(row.id) : "",
                name: row.name || "",
                grade: row.grade != null ? Number(row.grade) : 1,
                exp_num: row.exp_num != null ? Number(row.exp_num) : 0,
                icon: row.icon || "",
                background: row.background || "",
                colorList: parseColorList(row.color).map((c) => normalizeHex(c)),
                explain: row.explain || ""
            };
            this.editDialog = true;
            this.$nextTick(() => this.$refs.formRef?.clearValidate());
        },
        resetEditForm() {
            this.form = defaultLevelForm();
        },
        submitForm() {
            this.$refs.formRef.validate(async (valid) => {
                if (!valid) return false;
                this.saving = true;
                try {
                    /** 接口约定：color 为一维数组，元素为颜色字符串，如 ["#000000","#ffffff"] */
                    const color = (this.form.colorList || []).map((x) => normalizeHex(x));
                    const payload = {
                        name: (this.form.name || "").trim(),
                        grade: this.form.grade,
                        exp_num: this.form.exp_num,
                        icon: (this.form.icon || "").trim(),
                        background: (this.form.background || "").trim(),
                        color,
                        explain: (this.form.explain || "").trim()
                    };
                    if (this.form.id) payload.id = String(this.form.id);
                    const res = await this.$API.user.levelSave.post(payload);
                    if (res.code !== 1) {
                        this.$message.error(res.msg || "保存失败");
                        return false;
                    }
                    this.$message.success(res.msg || "保存成功");
                    this.editDialog = false;
                    this.getList();
                } finally {
                    this.saving = false;
                }
            });
        },
        async removeRow(row) {
            const id = row?.id;
            if (id == null) return;
            try {
                await this.$confirm("确认删除该等级吗？", "提示", {
                    type: "warning",
                    confirmButtonText: "删除",
                    cancelButtonText: "取消"
                });
            } catch (e) {
                return;
            }
            const res = await this.$API.user.levelDel.delete(id);
            if (res.code !== 1) {
                this.$message.error(res.msg || "删除失败");
                return;
            }
            this.$message.success(res.msg || "删除成功");
            this.getList();
        },
        async changeShow(row, show) {
            const id = row?.id;
            if (id == null) {
                this.$message.error("缺少等级 ID");
                return;
            }
            const res = await this.$API.user.levelSetShow.get(id, show);
            if (res.code !== 1) {
                this.$message.error(res.msg || "显示状态更新失败");
                this.getList();
                return;
            }
            this.$message.success(res.msg || "已更新");
            row.is_show = show;
        }
    }
};
</script>

<style scoped>
.card-title {
    font-size: 16px;
    font-weight: 600;
    color: var(--el-text-color-primary);
    letter-spacing: 0.02em;
}
.header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
}
.header-actions {
    display: flex;
    align-items: center;
    gap: 12px;
}
.level-table :deep(.el-table__header th.el-table__cell) {
    font-weight: 600;
    color: var(--el-text-color-regular);
}
.level-icon {
    width: 40px;
    height: 40px;
    border-radius: 6px;
}
.detail-icon {
    width: 72px;
    height: 72px;
    border-radius: 8px;
}
.icon-field {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
}
.w-full-num {
    width: 100%;
}
.w-full-num :deep(.el-input__inner) {
    text-align: left;
}
.color-palette-field {
    width: 100%;
}
.palette-hint {
    margin: 0 0 10px;
    font-size: 12px;
    color: var(--el-text-color-placeholder);
}
.palette-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 10px;
}
.palette-hex {
    font-family: ui-monospace, monospace;
    font-size: 13px;
    color: var(--el-text-color-regular);
    min-width: 7.5em;
}
.detail-bg {
    max-width: 240px;
    max-height: 120px;
    border-radius: 8px;
}
.color-tag {
    margin-right: 6px;
    margin-bottom: 4px;
}
</style>
