<script setup lang="ts">
import { PlayCircleOutlined } from '@ant-design/icons-vue';
import { computed, h, onMounted, ref } from 'vue';
import VxeUI from 'vxe-table';
import ReviewMediaPreview from '@/service/ReviewMediaPreview.vue';
import type { MediaItem } from '@/service/ReviewMediaPreview.vue';
import { getEvaluateDetailMethod } from '@/request/api/order.api';
const props = defineProps<{
    data: any;
}>();

function toScore(value: unknown) {
    const n = Number(value);
    return Number.isFinite(n) ? n : 0;
}

function normalizeMediaList(input: unknown): MediaItem[] {
    if (!Array.isArray(input)) return [];
    return input
        .map((it) => {
            if (typeof it === 'string') {
                const url = it;
                const type: MediaItem['type'] = /\.(mp4|webm|ogg)(\?|#|$)/i.test(url) ? 'video' : 'image';
                return { type, url } as MediaItem;
            }
            if (it && typeof it === 'object' && 'url' in it) {
                const anyIt = it as any;
                const url = String(anyIt.url ?? '');
                if (!url) return null;
                const type: MediaItem['type'] =
                    anyIt.type === 'video' || anyIt.type === 'image'
                        ? anyIt.type
                        : /\.(mp4|webm|ogg)(\?|#|$)/i.test(url)
                            ? 'video'
                            : 'image';
                return { type, url } as MediaItem;
            }
            return null;
        })
        .filter((x): x is MediaItem => Boolean(x));
}
const scroeType = ref([{
    name: '服务质量',
    score: 0,
}, {
    name: '服务态度',
    score: 0,
}, {
    name: '环境',
    score: 0,
}]);
// 用户评价假数据（淘宝式：每条评价有多张图/多个视频，先展示缩略图排列，点击可左右滑动预览）
const evaluateDetail = ref(
    {
        depict: '',
        // 图片/视频列表
        mediaList: [] as MediaItem[],
    });

const hasEvaluate = computed(() => {
    const depict = String(evaluateDetail.value.depict ?? '').trim();
    const hasMedia = (evaluateDetail.value.mediaList?.length ?? 0) > 0;
    const hasScore = scroeType.value.some((i) => toScore(i.score) > 0);
    return Boolean(depict) || hasMedia || hasScore;
});

const REVIEW_PREVIEW_MODAL_ID = 'review-media-preview-modal';
async function getEvaluateDetail() {
    console.log(props.data, "传过来的参数");
    if (props.data && props.data.id) {
        const res = await getEvaluateDetailMethod('2', props.data.id);
        console.log(res, "获取评价");
        if (res) {
            if (scroeType.value[0]) scroeType.value[0].score = toScore(res.qualityScore); //服务质量
            if (scroeType.value[1]) scroeType.value[1].score = toScore(res.attitudeScore); //服务态度
            if (scroeType.value[2]) scroeType.value[2].score = toScore(res.environmentScore); //环境
            evaluateDetail.value.depict = res.depict;
            evaluateDetail.value.mediaList = normalizeMediaList(res.imageVideos);
        }
    }
    console.log(evaluateDetail.value, "evaluateDetail");
}

onMounted(() => {
    // 获取用户评价
    getEvaluateDetail();
});



// 预览图片/视频
function openPreview(list: MediaItem[], index: number) {
    if (!list?.length) return;
    VxeUI.modal.open({
        id: REVIEW_PREVIEW_MODAL_ID,
        title: '预览',
        width: 720,
        escClosable: true,
        destroyOnClose: true,
        slots: {
            default() {
                return h(ReviewMediaPreview, {
                    mediaList: list,
                    initialIndex: index,
                });
            },
        },
    });
}
</script>

<template>
    <div class="service-detail">
        <!-- 用户评价 -->
        <div class="info-section">
            <div class="info-content-wrapper">
                <template v-if="hasEvaluate">
                    <div class="review-item">
                        <div class="review-top-container">
                            <div class="review-rating-box">
                                <div class="review-rating-row" v-for="scroe in scroeType" :key="scroe.name">
                                    <span class="review-criterion">{{ scroe.name }}</span>
                                    <a-rate :value="scroe.score" disabled allow-half class="review-stars" />
                                    <span class="review-score">{{ scroe.score }}分</span>
                                </div>
                            </div>
                            <div class="review-content-block">
                                <div class="review-content-line">
                                    <span class="review-content-label">评价内容:</span>
                                    <span class="review-content-text">{{ evaluateDetail.depict }}</span>
                                </div>
                                <div v-if="evaluateDetail.mediaList?.length" class="review-media-row">
                                    <div v-for="(media, i) in evaluateDetail.mediaList" :key="i" class="review-media-thumb"
                                        :class="{ 'is-video': media.type === 'video' }" role="button" tabindex="0"
                                        @click.stop.prevent="openPreview(evaluateDetail.mediaList, i)"
                                        @keydown.enter.space.prevent="openPreview(evaluateDetail.mediaList, i)">
                                        <img v-if="media.type === 'image'" :src="media.url" class="review-thumb-img" alt="" />
                                        <div v-else class="review-thumb-video">
                                            <video :src="media.url" muted preload="metadata" />
                                            <span class="review-thumb-play">
                                                <PlayCircleOutlined />
                                            </span>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </template>
                <div v-else class="empty-text">无</div>
            </div>
        </div>
    </div>
</template>

<style scoped lang="scss">
.service-detail {
    padding: 20px;
    color: black;
    background: #fff;

    .info-section {
        margin-top: 24px;
        margin-bottom: 24px;
        background: #fff;
    }

    .info-title {
        font-size: 16px;
        font-weight: 600;
        margin-bottom: 12px;
        color: #333;
    }

    .info-title-row {
        display: flex;
        align-items: center;
        gap: 8px;
        margin-bottom: 12px;

        .info-title {
            margin-bottom: 0;
        }
    }

    .info-content-wrapper {
        border: 1px solid #e8e8e8;
        border-radius: 4px;
        padding: 10px 20px;
    }

    .empty-text {
        color: #999;
        font-size: 14px;
        line-height: 22px;
        padding: 8px 0;
    }

    .review-item {
        padding: 12px 0;
        border-bottom: 1px solid #f0f0f0;

        &:last-child {
            border-bottom: none;
        }
    }

    .review-top-container {
        display: flex;
        align-items: flex-start;
        gap: 24px;
        margin-bottom: 12px;
    }

    .review-rating-box {
        flex-shrink: 0;
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        gap: 12px;
        min-width: 240px;
    }

    .review-rating-row {
        display: flex;
        align-items: center;
        gap: 8px;
        flex-shrink: 0;
    }

    .review-criterion {
        font-size: 14px;
        color: #333;
        width: 72px;
        text-align: left;
        white-space: nowrap;
    }

    .review-stars {
        font-size: 16px;

        :deep(.ant-rate-star-full .ant-rate-star-second) {
            color: #fadb14;
        }

        :deep(.ant-rate-star-full .ant-rate-star-first) {
            color: #fadb14;
        }
    }

    .review-score {
        font-size: 13px;
        color: #999;
    }

    .review-content-block {
        flex: 1;
        min-width: 0;
    }

    .review-content-line {
        display: flex;
        align-items: flex-start;
        gap: 6px;
    }

    .review-content-label {
        font-size: 14px;
        color: #333;
        margin-right: 4px;
        flex-shrink: 0;
    }

    .review-content-text {
        font-size: 14px;
        color: #333;
        line-height: 22px;
        margin: 0;
        white-space: pre-wrap;
        word-break: break-word;
    }

    .review-media-row {
        display: flex;
        gap: 8px;
        flex-wrap: wrap;
        margin-top: 12px;
        margin-left: 70px;
    }

    .review-media-thumb {
        width: 72px;
        height: 72px;
        border-radius: 6px;
        border: 1px solid #e8e8e8;
        overflow: hidden;
        flex-shrink: 0;
        cursor: pointer;
        background: #f5f5f5;
        transition: border-color 0.2s, box-shadow 0.2s;

        &:hover {
            border-color: #1890ff;
            box-shadow: 0 0 0 1px #1890ff;
        }

        .review-thumb-img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            display: block;
        }

        .review-thumb-video {
            position: relative;
            width: 100%;
            height: 100%;
            background: #2a2a2a;

            video {
                width: 100%;
                height: 100%;
                object-fit: cover;
                display: block;
            }

            .review-thumb-play {
                position: absolute;
                inset: 0;
                display: flex;
                align-items: center;
                justify-content: center;
                color: rgba(255, 255, 255, 0.9);
                font-size: 28px;
                pointer-events: none;
            }
        }
    }
}
</style>
