<script setup>
import { h, onMounted, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'

import {
  activateAnnouncement,
  createAnnouncement,
  deactivateAnnouncement,
  deleteAnnouncement,
  fetchAnnouncements,
  uploadAnnouncementImage,
} from '../api/announcements'

const formTitle = ref('')
const formContent = ref('')
const formImageUrl = ref('')
const imageInputRef = ref(null)
const uploading = ref(false)

const loading = ref(false)
const list = ref([])

async function load() {
  loading.value = true
  try {
    list.value = await fetchAnnouncements()
  } catch {
    list.value = []
  } finally {
    loading.value = false
  }
}

function clearForm() {
  formTitle.value = ''
  formContent.value = ''
  formImageUrl.value = ''
  if (imageInputRef.value) imageInputRef.value.value = ''
}

function openImagePicker() {
  imageInputRef.value?.click()
}

function clearImage() {
  formImageUrl.value = ''
  if (imageInputRef.value) imageInputRef.value.value = ''
}

async function onImageFileChange(event) {
  const file = event.target?.files?.[0]
  if (!file) return
  if (file.type && !file.type.startsWith('image/')) {
    ElMessage.error('请选择图片文件')
    event.target.value = ''
    return
  }

  uploading.value = true
  try {
    const res = await uploadAnnouncementImage(file)
    if (!res?.success || !res?.url) {
      ElMessage.error(res?.error || '上传失败')
      return
    }
    formImageUrl.value = res.url
    ElMessage.success('上传成功')
  } catch {
    // handled by interceptor
  } finally {
    uploading.value = false
    event.target.value = ''
  }
}

async function submit(isActive) {
  const title = formTitle.value.trim()
  const content = formContent.value.trim()
  const image_url = formImageUrl.value.trim()
  if (!title || !content) {
    ElMessage.error('标题和内容不能为空')
    return
  }

  try {
    const res = await createAnnouncement({ title, content, image_url, is_active: Boolean(isActive) })
    if (!res?.success) {
      ElMessage.error(res?.error || '保存失败')
      return
    }
    ElMessage.success('保存成功')
    clearForm()
    await load()
  } catch {
    // handled by interceptor
  }
}

async function view(row) {
  const body = h('div', { class: 'announcement-view' }, [
    row.content ? h('div', { class: 'announcement-view-text' }, row.content) : null,
    row.image_url
      ? h('img', {
          class: 'announcement-view-image',
          src: row.image_url,
          alt: '公告图片',
        })
      : null,
  ])
  await ElMessageBox.alert(body, row.title || '公告', {
    confirmButtonText: '关闭',
    dangerouslyUseHTMLString: false,
  })
}

async function onActivate(row) {
  try {
    await ElMessageBox.confirm('确定启用该公告吗？启用后将自动停用其他公告。', '启用公告', {
      confirmButtonText: '启用',
      cancelButtonText: '取消',
      type: 'warning',
    })
  } catch {
    return
  }

  try {
    const res = await activateAnnouncement(row.id)
    if (!res?.success) {
      ElMessage.error(res?.error || '启用失败')
      return
    }
    ElMessage.success('已启用')
    await load()
  } catch {
    // handled by interceptor
  }
}

async function onDeactivate(row) {
  try {
    await ElMessageBox.confirm('确定停用该公告吗？', '停用公告', {
      confirmButtonText: '停用',
      cancelButtonText: '取消',
      type: 'warning',
    })
  } catch {
    return
  }

  try {
    const res = await deactivateAnnouncement(row.id)
    if (!res?.success) {
      ElMessage.error(res?.error || '停用失败')
      return
    }
    ElMessage.success('已停用')
    await load()
  } catch {
    // handled by interceptor
  }
}

async function onDelete(row) {
  try {
    await ElMessageBox.confirm('确定删除该公告吗？删除后无法恢复。', '删除公告', {
      confirmButtonText: '删除',
      cancelButtonText: '取消',
      type: 'error',
    })
  } catch {
    return
  }

  try {
    const res = await deleteAnnouncement(row.id)
    if (!res?.success) {
      ElMessage.error(res?.error || '删除失败')
      return
    }
    ElMessage.success('已删除')
    await load()
  } catch {
    // handled by interceptor
  }
}

onMounted(load)
</script>

<template>
  <div class="page-stack">
    <div class="app-page-title">
      <h2>公告管理</h2>
    </div>

    <el-card shadow="never" :body-style="{ padding: '16px' }" class="card">
      <h3 class="section-title">创建公告</h3>

      <el-form label-width="90px">
        <el-form-item label="公告标题">
          <el-input v-model="formTitle" placeholder="请输入公告标题" maxlength="100" show-word-limit />
        </el-form-item>
        <el-form-item label="公告内容">
          <el-input
            v-model="formContent"
            type="textarea"
            :rows="5"
            placeholder="请输入公告内容（将以弹窗形式展示）"
            maxlength="2000"
            show-word-limit
          />
        </el-form-item>
        <el-form-item label="公告图片">
          <div class="image-upload-row">
            <el-button :icon="Plus" :loading="uploading" @click="openImagePicker">上传图片</el-button>
            <el-button v-if="formImageUrl" @click="clearImage">移除</el-button>
            <span v-if="formImageUrl" class="image-url">{{ formImageUrl }}</span>
            <input
              ref="imageInputRef"
              class="image-input"
              type="file"
              accept="image/*"
              @change="onImageFileChange"
            />
          </div>
        </el-form-item>
      </el-form>

      <div v-if="formImageUrl" class="image-preview">
        <img :src="formImageUrl" alt="公告图片预览" />
      </div>

      <div class="actions">
        <el-button type="primary" @click="submit(true)">发布并启用</el-button>
        <el-button @click="submit(false)">保存但不启用</el-button>
        <el-button @click="clearForm">清空</el-button>
      </div>

      <div class="help">
        说明：启用公告后，用户登录进入系统将弹窗提示；用户可选择“当次关闭”或“永久关闭本次公告”。
      </div>
    </el-card>

    <el-card shadow="never" :body-style="{ padding: '16px' }" class="card">
      <h3 class="section-title">公告列表</h3>

      <div class="table-wrap">
        <el-table :data="list" v-loading="loading" style="width: 100%">
          <el-table-column prop="id" label="ID" width="80" />
          <el-table-column label="标题" min-width="240">
            <template #default="{ row }">
              <span class="ellipsis" :title="row.title">{{ row.title }}</span>
            </template>
          </el-table-column>
          <el-table-column label="状态" width="120">
            <template #default="{ row }">
              <el-tag :type="row.is_active ? 'success' : 'info'" effect="light">
                {{ row.is_active ? '启用' : '停用' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="图片" width="100">
            <template #default="{ row }">
              <el-tag v-if="row.image_url" type="success" effect="light">有图</el-tag>
              <span v-else class="app-muted">-</span>
            </template>
          </el-table-column>
          <el-table-column prop="created_at" label="创建时间" width="180" />
          <el-table-column label="操作" width="260" fixed="right">
            <template #default="{ row }">
              <div class="actions">
                <el-button size="small" @click="view(row)">查看</el-button>
                <el-button v-if="row.is_active" size="small" @click="onDeactivate(row)">停用</el-button>
                <el-button v-else type="success" size="small" @click="onActivate(row)">启用</el-button>
                <el-button type="danger" size="small" @click="onDelete(row)">删除</el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-card>
  </div>
</template>

<style scoped>
.page-stack {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

.card {
  border-radius: var(--app-radius);
  border: 1px solid var(--app-border);
  background: var(--app-card-bg);
  box-shadow: var(--app-shadow-soft);
}

.section-title {
  margin: 0 0 12px;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 0.2px;
}

.help {
  margin-top: 10px;
  font-size: 12px;
  color: var(--app-muted);
}

.image-preview {
  margin: 6px 0 2px;
  display: flex;
  justify-content: flex-start;
}

.image-preview img {
  max-width: 280px;
  max-height: 160px;
  border-radius: 8px;
  border: 1px solid var(--app-border);
  object-fit: contain;
}

.image-upload-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.image-input {
  display: none;
}

.image-url {
  font-size: 12px;
  color: var(--app-muted);
  word-break: break-all;
}

.announcement-view {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.announcement-view-text {
  white-space: pre-wrap;
  line-height: 1.6;
  font-size: 14px;
}

.announcement-view-image {
  max-width: 100%;
  max-height: 320px;
  border-radius: 10px;
  border: 1px solid var(--app-border);
  object-fit: contain;
}

.table-wrap {
  overflow-x: auto;
  border-radius: 10px;
  border: 1px solid var(--app-border);
  background: #fff;
}

.ellipsis {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
</style>
