<script setup>
import { computed, onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'

import { fetchAccounts } from '../api/accounts'
import {
  clearScheduleLogs,
  createSchedule,
  deleteSchedule,
  fetchScheduleLogs,
  fetchSchedules,
  runScheduleNow,
  toggleSchedule,
  updateSchedule,
} from '../api/schedules'
import { useUserStore } from '../stores/user'

const userStore = useUserStore()

const loading = ref(false)
const schedules = ref([])
const schedulePage = ref(1)
const scheduleTotal = ref(0)
const schedulePageSize = 12

const accountsLoading = ref(false)
const accountOptions = ref([])

const editorOpen = ref(false)
const editorSaving = ref(false)
const editingId = ref(null)

const logsOpen = ref(false)
const logsLoading = ref(false)
const logs = ref([])
const logsSchedule = ref(null)

const vipModalOpen = ref(false)

const form = reactive({
  name: '',
  schedule_time: '08:00',
  weekdays: ['1', '2', '3', '4', '5'],
  browse_type: '应读',
  enable_screenshot: true,
  random_delay: false,
  account_ids: [],
})

const browseTypeOptions = [
  { label: '应读', value: '应读' },
  { label: '注册前未读', value: '注册前未读' },
]

function normalizeBrowseType(value) {
  if (String(value) === '注册前未读') return '注册前未读'
  return '应读'
}

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

const canUseSchedule = computed(() => userStore.isVip)
const scheduleTotalPages = computed(() => Math.max(1, Math.ceil((scheduleTotal.value || 0) / schedulePageSize)))

function normalizeTime(value) {
  const match = String(value || '').match(/^(\d{1,2}):(\d{2})$/)
  if (!match) return null
  const hour = Number(match[1])
  const minute = Number(match[2])
  if (Number.isNaN(hour) || Number.isNaN(minute)) return null
  if (hour < 0 || hour > 23 || minute < 0 || minute > 59) return null
  return `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`
}

function weekdaysText(textOrArray) {
  const raw = Array.isArray(textOrArray) ? textOrArray : String(textOrArray || '').split(',').filter(Boolean)
  const map = Object.fromEntries(weekdayOptions.map((w) => [w.value, w.label]))
  return raw.map((d) => map[String(d)] || String(d)).join(' ')
}

async function loadAccounts() {
  accountsLoading.value = true
  try {
    const list = await fetchAccounts({ refresh: false })
    accountOptions.value = (list || []).map((acc) => ({ label: acc.username, value: acc.id }))
  } catch {
    accountOptions.value = []
  } finally {
    accountsLoading.value = false
  }
}

async function reloadSchedulesAfterMutate() {
  if (schedulePage.value > 1 && schedules.value.length <= 1) {
    schedulePage.value -= 1
  }
  await loadSchedules()
}

async function onSchedulePageChange(page) {
  schedulePage.value = page
  await loadSchedules()
}

async function loadSchedules() {
  loading.value = true
  try {
    const params = {
      limit: schedulePageSize,
      offset: (schedulePage.value - 1) * schedulePageSize,
    }
    const payload = await fetchSchedules(params)
    const rawItems = Array.isArray(payload) ? payload : (Array.isArray(payload?.items) ? payload.items : [])
    const rawTotal = Array.isArray(payload) ? rawItems.length : Number(payload?.total ?? rawItems.length)
    schedules.value = rawItems.map((s) => ({
      ...s,
      browse_type: normalizeBrowseType(s?.browse_type),
    }))
    scheduleTotal.value = Number.isFinite(rawTotal) ? Math.max(0, rawTotal) : rawItems.length
  } catch (e) {
    if (e?.response?.status === 401) window.location.href = '/login'
    schedules.value = []
    scheduleTotal.value = 0
  } finally {
    loading.value = false
  }
}

function openCreate() {
  editingId.value = null
  form.name = ''
  form.schedule_time = '08:00'
  form.weekdays = ['1', '2', '3', '4', '5']
  form.browse_type = '应读'
  form.enable_screenshot = true
  form.random_delay = false
  form.account_ids = []
  editorOpen.value = true
}

function openEdit(schedule) {
  editingId.value = schedule.id
  form.name = schedule.name || ''
  form.schedule_time = normalizeTime(schedule.schedule_time) || '08:00'
  form.weekdays = String(schedule.weekdays || '')
    .split(',')
    .filter(Boolean)
    .map((v) => String(v))
  if (form.weekdays.length === 0) form.weekdays = ['1', '2', '3', '4', '5']
  form.browse_type = normalizeBrowseType(schedule.browse_type)
  form.enable_screenshot = Number(schedule.enable_screenshot ?? 1) !== 0
  form.random_delay = Number(schedule.random_delay ?? 0) !== 0
  form.account_ids = Array.isArray(schedule.account_ids) ? schedule.account_ids.slice() : []
  editorOpen.value = true
}

async function saveSchedule() {
  if (!canUseSchedule.value) {
    vipModalOpen.value = true
    return
  }

  const normalizedTime = normalizeTime(form.schedule_time)
  if (!normalizedTime) {
    ElMessage.error('时间格式错误，请使用 HH:MM')
    return
  }
  if (!form.weekdays || form.weekdays.length === 0) {
    ElMessage.warning('请选择至少一个执行日期')
    return
  }

  editorSaving.value = true
  try {
    const payload = {
      name: form.name.trim() || '我的定时任务',
      schedule_time: normalizedTime,
      weekdays: form.weekdays.join(','),
      browse_type: form.browse_type,
      enable_screenshot: form.enable_screenshot ? 1 : 0,
      random_delay: form.random_delay ? 1 : 0,
      account_ids: form.account_ids,
    }

    if (editingId.value) {
      await updateSchedule(editingId.value, payload)
      ElMessage.success('保存成功')
    } else {
      await createSchedule(payload)
      ElMessage.success('创建成功')
      schedulePage.value = 1
    }
    editorOpen.value = false
    await loadSchedules()
  } catch (e) {
    const data = e?.response?.data
    ElMessage.error(data?.error || '保存失败')
  } finally {
    editorSaving.value = false
  }
}

async function onDelete(schedule) {
  try {
    await ElMessageBox.confirm(`确定要删除定时任务「${schedule.name || '未命名任务'}」吗？`, '删除任务', {
      confirmButtonText: '删除',
      cancelButtonText: '取消',
      type: 'warning',
    })
  } catch {
    return
  }

  try {
    const res = await deleteSchedule(schedule.id)
    if (res?.success) {
      ElMessage.success('已删除')
      await reloadSchedulesAfterMutate()
    } else {
      ElMessage.error(res?.error || '删除失败')
    }
  } catch (e) {
    const data = e?.response?.data
    ElMessage.error(data?.error || '删除失败')
  }
}

async function onToggle(schedule, enabled) {
  if (!canUseSchedule.value) {
    vipModalOpen.value = true
    return
  }

  try {
    const res = await toggleSchedule(schedule.id, { enabled })
    if (res?.success) {
      schedule.enabled = enabled ? 1 : 0
      ElMessage.success(enabled ? '已启用' : '已禁用')
    }
  } catch {
    ElMessage.error('操作失败')
  }
}

async function onRunNow(schedule) {
  if (!canUseSchedule.value) {
    vipModalOpen.value = true
    return
  }

  try {
    const res = await runScheduleNow(schedule.id)
    if (res?.success) ElMessage.success(res?.message || '已开始执行')
    else ElMessage.error(res?.error || '执行失败')
  } catch (e) {
    const data = e?.response?.data
    ElMessage.error(data?.error || '执行失败')
  }
}

async function openLogs(schedule) {
  logsSchedule.value = schedule
  logsOpen.value = true
  logsLoading.value = true
  try {
    logs.value = await fetchScheduleLogs(schedule.id, { limit: 20 })
  } catch {
    logs.value = []
  } finally {
    logsLoading.value = false
  }
}

async function clearLogs() {
  const schedule = logsSchedule.value
  if (!schedule) return

  try {
    await ElMessageBox.confirm('确定要清空该任务的所有执行日志吗？', '清空日志', {
      confirmButtonText: '清空',
      cancelButtonText: '取消',
      type: 'warning',
    })
  } catch {
    return
  }

  try {
    const res = await clearScheduleLogs(schedule.id)
    if (res?.success) {
      ElMessage.success(`已清空 ${res?.deleted || 0} 条日志`)
      logs.value = []
    } else {
      ElMessage.error(res?.error || '操作失败')
    }
  } catch {
    ElMessage.error('操作失败')
  }
}

function statusTagType(status) {
  const text = String(status || '')
  if (text === 'success' || text === 'completed') return 'success'
  if (text === 'failed') return 'danger'
  return 'info'
}

function formatDuration(seconds) {
  const value = Number(seconds || 0)
  const mins = Math.floor(value / 60)
  const secs = value % 60
  if (mins <= 0) return `${secs} 秒`
  return `${mins} 分 ${secs} 秒`
}

onMounted(async () => {
  if (!userStore.vipInfo) {
    userStore.refreshVipInfo().catch(() => {
      window.location.href = '/login'
    })
  }

  await Promise.all([loadAccounts(), loadSchedules()])
})
</script>

<template>
  <div class="page">
    <el-alert
      v-if="!canUseSchedule"
      type="warning"
      show-icon
      :closable="false"
      title="定时任务为 VIP 专属功能，升级后可使用。"
      class="vip-alert"
    >
      <template #default>
        <div class="vip-actions">
          <el-button type="primary" plain @click="vipModalOpen = true">了解VIP特权</el-button>
        </div>
      </template>
    </el-alert>

    <el-card shadow="never" class="panel" :body-style="{ padding: '14px' }">
      <div class="panel-head">
        <div class="panel-title">定时任务</div>
        <div class="panel-actions">
          <el-button :loading="loading" @click="loadSchedules">刷新</el-button>
          <el-button type="primary" :disabled="!canUseSchedule" @click="openCreate">新建任务</el-button>
        </div>
      </div>

      <el-skeleton v-if="loading" :rows="6" animated />
      <template v-else>
        <el-empty v-if="schedules.length === 0" description="暂无定时任务" />
        <div v-else class="grid">
          <el-card v-for="s in schedules" :key="s.id" shadow="never" class="schedule-card" :body-style="{ padding: '14px' }">
            <div class="schedule-top">
              <div class="schedule-main">
                <div class="schedule-title">
                  <span class="schedule-name">{{ s.name || '未命名任务' }}</span>
                </div>
                <div class="schedule-meta app-muted">
                  <span>⏰ {{ normalizeTime(s.schedule_time) || s.schedule_time }}</span>
                  <span>📅 {{ weekdaysText(s.weekdays) }}</span>
                </div>
                <div class="schedule-meta app-muted">
                  <span>📋 {{ s.browse_type || '应读' }}</span>
                  <span>👥 {{ (s.account_ids || []).length }} 个账号</span>
                  <span>{{ Number(s.enable_screenshot ?? 1) !== 0 ? '📸 截图' : '📷 不截图' }}</span>
                  <span v-if="Number(s.random_delay ?? 0) !== 0">🎲 随机±15分钟</span>
                </div>
              </div>

              <div class="schedule-switch">
                <el-switch
                  :model-value="Boolean(Number(s.enabled))"
                  :disabled="!canUseSchedule"
                  inline-prompt
                  active-text="启用"
                  inactive-text="停用"
                  @change="(val) => onToggle(s, val)"
                />
              </div>
            </div>

            <div class="schedule-actions">
              <el-button size="small" type="primary" :disabled="!canUseSchedule" @click="onRunNow(s)">立即执行</el-button>
              <el-button size="small" @click="openLogs(s)">日志</el-button>
              <el-button size="small" :disabled="!canUseSchedule" @click="openEdit(s)">编辑</el-button>
              <el-button size="small" type="danger" text :disabled="!canUseSchedule" @click="onDelete(s)">删除</el-button>
            </div>
          </el-card>
        </div>

        <div v-if="scheduleTotal > schedulePageSize" class="pagination">
          <el-pagination
            v-model:current-page="schedulePage"
            :page-size="schedulePageSize"
            :total="scheduleTotal"
            layout="prev, pager, next, jumper, ->, total"
            @current-change="onSchedulePageChange"
          />
          <div class="page-hint app-muted">第 {{ schedulePage }} / {{ scheduleTotalPages }} 页</div>
        </div>
      </template>
    </el-card>

    <el-dialog v-model="editorOpen" :title="editingId ? '编辑定时任务' : '新建定时任务'" width="min(720px, 92vw)">
      <el-form label-position="top">
        <el-form-item label="任务名称">
          <el-input v-model="form.name" placeholder="我的定时任务" :disabled="!canUseSchedule" />
        </el-form-item>
        <el-form-item label="执行时间（HH:MM）">
          <el-time-picker
            v-model="form.schedule_time"
            placeholder="选择时间"
            format="HH:mm"
            value-format="HH:mm"
            style="width: 180px"
            :disabled="!canUseSchedule"
          />
        </el-form-item>
        <el-form-item label="执行日期">
          <el-checkbox-group v-model="form.weekdays" :disabled="!canUseSchedule">
            <el-checkbox v-for="w in weekdayOptions" :key="w.value" :label="w.value">{{ w.label }}</el-checkbox>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="浏览类型">
          <el-select v-model="form.browse_type" style="width: 160px" :disabled="!canUseSchedule">
            <el-option v-for="opt in browseTypeOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="截图">
          <div class="switch-row">
            <el-switch
              v-model="form.enable_screenshot"
              :disabled="!canUseSchedule"
              inline-prompt
              active-text="截图"
              inactive-text="不截图"
            />
            <el-switch
              v-model="form.random_delay"
              :disabled="!canUseSchedule"
              inline-prompt
              active-text="随机±15分钟"
              inactive-text="固定时间"
            />
          </div>
        </el-form-item>
        <el-form-item label="参与账号">
          <el-select
            v-model="form.account_ids"
            multiple
            filterable
            collapse-tags
            collapse-tags-tooltip
            placeholder="选择账号（可多选）"
            style="width: 100%"
            :loading="accountsLoading"
            :disabled="!canUseSchedule"
          >
            <el-option v-for="opt in accountOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
          </el-select>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="editorOpen = false">取消</el-button>
        <el-button type="primary" :loading="editorSaving" :disabled="!canUseSchedule" @click="saveSchedule">保存</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="logsOpen" :title="logsSchedule ? `【${logsSchedule.name || '未命名任务'}】执行日志` : '执行日志'" width="min(760px, 92vw)">
      <el-skeleton v-if="logsLoading" :rows="6" animated />
      <template v-else>
        <el-empty v-if="logs.length === 0" description="暂无执行日志" />
        <div v-else class="logs">
          <el-card v-for="log in logs" :key="log.id" shadow="never" class="log-card" :body-style="{ padding: '12px' }">
            <div class="log-head">
              <el-tag size="small" effect="light" :type="statusTagType(log.status)">
                {{ log.status === 'failed' ? '失败' : log.status === 'running' ? '进行中' : '成功' }}
              </el-tag>
              <span class="app-muted">{{ log.created_at || '' }}</span>
            </div>
            <div class="log-body">
              <div>账号数：{{ log.total_accounts || 0 }} 个</div>
              <div>成功：{{ log.success_count || 0 }} 个 · 失败：{{ log.failed_count || 0 }} 个</div>
              <div>耗时：{{ formatDuration(log.duration || 0) }}</div>
              <div v-if="log.error_message" class="log-error">错误：{{ log.error_message }}</div>
            </div>
          </el-card>
        </div>
      </template>

      <template #footer>
        <el-button @click="logsOpen = false">关闭</el-button>
        <el-button type="danger" plain :disabled="logs.length === 0" @click="clearLogs">清空日志</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="vipModalOpen" title="VIP 特权" width="min(560px, 92vw)">
      <el-alert
        type="info"
        :closable="false"
        title="升级 VIP 后可解锁：无限账号、优先排队、定时任务、批量操作。"
        show-icon
      />
      <div class="vip-body">
        <div class="vip-tip app-muted">升级方式：请通过“反馈”联系管理员开通。</div>
      </div>
      <template #footer>
        <el-button type="primary" @click="vipModalOpen = false">我知道了</el-button>
      </template>
    </el-dialog>
  </div>
</template>

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

.switch-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

.vip-alert {
  border-radius: var(--app-radius);
  border: 1px solid var(--app-border);
}

.vip-actions {
  margin-top: 10px;
}

.panel {
  border-radius: var(--app-radius);
  border: 1px solid var(--app-border);
}

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

.panel-title {
  font-size: 16px;
  font-weight: 900;
}

.panel-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 12px;
  align-items: start;
}

.schedule-card {
  border-radius: 14px;
  border: 1px solid var(--app-border);
}

.schedule-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.schedule-main {
  min-width: 0;
  flex: 1;
}

.schedule-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.schedule-name {
  font-size: 14px;
  font-weight: 900;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.schedule-meta {
  margin-top: 6px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 12px;
}

.schedule-actions {
  margin-top: 12px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.pagination {
  margin-top: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

.page-hint {
  font-size: 12px;
}

.logs {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.log-card {
  border-radius: 12px;
  border: 1px solid var(--app-border);
}

.log-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 12px;
}

.log-body {
  margin-top: 8px;
  font-size: 13px;
  line-height: 1.6;
}

.log-error {
  margin-top: 6px;
  color: #b91c1c;
}

.vip-body {
  padding: 12px 0 0;
}

.vip-tip {
  margin-top: 10px;
  font-size: 13px;
  line-height: 1.6;
}

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

@media (max-width: 768px) {
  .panel-actions {
    width: 100%;
    justify-content: flex-end;
  }

  .schedule-switch {
    width: 100%;
    display: flex;
    justify-content: flex-end;
  }
}
</style>
