<template>
  <div class="article-admin-page">
    <div class="page-title-wrap">
      <h1>企业动态</h1>
    </div>

    <div class="stats-grid">
      <div
        v-for="item in statsCards"
        :key="item.type"
        class="stats-card"
      >
        <div class="stats-icon" :class="item.iconClass">
          <i :class="item.icon"></i>
        </div>
        <div>
          <div class="stats-label">{{ item.label }}</div>
          <div class="stats-value">{{ item.count }} 篇</div>
          <div class="stats-read">阅读 {{ item.views }}</div>
        </div>
      </div>
    </div>

    <div class="filter-card">
      <el-form :model="queryForm" inline class="filter-form">
        <el-form-item label="文章类型">
          <el-select v-model="queryForm.type" size="small" clearable placeholder="全部类型" @change="handleSearch">
            <el-option label="企业动态" value="企业动态" />
            <el-option label="产品动态" value="产品动态" />
            <el-option label="行业洞察" value="行业洞察" />
            <el-option label="活动资讯" value="活动资讯" />
          </el-select>
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="queryForm.status" size="small" clearable placeholder="全部状态" @change="handleSearch">
            <el-option label="已发布" value="published" />
            <el-option label="草稿" value="draft" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-input
            v-model.trim="queryForm.keyword"
            size="small"
            clearable
            placeholder="搜索文章标题..."
            @keyup.enter.native="handleSearch"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" size="small" icon="el-icon-search" @click="handleSearch">搜索</el-button>
          <el-button type="primary" size="small" icon="el-icon-plus" @click="openArticleEditor">新建文章</el-button>
        </el-form-item>
      </el-form>
    </div>

    <div class="table-card">
      <el-table
        :data="pagedArticles"
        v-loading="loading"
        class="article-table"
        style="width: 100%"
        empty-text="暂无文章，点击“新建文章”开始创作"
      >
        <el-table-column label="序号" width="80">
          <template slot-scope="scope">
            {{ getRowNo(scope.$index) }}
          </template>
        </el-table-column>
        <el-table-column
          prop="title"
          label="标题"
          min-width="240"
          align="left"
          header-align="left"
          class-name="title-column"
          label-class-name="title-column-header"
          show-overflow-tooltip
        >
          <template slot-scope="scope">
            <span class="article-title">{{ scope.row.title }}</span>
          </template>
        </el-table-column>
        <el-table-column label="类型" width="120">
          <template slot-scope="scope">
            <span class="type-tag" :class="getTypeClass(scope.row.type)">{{ scope.row.type }}</span>
          </template>
        </el-table-column>
        <el-table-column label="状态" width="110">
          <template slot-scope="scope">
            <span class="status-tag" :class="scope.row.status === 'published' ? 'is-published' : 'is-draft'">
              <i></i>{{ scope.row.status === 'published' ? '已发布' : '草稿' }}
            </span>
          </template>
        </el-table-column>
        <el-table-column prop="updateTime" label="创建时间" width="170" />
        <el-table-column prop="publishTime" label="发布时间" width="140" />
        <el-table-column label="阅读数据" width="130">
          <template slot-scope="scope">
            <span v-if="scope.row.status === 'published'" class="views-text">
              <i class="el-icon-view"></i>{{ scope.row.views }}
            </span>
            <span v-else class="empty-read">-</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="180" fixed="right">
          <template slot-scope="scope">
            <el-button
              type="text"
              size="mini"
              :disabled="scope.row.status === 'published'"
              @click="editArticle(scope.row)"
            >
              编辑
            </el-button>
            <el-button
              v-if="scope.row.status === 'published'"
              type="text"
              size="mini"
              class="warning-text"
              @click="unpublishArticle(scope.row)"
            >
              下架
            </el-button>
            <el-button
              v-else
              type="text"
              size="mini"
              class="success-text"
              @click="publishArticle(scope.row)"
            >
              发布
            </el-button>
            <el-button
              type="text"
              size="mini"
              class="danger-text"
              :disabled="scope.row.status === 'published'"
              @click="deleteArticle(scope.row)"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="table-pagination">
        <span class="pagination-info">显示 {{ pageStart }}-{{ pageEnd }} 条，共 {{ total }} 条</span>
        <el-pagination
          background
          layout="prev, pager, next, jumper"
          :current-page.sync="page"
          :page-size="pageSize"
          :total="total"
          @current-change="handlePageChange"
        />
      </div>
    </div>

    <article-editor-dialog
      :visible.sync="editorVisible"
      :article="currentArticle"
      @save="handleSaveArticle"
    />
  </div>
</template>

<script>
import ArticleEditorDialog from './ArticleEditorDialog.vue'
import {
  reqAddNews,
  reqDeleteNews,
  reqEditNews,
  reqNewsListAdmin,
  reqPublishNews,
  reqUnpublishNews
} from '@/api/newsapi/newsapi'
export default {
  name: 'NewsLog',
  components: { ArticleEditorDialog },
  data() {
    return {
      page: 1,
      pageSize: 10,
      total: 0,
      loading: false,
      editorVisible: false,
      currentArticle: null,
      queryForm: {
        type: '',
        status: '',
        keyword: ''
      },
      articleList: []
    }
  },
  computed: {
    filteredArticles() {
      return this.articleList
    },
    pagedArticles() {
      return this.articleList
    },
    pageStart() {
      if (!this.total) return 0
      return (this.page - 1) * this.pageSize + 1
    },
    pageEnd() {
      if (!this.total) return 0
      return Math.min(this.page * this.pageSize, this.total)
    },
    statsCards() {
      const map = {
        企业动态: { label: '企业动态', type: '企业动态', icon: 'el-icon-document', iconClass: 'blue' },
        产品动态: { label: '产品动态', type: '产品动态', icon: 'el-icon-box', iconClass: 'green' },
        行业洞察: { label: '行业洞察', type: '行业洞察', icon: 'el-icon-data-analysis', iconClass: 'amber' },
        活动资讯: { label: '活动资讯', type: '活动资讯', icon: 'el-icon-date', iconClass: 'purple' }
      }
      return Object.values(map).map(item => {
        const list = this.articleList.filter(article => article.type === item.type)
        return {
          ...item,
          count: list.length,
          views: list.reduce((total, article) => total + Number(article.views || 0), 0)
        }
      })
    }
  },
  created() {
    // 页面创建后立即拉取第一页文章列表。
    this.getArticleList()
  },
  methods: {
    getRowNo(index) {
      // 根据当前分页计算表格序号。
      return (this.page - 1) * this.pageSize + index + 1
    },
    getTypeClass(type) {
      // 按文章类型返回对应的标签样式类。
      const classMap = {
        企业动态: 'type-blue',
        产品动态: 'type-green',
        行业洞察: 'type-amber',
        活动资讯: 'type-violet'
      }
      return classMap[type] || 'type-blue'
    },
    handleSearch() {
      // 筛选条件变化后从第一页重新查询。
      this.page = 1
      this.getArticleList()
    },
    handlePageChange(page) {
      // 用户切换分页后更新页码并重新拉取数据。
      this.page = page
      this.getArticleList()
    },
    openArticleEditor() {
      // 清空当前文章，打开新建弹窗。
      this.currentArticle = null
      this.editorVisible = true
    },
    editArticle(row) {
      // 编辑回显直接读取当前表格行数据，不再请求详情接口。
      this.currentArticle = { ...row }
      this.editorVisible = true
    },
    getApiStatus(status) {
      // 页面状态转成接口需要的状态值：1 上架，0 草稿/下架。
      return String(status) === '1' || status === 'published' ? '1' : '0'
    },
    getViewStatus(status) {
      // 接口状态转成页面使用的状态枚举。
      return String(status) === '1' || status === 'published' ? 'published' : 'draft'
    },
    isSuccess(res) {
      // 兼容不同接口的成功标识。
      return res && (res.status === true || res.status === 'true' || res.code === 200)
    },
    buildQueryParams() {
      // 组装后台列表查询参数。
      return {
        url_link: window.location.href,
        current_page: String(this.page),
        page_size: String(this.pageSize),
        title: this.queryForm.keyword.trim(),
        article_type: this.queryForm.type,
        status: this.queryForm.status ? this.getApiStatus(this.queryForm.status) : ''
      }
    },
    normalizeArticle(row) {
      // 将接口字段统一转换成页面表格和编辑弹窗使用的字段。
      return {
        id: row.id,
        title: row.title || '',
        summary: row.summary || '',
        type: row.article_type || row.type || '企业动态',
        status: this.getViewStatus(row.status),
        publishTime: row.publish_time || row.publishTime || '',
        updateTime: row.update_time || row.updateTime || '',
        views: row.read_count || row.views || 0,
        content: row.content || '',
        coverUrl: row.cover_img || row.coverUrl || '',
        coverName: row.cover_name || row.coverName || ''
      }
    },
    getResponseList(res) {
      // 兼容接口可能返回的多种列表结构。
      if (Array.isArray(res.data)) return res.data
      if (res.data && Array.isArray(res.data.data)) return res.data.data
      if (res.data && Array.isArray(res.data.list)) return res.data.list
      if (Array.isArray(res.list)) return res.list
      return []
    },
    getResponseTotal(res, list) {
      // 兼容接口可能返回的多种总数字段。
      const data = res.data && !Array.isArray(res.data) ? res.data : {}
      const pagination = res.pagination || data.pagination || data.page || {}
      return Number(
        res.total ||
        res.total_count ||
        data.total ||
        data.total_count ||
        pagination.total ||
        list.length
      )
    },
    buildArticlePayload(article) {
      // 将编辑弹窗字段转换成新增/编辑接口需要的字段。
      return {
        ...(article.id ? { id: article.id } : {}),
        url_link: window.location.href,
        title: article.title,
        article_type: article.type,
        summary: article.summary,
        update_time: article.update_time || article.updateTime,
        publish_time: article.publish_time || article.publishTime,
        cover_img: article.coverUrl,
        content: article.content,
        status: this.getApiStatus(article.status)
      }
    },
    async confirmAction(title, message, type = 'warning', confirmButtonText = '确定') {
      // 操作前弹出二次确认，用户取消时直接终止后续请求。
      const isDanger = type === 'error'
      const isSuccess = type === 'success'
      try {
        await this.$confirm(message, title, {
          confirmButtonText,
          cancelButtonText: '取消',
          type,
          customClass: `news-confirm-box ${isDanger ? 'news-confirm-box--danger' : isSuccess ? 'news-confirm-box--success' : 'news-confirm-box--warning'}`,
          confirmButtonClass: `news-confirm-btn news-confirm-btn--confirm ${isDanger ? 'is-danger' : isSuccess ? 'is-success' : ''}`,
          cancelButtonClass: 'news-confirm-btn news-confirm-btn--cancel'
        })
        return true
      } catch (error) {
        return false
      }
    },
    async getArticleList() {
      // 开启表格 loading，防止用户误以为页面没有响应。
      this.loading = true
      try {
        // 按当前筛选条件和分页请求后台文章列表。
        const res = await reqNewsListAdmin(this.buildQueryParams())
        if (this.isSuccess(res)) {
          // 请求成功后解析列表数据。
          const list = this.getResponseList(res)
          // 将接口数据映射成页面展示字段。
          this.articleList = list.map(item => this.normalizeArticle(item))
          // 读取接口总数，用于分页器和底部统计。
          this.total = this.getResponseTotal(res, list)
          return
        }
        // 接口返回失败时清空列表，避免展示旧数据。
        this.articleList = []
        this.total = 0
      } catch (error) {
        // 请求异常时清空列表并提示用户。
        this.articleList = []
        this.total = 0
        this.$message.error('文章列表加载失败')
      } finally {
        // 无论成功失败都关闭 loading。
        this.loading = false
      }
    },
    async handleSaveArticle(article) {
      // 根据是否存在 id 判断是编辑还是新增。
      const request = article.id ? reqEditNews : reqAddNews
      try {
        // 调用新增或编辑接口保存文章。
        const res = await request(this.buildArticlePayload(article))
        if (!this.isSuccess(res)) {
          // 接口明确返回失败时展示后端错误信息。
          this.$message.error((res && (res.message || res.msg)) || '保存失败')
          return
        }
        // 保存成功后提示，并刷新列表展示最新数据。
        this.$message.success(this.getApiStatus(article.status) === '1' ? '发布成功' : '草稿已保存')
        this.getArticleList()
      } catch (error) {
        // 网络或程序异常时提示保存失败。
        this.$message.error('保存失败')
      }
    },
    async publishArticle(row) {
      // 上架前先二次确认，避免误操作。
      const confirmed = await this.confirmAction('确认发布企业动态文章？', '请确认该文章不包含敏感词汇。', 'success', '确定发布')
      if (!confirmed) return
      try {
        // 调用上架接口。
        const res = await reqPublishNews({ id: row.id })
        if (!this.isSuccess(res)) {
          // 接口返回失败时展示错误并停止刷新。
          this.$message.error((res && (res.message || res.msg)) || '发布失败')
          return
        }
        // 上架成功后刷新列表。
        this.$message.success('发布成功')
        this.getArticleList()
      } catch (error) {
        // 请求异常时提示用户。
        this.$message.error('发布失败')
      }
    },
    async unpublishArticle(row) {
      // 下架前先二次确认，避免误操作。
      const confirmed = await this.confirmAction('确定要下架这篇文章吗？', '下架后将在企业动态页面隐藏。')
      if (!confirmed) return
      try {
        // 调用下架接口。
        const res = await reqUnpublishNews({ id: row.id })
        if (!this.isSuccess(res)) {
          // 接口返回失败时展示错误并停止刷新。
          this.$message.error((res && (res.message || res.msg)) || '下架失败')
          return
        }
        // 下架成功后刷新列表。
        this.$message.success('下架成功')
        this.getArticleList()
      } catch (error) {
        // 请求异常时提示用户。
        this.$message.error('下架失败')
      }
    },
    async deleteArticle(row) {
      // 删除前先二次确认，避免误删文章。
      const confirmed = await this.confirmAction('确认删除', `删除后不可恢复，确定要删除「${row.title}」吗？`, 'error')
      if (!confirmed) return
      try {
        // 调用删除接口。
        const res = await reqDeleteNews({ id: row.id })
        if (!this.isSuccess(res)) {
          // 接口返回失败时展示错误并停止刷新。
          this.$message.error((res && (res.message || res.msg)) || '删除失败')
          return
        }
        // 删除当前页最后一条时，自动回到上一页。
        if (this.articleList.length === 1 && this.page > 1) this.page -= 1
        // 删除成功后刷新列表。
        this.$message.success('删除成功')
        this.getArticleList()
      } catch (error) {
        // 请求异常时提示用户。
        this.$message.error('删除失败')
      }
    }
  }
}
</script>

<style scoped>
.article-admin-page {
  min-height: calc(100vh - 84px);
  padding: 24px;
  background: #f3f7ff;
}

.page-title-wrap {
  margin-bottom: 24px;
}

.page-title-wrap h1 {
  margin: 0;
  color: #1f2937;
  font-size: 28px;
  font-weight: 700;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}

.stats-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  background: #fff;
  border: 1px solid #edf0f5;
  border-radius: 14px;
}

.stats-icon {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  font-size: 20px;
}

.stats-icon.blue {
  color: #3b82f6;
  background: #eff6ff;
}

.stats-icon.green {
  color: #10b981;
  background: #ecfdf5;
}

.stats-icon.amber {
  color: #f59e0b;
  background: #fffbeb;
}

.stats-icon.purple {
  color: #8b5cf6;
  background: #f5f3ff;
}

.stats-label,
.stats-read {
  color: #9ca3af;
  font-size: 12px;
}

.stats-value {
  margin: 3px 0;
  color: #1f2937;
  font-size: 18px;
  font-weight: 700;
}

.filter-card,
.table-card {
  background: #fff;
  border: 1px solid #edf0f5;
  border-radius: 14px;
}

.filter-card {
  padding: 16px;
  margin-bottom: 24px;
}

.filter-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.filter-form ::v-deep .el-form-item {
  margin-right: 14px;
  margin-bottom: 0;
}

.filter-form ::v-deep .el-input,
.filter-form ::v-deep .el-select {
  width: 170px;
}

.filter-form ::v-deep .el-input__inner {
  border-radius: 8px;
}

.filter-form ::v-deep .el-button--small {
  height: 32px;
  border-radius: 8px;
}

.table-card {
  overflow: hidden;
}

.article-table ::v-deep th {
  background: #f8fafc;
  color: #6b7280;
  font-size: 14px;
  font-weight: 600;
}

.article-table ::v-deep .title-column .cell,
.article-table ::v-deep .title-column-header .cell {
  justify-content: flex-start;
  /* text-align: left !important; */
}

.article-title {
  display: block;
  width: 100%;
  color: #1f2937;
  font-weight: 600;
  text-align: left;
}

.type-tag {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 12px;
}

.type-blue {
  color: #2563eb;
  background: #eff6ff;
}

.type-green {
  color: #059669;
  background: #ecfdf5;
}

.type-amber {
  color: #d97706;
  background: #fffbeb;
}

.type-violet {
  color: #db2777;
  background: #fdf2f8;
}

.status-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
}

.status-tag i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
}

.status-tag.is-published {
  color: #16a34a;
}

.status-tag.is-published i {
  background: #22c55e;
}

.status-tag.is-draft {
  color: #9ca3af;
}

.status-tag.is-draft i {
  background: #d1d5db;
}

.views-text {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: #6b7280;
  font-size: 12px;
}

.empty-read {
  color: #d1d5db;
  font-size: 12px;
}

.success-text {
  color: #16a34a;
}

.warning-text {
  color: #f59e0b;
}

.danger-text {
  color: #f87171;
}

.table-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  border-top: 1px solid #edf0f5;
}

.pagination-info {
  color: #6b7280;
  font-size: 14px;
}

@media (max-width: 1200px) {
  .stats-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 768px) {
  .article-admin-page {
    padding: 12px;
  }

  .stats-grid {
    grid-template-columns: 1fr;
  }

  .table-pagination {
    flex-direction: column;
    gap: 10px;
    align-items: flex-start;
  }
}
</style>