<template>
  <div class="media-library-page">
    <el-card class="panel-card">
      <div class="header-actions">
        <el-form :inline="true" :model="searchForm" class="search-form">
          <el-form-item label="目标医院" v-if="isSystemAdmin">
            <el-select
              v-model="searchForm.hospitalId"
              placeholder="系统管理员上传/查看前请先选择医院"
              clearable
              filterable
              style="width: 260px"
            >
              <el-option
                v-for="hospital in hospitals"
                :key="hospital.id"
                :label="hospital.name"
                :value="hospital.id"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="关键词">
            <el-input
              v-model="searchForm.keyword"
              placeholder="文件名"
              clearable
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="Search" @click="fetchData">
              查询
            </el-button>
            <el-button icon="Refresh" @click="resetSearch">重置</el-button>
            <AssetUploadButton
              button-text="上传文件"
              :hospital-id="currentUploadHospitalId"
              :disabled="isSystemAdmin && !currentUploadHospitalId"
              accept="image/*,video/*,.pdf,.doc,.docx,.xls,.xlsx"
              @uploaded="handleUploaded"
            />
          </el-form-item>
        </el-form>
      </div>

      <el-alert
        v-if="isSystemAdmin && !currentUploadHospitalId"
        type="warning"
        :closable="false"
        title="系统管理员上传或查看图库前必须先选择医院。"
        style="margin-bottom: 16px"
      />

      <el-tabs v-model="activeTab" @tab-change="handleTabChange">
        <el-tab-pane label="全部" name="ALL" />
        <el-tab-pane label="图库" name="IMAGE" />
        <el-tab-pane label="视频库" name="VIDEO" />
        <el-tab-pane label="文件库" name="FILE" />
      </el-tabs>

      <div v-loading="loading">
        <el-empty
          v-if="!assets.length"
          description="当前筛选条件下暂无上传文件"
        />

        <el-row v-else :gutter="16" class="asset-grid">
          <el-col
            v-for="asset in assets"
            :key="asset.id"
            :xs="24"
            :sm="12"
            :lg="8"
            :xl="6"
          >
            <el-card shadow="hover" class="asset-card">
              <div class="asset-preview">
                <el-image
                  v-if="asset.type === 'IMAGE'"
                  :src="asset.url"
                  fit="contain"
                  preview-teleported
                  :preview-src-list="[asset.url]"
                  class="asset-image"
                />
                <video
                  v-else-if="asset.type === 'VIDEO'"
                  :src="asset.url"
                  controls
                  class="asset-video"
                />
                <div v-else class="asset-file-placeholder">
                  <el-icon><Document /></el-icon>
                  <span>文件</span>
                </div>
              </div>

              <div class="asset-meta">
                <div class="asset-name" :title="asset.originalName">
                  {{ asset.originalName }}
                </div>
                <div class="asset-submeta">
                  {{ formatFileSize(asset.fileSize) }} ·
                  {{ formatDateTime(asset.createdAt) }}
                </div>
                <div class="asset-submeta">
                  {{ asset.creator?.name || '-' }}
                  <span v-if="asset.hospital?.name">
                    · {{ asset.hospital.name }}
                  </span>
                </div>
                <el-link :href="asset.url" target="_blank" type="primary">
                  打开原文件
                </el-link>
              </div>
            </el-card>
          </el-col>
        </el-row>
      </div>

      <div class="pagination-container">
        <el-pagination
          v-model:current-page="page"
          v-model:page-size="pageSize"
          :page-sizes="[12, 24, 48]"
          :total="total"
          background
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="fetchData"
          @current-change="fetchData"
        />
      </div>
    </el-card>
  </div>
</template>

<script setup>
import { computed, onMounted, reactive, ref } from 'vue';
import { Document } from '@element-plus/icons-vue';
import { getHospitals } from '../../api/organization';
import { getUploadAssets } from '../../api/uploads';
import { useUserStore } from '../../store/user';
import AssetUploadButton from '../../components/AssetUploadButton.vue';

const userStore = useUserStore();
const isSystemAdmin = computed(() => userStore.role === 'SYSTEM_ADMIN');

const hospitals = ref([]);
const assets = ref([]);
const loading = ref(false);
const total = ref(0);
const page = ref(1);
const pageSize = ref(12);
const activeTab = ref('ALL');

const searchForm = reactive({
  keyword: '',
  hospitalId: null,
});

const currentUploadHospitalId = computed(() => {
  if (isSystemAdmin.value) {
    return searchForm.hospitalId || null;
  }
  return userStore.userInfo?.hospitalId || null;
});

function buildQueryParams() {
  const params = {
    page: page.value,
    pageSize: pageSize.value,
  };

  if (searchForm.keyword) {
    params.keyword = searchForm.keyword;
  }
  if (activeTab.value !== 'ALL') {
    params.type = activeTab.value;
  }
  if (isSystemAdmin.value && searchForm.hospitalId) {
    params.hospitalId = searchForm.hospitalId;
  }

  return params;
}

async function fetchHospitalsForAdmin() {
  if (!isSystemAdmin.value) {
    return;
  }
  const res = await getHospitals({ page: 1, pageSize: 100 });
  hospitals.value = res.list || [];
  if (!searchForm.hospitalId && hospitals.value.length > 0) {
    searchForm.hospitalId = hospitals.value[0].id;
  }
}

async function fetchData() {
  if (isSystemAdmin.value && !searchForm.hospitalId) {
    assets.value = [];
    total.value = 0;
    return;
  }

  loading.value = true;
  try {
    const res = await getUploadAssets(buildQueryParams());
    assets.value = Array.isArray(res?.list) ? res.list : [];
    total.value = res?.total || 0;
  } finally {
    loading.value = false;
  }
}

async function resetSearch() {
  searchForm.keyword = '';
  page.value = 1;
  activeTab.value = 'ALL';
  await fetchData();
}

async function handleTabChange() {
  page.value = 1;
  await fetchData();
}

async function handleUploaded() {
  page.value = 1;
  await fetchData();
}

function formatDateTime(value) {
  if (!value) {
    return '-';
  }
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) {
    return '-';
  }
  return date.toLocaleString('zh-CN', { hour12: false });
}

function formatFileSize(value) {
  const size = Number(value) || 0;
  if (size < 1024) {
    return `${size} B`;
  }
  if (size < 1024 * 1024) {
    return `${(size / 1024).toFixed(1)} KB`;
  }
  return `${(size / (1024 * 1024)).toFixed(1)} MB`;
}

onMounted(async () => {
  await fetchHospitalsForAdmin();
  await fetchData();
});
</script>

<style scoped>
.media-library-page {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.asset-grid {
  margin-top: 8px;
}

.asset-card {
  margin-bottom: 16px;
}

.asset-preview {
  height: 220px;
  padding: 10px;
  border-radius: 10px;
  overflow: hidden;
  background: #f5f7fa;
  display: flex;
  align-items: center;
  justify-content: center;
}

.asset-image,
.asset-video {
  width: 100%;
  height: 100%;
  border-radius: 8px;
}

.asset-image {
  display: block;
  background: #edf4fb;
}

.asset-image :deep(.el-image__inner) {
  object-fit: contain;
}

.asset-video {
  object-fit: contain;
  background: #0f172a;
}

.asset-file-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  color: #909399;
  font-size: 14px;
}

.asset-meta {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 12px;
}

.asset-name {
  font-weight: 600;
  color: #303133;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.asset-submeta {
  color: #909399;
  font-size: 13px;
}

.pagination-container {
  display: flex;
  justify-content: flex-end;
  margin-top: 16px;
}
</style>
