﻿<template>
  <div class="page-shell">
    <div class="section-title">活动管理</div>
    <div class="section-subtitle">发布节气文化活动、管理报名名额与状态</div>

    <a-card class="search-card">
      <div class="filter-group">
        <a-select v-model="status" placeholder="筛选状态" allow-clear style="width: 160px;">
          <a-option value="draft">草稿</a-option>
          <a-option value="published">已发布</a-option>
          <a-option value="closed">已结束</a-option>
        </a-select>
        <a-input v-model="keyword" placeholder="搜索活动主题" allow-clear />
        <a-button type="primary" @click="fetchList">查询</a-button>
      </div>
      <div class="action-group">
        <a-button type="primary" @click="openCreate">新建活动</a-button>
      </div>
    </a-card>

    <a-table class="table-shell" :columns="columns" :data="rows" row-key="id" :pagination="false">
      <template #status="{ record }">
        <a-tag :color="statusColor(record.status)">{{ statusText(record.status) }}</a-tag>
      </template>
      <template #action="{ record }">
        <a-space>
          <a-button size="mini" type="text" @click="openEdit(record)">编辑</a-button>
          <a-button size="mini" type="text" @click="publish(record.id)" v-if="record.status !== 'published'">发布</a-button>
          <a-button size="mini" type="text" @click="close(record.id)" v-if="record.status === 'published'">结束</a-button>
          <a-button size="mini" type="text" @click="goSignups(record)">报名名单</a-button>
        </a-space>
      </template>
    </a-table>

    <a-modal v-model:visible="visible" :title="modalTitle" @ok="handleSave" :ok-text="isEdit ? '保存' : '创建'" width="1100px">
      <div class="modal-body">
        <div class="calendar-panel">
          <div class="calendar-head">
            <div>
              <div class="calendar-title">节气日历</div>
              <div class="calendar-tip">点击有节气的日期，一键生成活动草稿</div>
            </div>
            <div class="calendar-actions">
              <a-button size="mini" @click="prevMonth">上个月</a-button>
              <a-button size="mini" @click="goToday">本月</a-button>
              <a-button size="mini" @click="nextMonth">下个月</a-button>
            </div>
          </div>
          <div class="calendar-month">{{ monthLabel }}</div>
          <div class="calendar-grid">
            <div class="calendar-week" v-for="(week, wIndex) in calendarDays" :key="wIndex">
              <div class="calendar-cell" v-for="day in week" :key="day.key" :class="dayClass(day)" @click="selectDay(day)">
                <span class="cell-day">{{ day.date }}</span>
                <span v-if="day.term" class="term-chip">{{ day.term }}</span>
              </div>
            </div>
          </div>
        </div>
        <div class="form-panel">
          <a-form :model="form" layout="vertical" class="form-shell">
            <div class="form-title">活动信息</div>
            <a-form-item label="活动标题" required>
              <a-input v-model="form.title" placeholder="请输入活动标题" />
            </a-form-item>
            <a-form-item label="节气" required>
              <a-select v-model="form.term" placeholder="请选择节气">
                <a-option v-for="item in terms" :key="item" :value="item">{{ item }}</a-option>
              </a-select>
            </a-form-item>
            <a-form-item label="活动简介">
              <a-input v-model="form.summary" placeholder="一句话描述活动" />
            </a-form-item>
            <a-form-item label="活动详情">
              <a-textarea v-model="form.content" placeholder="详细介绍活动内容" :auto-size="{ minRows: 3 }" />
            </a-form-item>
            <a-form-item label="地点" required>
              <a-input v-model="form.location" placeholder="活动地点" />
            </a-form-item>
            <a-form-item label="活动时间" required>
              <a-range-picker v-model="form.activityTime" show-time format="YYYY-MM-DD HH:mm" value-format="YYYY-MM-DDTHH:mm:ss" />
            </a-form-item>
            <a-form-item label="报名时间" required>
              <a-range-picker v-model="form.signupTime" show-time format="YYYY-MM-DD HH:mm" value-format="YYYY-MM-DDTHH:mm:ss" />
            </a-form-item>
            <a-form-item label="报名名额" required>
              <a-input-number v-model="form.quota" :min="1" />
            </a-form-item>
            <a-form-item label="封面图链接">
              <a-input v-model="form.coverUrl" placeholder="选填" />
            </a-form-item>
            <a-form-item label="状态">
              <a-select v-model="form.status" placeholder="默认草稿">
                <a-option value="draft">草稿</a-option>
                <a-option value="published">已发布</a-option>
                <a-option value="closed">已结束</a-option>
              </a-select>
            </a-form-item>
          </a-form>
        </div>
      </div>
    </a-modal>
  </div>
</template>

<script setup>
import { onMounted, reactive, ref, computed } from 'vue';
import { useRouter } from 'vue-router';
import { Message } from '@arco-design/web-vue';
import { listActivitiesAdmin, getActivityAdmin, createActivity, updateActivity, publishActivity, closeActivity } from '../api/activities';
import { Solar } from 'lunar-javascript';

const router = useRouter();
const rows = ref([]);
const status = ref('');
const keyword = ref('');
const visible = ref(false);
const isEdit = ref(false);
const currentId = ref(null);
const calendarBase = ref(new Date());

const form = reactive({
  title: '',
  term: '',
  summary: '',
  content: '',
  location: '',
  activityTime: [],
  signupTime: [],
  quota: 20,
  coverUrl: '',
  status: 'draft'
});

const terms = [
  '立春', '雨水', '惊蛰', '春分', '清明', '谷雨',
  '立夏', '小满', '芒种', '夏至', '小暑', '大暑',
  '立秋', '处暑', '白露', '秋分', '寒露', '霜降',
  '立冬', '小雪', '大雪', '冬至', '小寒', '大寒'
];

const columns = [
  { title: '活动标题', dataIndex: 'title' },
  { title: '节气', dataIndex: 'term' },
  { title: '地点', dataIndex: 'location' },
  { title: '开始时间', dataIndex: 'startTime' },
  { title: '名额', dataIndex: 'quota' },
  { title: '已报名', dataIndex: 'signupCount' },
  { title: '状态', slotName: 'status' },
  { title: '操作', slotName: 'action' }
];

const modalTitle = computed(() => (isEdit.value ? '编辑活动' : '新建活动'));

const fetchList = async () => {
  const res = await listActivitiesAdmin({ status: status.value, keyword: keyword.value });
  rows.value = res.data || [];
};

const resetForm = () => {
  form.title = '';
  form.term = '';
  form.summary = '';
  form.content = '';
  form.location = '';
  form.activityTime = [];
  form.signupTime = [];
  form.quota = 20;
  form.coverUrl = '';
  form.status = 'draft';
};

const termCache = new Map();

const termForDate = (date) => {
  try {
    if (!date) return '';
    const key = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
    if (termCache.has(key)) {
      return termCache.get(key);
    }
    const solar = Solar.fromDate(date);
    const term = solar.getLunar().getJieQi() || '';
    termCache.set(key, term);
    return term;
  } catch (err) {
    return '';
  }
};

const buildCalendar = (baseDate) => {
  const year = baseDate.getFullYear();
  const month = baseDate.getMonth();
  const first = new Date(year, month, 1);
  const startOffset = first.getDay();
  const startDate = new Date(year, month, 1 - startOffset);
  const weeks = [];
  for (let w = 0; w < 6; w += 1) {
    const row = [];
    for (let d = 0; d < 7; d += 1) {
      const current = new Date(startDate);
      current.setDate(startDate.getDate() + w * 7 + d);
      const term = termForDate(current);
      row.push({
        key: `${current.getFullYear()}-${current.getMonth() + 1}-${current.getDate()}`,
        date: current.getDate(),
        fullDate: current,
        term,
        isCurrentMonth: current.getMonth() === month
      });
    }
    weeks.push(row);
  }
  return weeks;
};

const calendarDays = computed(() => buildCalendar(calendarBase.value));

const monthLabel = computed(() => {
  const year = calendarBase.value.getFullYear();
  const month = calendarBase.value.getMonth() + 1;
  return `${year}年${month}月`;
});

const prevMonth = () => {
  const date = new Date(calendarBase.value);
  date.setMonth(date.getMonth() - 1);
  calendarBase.value = date;
};

const nextMonth = () => {
  const date = new Date(calendarBase.value);
  date.setMonth(date.getMonth() + 1);
  calendarBase.value = date;
};

const goToday = () => {
  calendarBase.value = new Date();
};

const dayClass = (day) => ({
  'is-other': !day.isCurrentMonth,
  'is-term': Boolean(day.term)
});

const formatDateTime = (date, time = '09:00:00') => {
  const pad = (val) => String(val).padStart(2, '0');
  const year = date.getFullYear();
  const month = pad(date.getMonth() + 1);
  const day = pad(date.getDate());
  return `${year}-${month}-${day}T${time}`;
};

const addDays = (date, days) => {
  const next = new Date(date);
  next.setDate(next.getDate() + days);
  return next;
};

const selectDay = (day) => {
  if (!day.term) {
    Message.warning('这一天不是节气日，可手动填写活动信息');
    return;
  }
  const date = day.fullDate;
  form.term = day.term;
  form.title = `${day.term}节气文化活动`;
  form.summary = `围绕${day.term}开展的社区传统文化活动。`;
  form.content = `本次活动以${day.term}为主题，包含节气科普、互动体验与邻里交流等内容。`;
  form.activityTime = [formatDateTime(date, '09:00:00'), formatDateTime(date, '11:00:00')];
  form.signupTime = [
    formatDateTime(addDays(date, -7), '00:00:00'),
    formatDateTime(addDays(date, -1), '23:59:59')
  ];
  form.status = 'draft';
  Message.success(`已根据${day.term}生成活动草稿`);
};

const openCreate = () => {
  resetForm();
  isEdit.value = false;
  currentId.value = null;
  calendarBase.value = new Date();
  visible.value = true;
};

const openEdit = async (record) => {
  isEdit.value = true;
  currentId.value = record.id;
  const res = await getActivityAdmin(record.id);
  const data = res.data || record;
  form.title = data.title;
  form.term = data.term;
  form.summary = data.summary || '';
  form.content = data.content || '';
  form.location = data.location;
  form.activityTime = [data.startTime, data.endTime];
  form.signupTime = [data.signupStart, data.signupEnd];
  form.quota = data.quota;
  form.coverUrl = data.coverUrl || '';
  form.status = data.status;
  calendarBase.value = new Date(data.startTime);
  visible.value = true;
};

const handleSave = async () => {
  if (!form.title || !form.term || !form.location || form.activityTime.length !== 2 || form.signupTime.length !== 2) {
    Message.warning('请填写完整的活动信息');
    return;
  }
  const payload = {
    title: form.title,
    term: form.term,
    summary: form.summary,
    content: form.content,
    location: form.location,
    startTime: form.activityTime[0],
    endTime: form.activityTime[1],
    signupStart: form.signupTime[0],
    signupEnd: form.signupTime[1],
    quota: form.quota,
    status: form.status,
    coverUrl: form.coverUrl
  };
  if (isEdit.value) {
    await updateActivity(currentId.value, payload);
    Message.success('活动已更新');
  } else {
    await createActivity(payload);
    Message.success('活动已创建');
  }
  visible.value = false;
  await fetchList();
};

const publish = async (id) => {
  await publishActivity(id);
  Message.success('活动已发布');
  await fetchList();
};

const close = async (id) => {
  await closeActivity(id);
  Message.success('活动已结束');
  await fetchList();
};

const goSignups = (record) => {
  router.push(`/admin/activities/${record.id}/signups`);
};

const statusText = (value) => {
  if (value === 'published') return '已发布';
  if (value === 'closed') return '已结束';
  return '草稿';
};

const statusColor = (value) => {
  if (value === 'published') return 'green';
  if (value === 'closed') return 'gray';
  return 'orange';
};

onMounted(fetchList);
</script>

<style scoped>
.search-card {
  margin-bottom: 18px;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid var(--brand-line);
  box-shadow: var(--shadow-card);
  padding: 18px;
  gap: 16px;
  flex-wrap: nowrap;
}

.filter-group {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: nowrap;
  flex: 1;
}

.action-group {
  display: flex;
  gap: 12px;
  margin-left: 8px;
  white-space: nowrap;
}

.filter-group :deep(.arco-input-wrapper) {
  width: 260px;
}

.table-shell :deep(.arco-table) {
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: rgba(255, 255, 255, 0.94);
  box-shadow: var(--shadow-card);
}

.modal-body {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 18px;
}

.calendar-panel {
  background: linear-gradient(180deg, rgba(250, 245, 255, 0.95), rgba(255, 247, 237, 0.9));
  border-radius: var(--radius-lg);
  padding: 16px;
  border: 1px solid rgba(124, 58, 237, 0.18);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.6);
}

.calendar-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.calendar-actions {
  display: flex;
  gap: 8px;
}

.calendar-title {
  font-size: 18px;
  font-weight: 700;
}

.calendar-tip {
  font-size: 12px;
  color: rgba(42, 15, 69, 0.7);
  margin-top: 4px;
}

.calendar-month {
  font-size: 18px;
  font-weight: 700;
  margin: 10px 0 12px;
  color: var(--brand-ink-soft);
}

.calendar-grid {
  display: grid;
  gap: 8px;
}

.calendar-week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 8px;
}

.calendar-cell {
  background: rgba(255, 255, 255, 0.96);
  border-radius: 12px;
  padding: 8px;
  min-height: 88px;
  cursor: pointer;
  border: 1px solid rgba(124, 58, 237, 0.12);
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.calendar-cell:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 20px rgba(44, 16, 91, 0.14);
}

.calendar-cell.is-other {
  opacity: 0.45;
}

.calendar-cell.is-term {
  border-color: rgba(249, 115, 22, 0.5);
  background: rgba(255, 247, 237, 0.92);
}

.cell-day {
  font-weight: 700;
  font-size: 14px;
}

.term-chip {
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 10px;
  background: rgba(249, 115, 22, 0.18);
  color: #c2410c;
  width: fit-content;
}

.form-panel {
  padding: 8px 12px;
  background: rgba(255, 255, 255, 0.94);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  border: 1px solid rgba(124, 58, 237, 0.12);
}

.form-shell {
  padding: 4px 6px;
}

.form-title {
  font-size: 16px;
  font-weight: 700;
  margin-bottom: 8px;
}

@media (max-width: 960px) {
  .modal-body {
    grid-template-columns: 1fr;
  }

  .search-card {
    flex-direction: column;
    align-items: stretch;
  }

  .filter-group {
    flex-wrap: wrap;
  }
}
</style>
