<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { scheduleApi, targetApi } from '@/api/service-monitor'
import { useUserStore } from '@/stores/user'
import type { Schedule, Target, CreateScheduleRequest } from '@/types/service-monitor'

const router = useRouter()
const userStore = useUserStore()

const schedules = ref<Schedule[]>([])
const targets = ref<Target[]>([])
const loading = ref(false)

const isAdmin = computed(() => userStore.isAdmin)

// Dialog
const dialogVisible = ref(false)
const dialogTitle = ref('新增定时任务')
const editingId = ref<string | null>(null)
const saving = ref(false)

// Form
const form = ref<{
  name: string
  target_id: string
  suite: 'quick' | 'full'
  repeat_mode: 'daily' | 'weekday' | 'weekly'
  hour: number
  minute: number
  weekdays: number[]
  start_date: string
  end_date: string
}>({
  name: '',
  target_id: '',
  suite: 'quick',
  repeat_mode: 'daily',
  hour: 8,
  minute: 0,
  weekdays: [],
  start_date: '',
  end_date: '',
})

// Auto refresh
let refreshTimer: ReturnType<typeof setInterval> | null = null

// Status map
const STATUS_MAP: Record<string, { badge: string; label: string }> = {
  running: { badge: 'running', label: '🔄 执行中' },
  success: { badge: 'success', label: '✅ 成功' },
  failed: { badge: 'failed', label: '❌ 失败' },
  error: { badge: 'error', label: '⚠️ 异常' },
  idle: { badge: 'idle', label: '⏸ 待执行' },
}

// Load data
async function loadData() {
  loading.value = true
  try {
    const [schedRes, tgtRes] = await Promise.all([
      scheduleApi.getSchedules(),
      targetApi.getTargets(),
    ])
    schedules.value = schedRes.schedules || []
    targets.value = tgtRes.targets || []
  } catch {
    ElMessage.error('加载数据失败')
  } finally {
    loading.value = false
  }
  checkAutoRefresh()
}

function checkAutoRefresh() {
  const hasRunning = schedules.value.some(s => s.current_status === 'running')
  if (hasRunning) startAutoRefresh()
  else stopAutoRefresh()
}

function startAutoRefresh() {
  if (refreshTimer) return
  refreshTimer = setInterval(refreshSchedules, 3000)
}

function stopAutoRefresh() {
  if (refreshTimer) {
    clearInterval(refreshTimer)
    refreshTimer = null
  }
}

async function refreshSchedules() {
  try {
    const res = await scheduleApi.getSchedules()
    if (res.success) {
      schedules.value = res.schedules || []
      checkAutoRefresh()
    }
  } catch {
    // silent
  }
}

// Format
function formatTime(timeStr: string | null | undefined) {
  if (!timeStr) return '-'
  return timeStr.slice(0, 16).replace('T', ' ')
}

function suiteLabel(suite: string) {
  return suite === 'quick' ? '快速' : '全量'
}

function statusInfo(status: string | null | undefined) {
  const key = status || 'idle'
  return STATUS_MAP[key] || STATUS_MAP.idle
}

function statusBadgeClass(status: string | null | undefined) {
  const badge = statusInfo(status).badge
  return `badge-${badge}`
}

function descriptionText(s: Schedule) {
  const mode = s.repeat_mode
  const time = `${String(s.hour).padStart(2, '0')}:${String(s.minute).padStart(2, '0')}`
  if (mode === 'daily') return `每天 ${time}`
  if (mode === 'weekday') return `工作日 ${time}`
  if (mode === 'weekly') {
    const dayNames = ['', '一', '二', '三', '四', '五', '六', '日']
    const days = (s.weekdays || []).map(d => `周${dayNames[d] || d}`).join('、')
    return `每周 ${days} ${time}`
  }
  return s.cron
}

// CRUD
function openCreate() {
  editingId.value = null
  dialogTitle.value = '新增定时任务'
  form.value = {
    name: '',
    target_id: targets.value.length > 0 ? targets.value[0].id : '',
    suite: 'quick',
    repeat_mode: 'daily',
    hour: 8,
    minute: 0,
    weekdays: [],
    start_date: '',
    end_date: '',
  }
  dialogVisible.value = true
}

function openEdit(s: Schedule) {
  editingId.value = s.id
  dialogTitle.value = '编辑定时任务'
  form.value = {
    name: s.name,
    target_id: s.target_id,
    suite: s.suite,
    repeat_mode: s.repeat_mode || 'daily',
    hour: s.hour ?? 8,
    minute: s.minute ?? 0,
    weekdays: s.weekdays ? [...s.weekdays] : [],
    start_date: s.start_date || '',
    end_date: s.end_date || '',
  }
  dialogVisible.value = true
}

async function handleSave() {
  if (!form.value.name) {
    ElMessage.warning('请输入任务名称')
    return
  }
  if (!form.value.target_id) {
    ElMessage.warning('请选择监测目标')
    return
  }
  if (form.value.repeat_mode === 'weekly' && form.value.weekdays.length === 0) {
    ElMessage.warning('请选择至少一个星期')
    return
  }
  if (form.value.end_date && form.value.start_date && form.value.end_date < form.value.start_date) {
    ElMessage.warning('失效日期必须晚于生效日期')
    return
  }

  saving.value = true
  try {
    const data: CreateScheduleRequest = {
      name: form.value.name,
      target_id: form.value.target_id,
      suite: form.value.suite,
      repeat_mode: form.value.repeat_mode,
      hour: form.value.hour,
      minute: form.value.minute,
      weekdays: form.value.repeat_mode === 'weekly' ? form.value.weekdays : [],
      start_date: form.value.start_date || undefined,
      end_date: form.value.end_date || undefined,
    }

    if (editingId.value) {
      await scheduleApi.updateSchedule(editingId.value, data)
    } else {
      await scheduleApi.createSchedule(data)
    }
    ElMessage.success(editingId.value ? '保存成功' : '创建成功')
    dialogVisible.value = false
    loadData()
  } catch (e: any) {
    ElMessage.error(e?.message || '保存失败')
  } finally {
    saving.value = false
  }
}

async function handleDelete(s: Schedule) {
  try {
    await ElMessageBox.confirm(`确定删除定时任务「${s.name}」？`, '确认删除', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })
    await scheduleApi.deleteSchedule(s.id)
    ElMessage.success('删除成功')
    loadData()
  } catch {
    // cancel
  }
}

async function handleToggle(s: Schedule) {
  try {
    await scheduleApi.toggleSchedule(s.id)
    ElMessage.success(s.enabled ? '已禁用' : '已启用')
    loadData()
  } catch (e: any) {
    ElMessage.error(e?.message || '操作失败')
  }
}

async function handleRun(s: Schedule) {
  try {
    const res = await scheduleApi.runSchedule(s.id)
    if (res.success) {
      ElMessage.success('已触发执行')
      loadData()
    }
  } catch (e: any) {
    ElMessage.error(e?.message || '执行失败')
  }
}

function viewReport(reportId: string | null) {
  if (reportId) {
    router.push({ name: 'MonitorReportDetail', params: { reportId } })
  }
}

// Weekday toggle
const WEEKDAYS = [
  { value: 1, label: '一' },
  { value: 2, label: '二' },
  { value: 3, label: '三' },
  { value: 4, label: '四' },
  { value: 5, label: '五' },
  { value: 6, label: '六' },
  { value: 7, label: '日' },
]

function toggleWeekday(day: number) {
  const idx = form.value.weekdays.indexOf(day)
  if (idx >= 0) form.value.weekdays.splice(idx, 1)
  else form.value.weekdays.push(day)
}

function isWeekdaySelected(day: number) {
  return form.value.weekdays.includes(day)
}

onMounted(loadData)
onUnmounted(stopAutoRefresh)
</script>

<template>
  <div class="page-schedule">
    <div class="section-head">
      <h1 class="section-title">⏰ 定时任务</h1>
      <el-button v-if="isAdmin" type="primary" @click="openCreate">
        + 新增定时任务
      </el-button>
    </div>

    <!-- Schedule list -->
    <el-card v-loading="loading" class="table-card">
      <div v-if="schedules.length > 0" class="schedule-list">
        <div
          v-for="s in schedules"
          :key="s.id"
          class="schedule-row"
        >
          <div class="row-main">
            <span class="sched-name">{{ s.name }}</span>
            <span class="sched-target">{{ s.target_name }}</span>
            <span class="sched-suite">{{ suiteLabel(s.suite) }}</span>
            <span class="sched-desc">{{ descriptionText(s) }}</span>
            <span>
              <span
                class="status-badge"
                :class="s.enabled ? 'badge-enabled' : 'badge-disabled'"
              >
                {{ s.enabled ? '启用' : '禁用' }}
              </span>
            </span>
            <span class="last-run">
              <template v-if="s.last_run_at">
                <span class="last-run-time">{{ formatTime(s.last_run_at) }}</span>
                <span
                  class="status-badge small"
                  :class="statusBadgeClass(s.current_status)"
                >
                  {{ statusInfo(s.current_status).label }}
                </span>
                <a
                  v-if="s.last_report_id"
                  class="report-link"
                  href="javascript:;"
                  @click="viewReport(s.last_report_id)"
                >报告</a>
              </template>
              <template v-else>
                <span class="last-run-time muted">未执行</span>
              </template>
            </span>
            <span class="next-run">{{ formatTime(s.next_run_at) }}</span>
          </div>
          <div v-if="isAdmin" class="row-actions">
            <el-button size="small" class="btn-run" @click="handleRun(s)">执行</el-button>
            <el-button
              size="small"
              class="btn-toggle"
              @click="handleToggle(s)"
            >
              {{ s.enabled ? '禁用' : '启用' }}
            </el-button>
            <el-button size="small" @click="openEdit(s)">编辑</el-button>
            <el-button size="small" type="danger" @click="handleDelete(s)">删除</el-button>
          </div>
        </div>
      </div>
      <el-empty v-else description="暂无定时任务" />
    </el-card>

    <!-- Create/Edit Dialog -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="520px"
      :close-on-click-modal="false"
    >
      <el-form :model="form" label-position="top">
        <el-form-item label="任务名称">
          <el-input v-model="form.name" placeholder="如：每日全量巡检" />
        </el-form-item>

        <el-form-item label="监测目标">
          <el-select v-model="form.target_id" style="width: 100%;">
            <el-option
              v-for="t in targets"
              :key="t.id"
              :label="t.name"
              :value="t.id"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="巡检套件">
          <el-select v-model="form.suite" style="width: 100%;">
            <el-option value="quick" label="快速巡检" />
            <el-option value="full" label="全量巡检" />
          </el-select>
        </el-form-item>

        <el-form-item label="重复周期">
          <div class="repeat-group">
            <div
              class="repeat-btn"
              :class="{ active: form.repeat_mode === 'daily' }"
              @click="form.repeat_mode = 'daily'"
            >
              每天
            </div>
            <div
              class="repeat-btn"
              :class="{ active: form.repeat_mode === 'weekday' }"
              @click="form.repeat_mode = 'weekday'"
            >
              工作日
            </div>
            <div
              class="repeat-btn"
              :class="{ active: form.repeat_mode === 'weekly' }"
              @click="form.repeat_mode = 'weekly'"
            >
              每周
            </div>
          </div>
        </el-form-item>

        <el-form-item label="执行时间">
          <div class="time-picker">
            <el-select v-model="form.hour" style="width: 80px;">
              <el-option v-for="h in 24" :key="h - 1" :value="h - 1" :label="String(h - 1).padStart(2, '0')" />
            </el-select>
            <span class="time-sep">:</span>
            <el-select v-model="form.minute" style="width: 80px;">
              <el-option v-for="m in 12" :key="(m - 1) * 5" :value="(m - 1) * 5" :label="String((m - 1) * 5).padStart(2, '0')" />
            </el-select>
          </div>
        </el-form-item>

        <el-form-item v-if="form.repeat_mode === 'weekly'" label="星期几">
          <div class="weekday-group">
            <div
              v-for="w in WEEKDAYS"
              :key="w.value"
              class="weekday-btn"
              :class="{ active: isWeekdaySelected(w.value) }"
              @click="toggleWeekday(w.value)"
            >
              {{ w.label }}
            </div>
          </div>
        </el-form-item>

        <el-form-item label="有效期（可选）">
          <div class="date-row">
            <el-date-picker
              v-model="form.start_date"
              type="date"
              placeholder="生效日期"
              value-format="YYYY-MM-DD"
              style="flex: 1;"
            />
            <el-date-picker
              v-model="form.end_date"
              type="date"
              placeholder="失效日期"
              value-format="YYYY-MM-DD"
              style="flex: 1;"
            />
          </div>
          <div class="form-hint">不设置则永久有效</div>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="saving" @click="handleSave">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
.page-schedule {
  padding: 0 0 40px;
}

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

.section-title {
  font-size: 18px;
  font-weight: 700;
  color: $gray-900;
}

.table-card {
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.schedule-list {
  display: flex;
  flex-direction: column;
}

.schedule-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid $gray-100;
  gap: 12px;

  &:last-child {
    border-bottom: none;
  }
}

.row-main {
  display: flex;
  align-items: center;
  gap: 16px;
  flex: 1;
  min-width: 0;
  flex-wrap: wrap;
}

.sched-name {
  font-weight: 600;
  color: $gray-900;
  min-width: 80px;
}

.sched-target {
  font-size: 13px;
  color: $gray-700;
}

.sched-suite {
  font-size: 13px;
  color: $gray-500;
}

.sched-desc {
  font-size: 13px;
  color: $gray-500;
}

.status-badge {
  font-size: 12px;
  padding: 3px 10px;
  border-radius: 6px;
  font-weight: 600;
  display: inline-block;

  &.small {
    font-size: 11px;
    padding: 2px 8px;
  }
}

.badge-enabled {
  background: #dcfce7;
  color: #15803d;
}

.badge-disabled {
  background: $gray-100;
  color: $gray-500;
}

.badge-running {
  background: #dbeafe;
  color: #1d4ed8;
}

.badge-success {
  background: #dcfce7;
  color: #15803d;
}

.badge-failed, .badge-error {
  background: #fee2e2;
  color: #dc2626;
}

.badge-idle {
  background: $gray-100;
  color: $gray-500;
}

.last-run {
  display: flex;
  align-items: center;
  gap: 6px;
}

.last-run-time {
  font-size: 12px;
  color: $gray-700;

  &.muted {
    color: $gray-400;
  }
}

.report-link {
  font-size: 12px;
  color: $primary;
  cursor: pointer;

  &:hover {
    text-decoration: underline;
  }
}

.next-run {
  font-size: 12px;
  color: $gray-500;
}

.row-actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}

.btn-run {
  background: #dbeafe;
  color: #1d4ed8;
  border-color: #dbeafe;
}

.btn-toggle {
  background: #fef3c7;
  color: #92400e;
  border-color: #fef3c7;
}

// Dialog form
.repeat-group {
  display: flex;
  gap: 8px;
  width: 100%;
}

.repeat-btn {
  flex: 1;
  padding: 10px 0;
  text-align: center;
  border: 2px solid $gray-200;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  color: $gray-600;
  background: #fff;
  transition: all 0.15s;

  &:hover {
    border-color: $primary;
    color: $primary;
  }

  &.active {
    border-color: $primary;
    background: $primary;
    color: #fff;
  }
}

.time-picker {
  display: flex;
  align-items: center;
  gap: 6px;
}

.time-sep {
  font-size: 18px;
  font-weight: 700;
  color: $gray-400;
}

.weekday-group {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.weekday-btn {
  width: 44px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid $gray-200;
  border-radius: 8px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: $gray-600;
  background: #fff;
  transition: all 0.15s;

  &:hover {
    border-color: $primary;
    color: $primary;
  }

  &.active {
    border-color: $primary;
    background: $primary;
    color: #fff;
  }
}

.date-row {
  display: flex;
  gap: 12px;
  width: 100%;
}

.form-hint {
  font-size: 12px;
  color: $gray-500;
  margin-top: 4px;
}

@media screen and (max-width: 1024px) {
  .sched-suite, .next-run {
    display: none;
  }
}

@media screen and (max-width: 768px) {
  .row-main {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }

  .schedule-row {
    flex-direction: column;
    align-items: flex-start;
    padding: 14px;
  }

  .row-actions {
    width: 100%;
    flex-wrap: wrap;
  }

  .repeat-group {
    flex-direction: column;
    gap: 6px;
  }

  .repeat-btn {
    padding: 8px 0;
    font-size: 13px;
  }

  .date-row {
    flex-direction: column;
    gap: 0;
  }

  .section-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }
}

@media screen and (max-width: 480px) {
  .sched-name {
    font-size: 14px;
  }

  .weekday-btn {
    width: 36px;
    height: 30px;
    font-size: 11px;
  }
}
</style>
