<template>
  <div class="review-appeal-history-container">
    <div class="page-header">
      <el-button @click="goBack"> 返回 </el-button>
      <h2 class="page-title">申诉历史</h2>
    </div>

    <div class="tabs-section">
      <el-tabs v-model="activeTab" @tab-change="handleTabClick($event)">
        <el-tab-pane label="全部" name="all" />
        <el-tab-pane label="审核中" name="pending" />
        <el-tab-pane label="被驳回" name="rejected" />
        <el-tab-pane label="已通过" name="approved" />
      </el-tabs>
    </div>

    <div v-if="appealHistoryList.length > 0" class="appeal-history-list">
      <div v-for="item in appealHistoryList" :key="item.id" class="appeal-card">
        <!-- 标题行：顾客评价 + 状态标签 -->
        <div class="card-title-row">
          <span class="card-title">顾客评价</span>
          <el-tag :class="['status-tag', getAppealStatusTagClass(item.appealStatus)]" size="default">
            {{ getAppealStatusText(item.appealStatus) }}
          </el-tag>
        </div>

        <!-- 用户信息：头像、昵称、评价时间 -->
        <div class="card-user">
          <el-avatar :src="getUserAvatar(item)" :size="40" class="user-avatar">
            <el-icon><User /></el-icon>
          </el-avatar>
          <div class="user-meta">
            <div class="user-name">
              {{ item.isAnonymous == 1 || !item.userName ? "匿名用户" : item.userName }}
            </div>
            <div class="review-time">
              {{ formatTime(item.createdTime) }}
            </div>
          </div>
        </div>

        <!-- 评价内容 -->
        <div class="card-content">
          {{ getCommentContent(item) }}
        </div>

        <!-- 评价图片/视频（视频用首帧 + 播放图标，可预览） -->
        <div v-if="getCommentMedia(item).length > 0" class="card-media">
          <template v-for="(m, idx) in getCommentMedia(item)" :key="idx">
            <el-image
              v-if="m.type === 'image'"
              :src="m.url"
              :preview-src-list="getCommentMediaImages(item)"
              :initial-index="getMediaImageIndex(getCommentMedia(item), idx)"
              fit="cover"
              class="media-item comment-img"
            />
            <div v-else class="media-item media-video-wrap" @click="openVideoPreview(m.url)">
              <video
                :src="m.url"
                class="video-thumb"
                preload="metadata"
                muted
                playsinline
                @loadeddata="onVideoLoadedData($event)"
              />
              <div class="video-mask">
                <el-icon class="video-play-icon">
                  <VideoPlay />
                </el-icon>
              </div>
            </div>
          </template>
        </div>
        <!-- 申诉时间 + 状态 + 查看详情 -->
        <div class="card-appeal">
          <div class="appeal-time-row">
            <span class="appeal-time-label">申诉时间</span>
            <span class="appeal-time-value">{{ formatTime(item.appealTime || item.createdTime) }}</span>
          </div>
          <div class="appeal-status-row">
            <span class="appeal-status-text">
              <el-icon v-if="item.appealStatus === 0" class="status-icon status-pending"><Clock /></el-icon>
              <el-icon v-else-if="item.appealStatus === 2" class="status-icon status-approved"><CircleCheck /></el-icon>
              <el-icon v-else class="status-icon status-rejected"><CircleClose /></el-icon>
              {{ getAppealStatusDesc(item.appealStatus) }}
            </span>
            <el-button type="primary" link class="btn-detail" @click="viewDetail(item)"> 查看详情 </el-button>
          </div>
        </div>
      </div>
    </div>

    <el-empty v-else description="暂无申诉记录" />

    <div v-if="pagination.total > 0" class="pagination-section">
      <el-pagination
        v-model:current-page="pagination.page"
        v-model:page-size="pagination.pageSize"
        :page-sizes="[10, 20, 30, 50]"
        :total="pagination.total"
        layout="prev, pager, next"
        background
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 视频预览弹窗 -->
    <el-dialog
      v-model="videoPreviewVisible"
      title="视频预览"
      width="80%"
      max-width="720px"
      destroy-on-close
      align-center
      @closed="closeVideoPreview"
    >
      <video v-if="videoPreviewUrl" :src="videoPreviewUrl" controls autoplay style="width: 100%; max-height: 70vh" />
    </el-dialog>
  </div>
</template>

<script setup lang="ts" name="reviewAppealHistory">
import { ref, reactive, onMounted } from "vue";
import { useRouter } from "vue-router";
import { User, Clock, CircleCheck, CircleClose, VideoPlay } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import { getAppealHistory } from "@/api/modules/newLoginApi";
import { localGet } from "@/utils";

const router = useRouter();

const activeTab = ref("all");
const appealHistoryList = ref<any[]>([]);
const pagination = reactive({
  page: 1,
  pageSize: 10,
  total: 0
});

const goBack = () => router.back();

const handleTabClick = (val: string | number) => {
  activeTab.value = typeof val === "number" ? String(val) : val;
  pagination.page = 1;
  loadAppealHistory();
};

const handleSizeChange = (val: number) => {
  pagination.pageSize = val;
  pagination.page = 1;
  loadAppealHistory();
};

const handleCurrentChange = (val: number) => {
  pagination.page = val;
  loadAppealHistory();
};

const loadAppealHistory = async () => {
  try {
    let appealStatus =
      activeTab.value === "all" ? "" : activeTab.value === "pending" ? 0 : activeTab.value === "rejected" ? 1 : 2;
    const params: any = {
      storeId: localGet("createdId") || "",
      appealStatus,
      pageNum: pagination.page,
      pageSize: pagination.pageSize
    };

    const res: any = await getAppealHistory(params);
    const isOk = res?.code === 200 || res?.code === 0;
    const data = res?.data ?? res;

    if (isOk) {
      appealHistoryList.value = data?.records ?? data ?? [];
      pagination.total = data?.total ?? 0;
    } else {
      appealHistoryList.value = [];
      pagination.total = 0;
      if (res?.msg) ElMessage.error(res.msg);
    }
  } catch (error: any) {
    appealHistoryList.value = [];
    pagination.total = 0;
    ElMessage.error(error?.message || "获取申诉历史失败");
  }
};

const viewDetail = (item: any) => {
  router.push({ path: "/dynamicManagement/reviewAppealDetail", query: { id: item.id } });
};

const formatTime = (t: string) => {
  if (!t) return "--";
  return String(t).replace(/-/g, "/");
};

const getUserAvatar = (item: any) => {
  return item.userImage ?? item.userAvatar ?? "";
};

const getCommentContent = (item: any) => {
  return item.commentContent ?? item.reviewContent ?? item.content ?? "--";
};

const VIDEO_EXT = [".mp4", ".mov", ".avi", ".wmv", ".flv", ".mkv", ".webm", ".m4v"];
const isVideoUrl = (url: string) => {
  const lower = (url || "").toLowerCase();
  return VIDEO_EXT.some(ext => lower.includes(ext));
};

interface MediaItem {
  url: string;
  type: "image" | "video";
}
const getCommentMedia = (item: any): MediaItem[] => {
  const urls: string[] = [];
  const list = item.commentImgId;
  if (Array.isArray(list)) urls.push(...list.filter(Boolean));
  else if (typeof list === "string" && list.trim())
    urls.push(
      ...list
        .split(",")
        .map((s: string) => s.trim())
        .filter(Boolean)
    );
  const videoList = item.commentVideoList ?? item.videoUrls ?? item.videoList;
  if (Array.isArray(videoList)) urls.push(...videoList.filter(Boolean));
  else if (typeof videoList === "string" && videoList.trim())
    urls.push(
      ...videoList
        .split(",")
        .map((s: string) => s.trim())
        .filter(Boolean)
    );
  return urls.map(url => ({ url, type: isVideoUrl(url) ? "video" : "image" }));
};

const getCommentMediaImages = (item: any): string[] => {
  return getCommentMedia(item)
    .filter(m => m.type === "image")
    .map(m => m.url);
};

const getMediaImageIndex = (media: MediaItem[], currentIndex: number): number => {
  let idx = 0;
  for (let i = 0; i < currentIndex; i++) if (media[i].type === "image") idx++;
  return idx;
};

const videoPreviewVisible = ref(false);
const videoPreviewUrl = ref("");
const openVideoPreview = (url: string) => {
  videoPreviewUrl.value = url;
  videoPreviewVisible.value = true;
};
const closeVideoPreview = () => {
  videoPreviewUrl.value = "";
  videoPreviewVisible.value = false;
};
const onVideoLoadedData = (e: Event) => {
  const video = e.target as HTMLVideoElement;
  if (video) {
    video.currentTime = 0;
    video.pause();
  }
};

// appealStatus: 0=审核中 1=被驳回 2=已通过
const getAppealStatusTagClass = (status: number) => {
  const map: Record<number, string> = {
    0: "tag-pending",
    1: "tag-rejected",
    2: "tag-approved"
  };
  return map[status] ?? "";
};

const getAppealStatusText = (status: number) => {
  const map: Record<number, string> = {
    0: "审核中",
    1: "被驳回",
    2: "已通过"
  };
  return map[status] ?? "";
};

const getAppealStatusDesc = (status: number) => {
  const map: Record<number, string> = {
    0: "等待平台审核",
    1: "被驳回",
    2: "已通过"
  };
  return map[status] ?? "";
};

onMounted(() => loadAppealHistory());
</script>

<style lang="scss" scoped>
.review-appeal-history-container {
  min-height: calc(100vh - 120px);
  padding: 20px;
  background: #f5f7fa;
  .page-header {
    display: flex;
    gap: 16px;
    align-items: center;
    margin-bottom: 20px;
    .page-title {
      flex: 1;
      margin: 0;
      font-size: 18px;
      font-weight: 600;
      color: #303133;
      text-align: center;
    }
  }
  .tabs-section {
    margin-bottom: 16px;
  }
  .appeal-history-list {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-bottom: 24px;
    .appeal-card {
      padding: 16px;
      overflow: hidden;
      background: #ffffff;
      border-radius: 12px;
      box-shadow: 0 2px 12px rgb(0 0 0 / 6%);
      .card-title-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding-bottom: 12px;
        margin-bottom: 16px;
        border-bottom: 1px solid #ebeef5;
        .card-title {
          font-size: 15px;
          font-weight: 600;
          color: #303133;
        }
        .status-tag {
          padding: 4px 10px;
          font-size: 12px;
          color: #ffffff;
          border: none;
          border-radius: 6px;
          &.tag-pending {
            background: #409eff;
          }
          &.tag-approved {
            background: #16aa68;
          }
          &.tag-rejected {
            background: #f4420a;
          }
        }
      }
      .card-user {
        display: flex;
        gap: 12px;
        align-items: center;
        margin-bottom: 12px;
        .user-avatar {
          flex-shrink: 0;
        }
        .user-meta {
          .user-name {
            margin-bottom: 4px;
            font-size: 14px;
            font-weight: 600;
            color: #303133;
          }
          .review-time {
            font-size: 12px;
            color: #909399;
          }
        }
      }
      .card-content {
        margin-bottom: 12px;
        font-size: 14px;
        line-height: 1.6;
        color: #606266;
      }
      .card-media {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        margin-bottom: 16px;
        .media-item {
          flex-shrink: 0;
          width: 80px;
          height: 80px;
          overflow: hidden;
          border-radius: 8px;
        }
        .comment-img {
          object-fit: cover;
        }
        .media-video-wrap {
          position: relative;
          cursor: pointer;
          background: #000000;
          .video-thumb {
            display: block;
            width: 100%;
            height: 100%;
            object-fit: cover;
          }
          .video-mask {
            position: absolute;
            inset: 0;
            display: flex;
            align-items: center;
            justify-content: center;
            background: rgb(0 0 0 / 35%);
            .video-play-icon {
              font-size: 28px;
              color: #ffffff;
            }
          }
        }
      }
      .card-appeal {
        padding: 12px 16px 16px;
        padding-top: 12px;
        margin: 0 -16px -16px;
        background: linear-gradient(to top, rgb(86 125 244 / 3%), transparent);
        border-top: 1px solid #ebeef5;
        .appeal-time-row {
          display: flex;
          align-items: center;
          justify-content: space-between;
          margin-bottom: 10px;
          font-size: 13px;
          .appeal-time-label {
            color: #606266;
          }
          .appeal-time-value {
            color: #909399;
          }
        }
        .appeal-status-row {
          display: flex;
          flex-wrap: wrap;
          gap: 8px;
          align-items: center;
          justify-content: space-between;
          .appeal-status-text {
            display: inline-flex;
            gap: 6px;
            align-items: center;
            font-size: 13px;
            color: #606266;
            .status-icon {
              font-size: 16px;
              &.status-pending {
                color: #fa913d;
              }
              &.status-approved {
                color: #16aa68;
              }
              &.status-rejected {
                color: #f4420a;
              }
            }
          }
          .btn-detail {
            padding: 0;
            font-size: 14px;
          }
        }
      }
    }
  }
  .pagination-section {
    display: flex;
    justify-content: flex-end;
    padding: 16px 0;
  }
}
</style>
