<template>
  <div class="store-page">
    <Breadcrumb />

    <a-card title="抢课任务">
      <div class="buttonGroup buttonGroup-desktop">
        <a-button v-if="canSubmit" type="primary" size="large" @click="openModal()">
          <template #icon><icon-plus /></template>
          提交任务
        </a-button>
        <a-button size="large" @click="refreshList()">
          <template #icon><icon-refresh /></template>
          刷新
        </a-button>
      </div>

      <div class="buttonGroup buttonGroup-mobile">
        <a-button v-if="canSubmit" type="primary" size="large" @click="openModal()">
          <template #icon><icon-plus /></template>
          提交任务
        </a-button>
        <a-button size="large" @click="refreshList()">
          <template #icon><icon-refresh /></template>
          刷新
        </a-button>
      </div>

      <AppQueryFilter>
        <a-row class="queryForm app-query-form query-row">
          <a-col :flex="'1000px'" class="query-main">
            <a-form :model="query" :label-col-props="{ span: 6 }" :wrapper-col-props="{ span: 18 }" label-align="left">
              <a-row :gutter="16">
                <a-col :span="6">
                  <a-form-item field="status" label="状态">
                    <a-select v-model="query.status" placeholder="全部" allow-clear>
                      <a-option value="paused">未开始</a-option>
                      <a-option value="pending">待分配</a-option>
                      <a-option value="assigned">已分配</a-option>
                      <a-option value="running">抢课中</a-option>
                      <a-option value="success">成功</a-option>
                      <a-option value="failed">失败</a-option>
                      <a-option value="cancelled">已取消</a-option>
                    </a-select>
                  </a-form-item>
                </a-col>
                <a-col :span="6">
                  <a-form-item field="student_num" label="学号">
                    <a-input v-model="query.student_num" placeholder="学号" allow-clear />
                  </a-form-item>
                </a-col>
                <a-col :span="6">
                  <a-form-item field="name" label="备注">
                    <a-input v-model="query.name" placeholder="备注关键词" allow-clear />
                  </a-form-item>
                </a-col>
                <a-col :span="6">
                  <a-form-item field="batch_id" label="选课批次">
                    <a-select v-model="query.batch_id" placeholder="全部" allow-clear allow-search>
                      <a-option v-for="item in batchOptions" :key="item.id" :value="item.id">
                        {{ item.name }}（{{ item.jx0502zbid }}）
                      </a-option>
                    </a-select>
                  </a-form-item>
                </a-col>
                <a-col :span="6">
                  <a-form-item field="course_name" label="课程名称">
                    <a-input v-model="query.course_name" placeholder="模糊匹配课程或分组" allow-clear />
                  </a-form-item>
                </a-col>
              </a-row>
            </a-form>
          </a-col>
          <a-divider class="query-divider" style="height: 84px" direction="vertical" />
          <a-col :flex="1" class="app-query-actions">
            <a-space class="query-actions-space" direction="vertical" :size="18">
              <a-button type="primary" @click="search">
                <template #icon><icon-search /></template>
                搜索
              </a-button>
              <a-button @click="resetQuery">
                <template #icon><icon-refresh /></template>
                重置
              </a-button>
            </a-space>
          </a-col>
        </a-row>
      </AppQueryFilter>

      <a-alert v-if="notice" style="margin-top: 15px;">{{ notice }}</a-alert>

      <a-table row-key="id" :data="data" :bordered="false" hoverable class="table" :loading="loading"
        :scroll="{ x: 1200 }" :pagination="false">
        <template #columns>
          <a-table-column title="学号" data-index="student_num" :width="130" />
          <a-table-column title="选课批次" :width="220" ellipsis tooltip>
            <template #cell="{ record }">
              {{ record.batch_name || record.jx0502zbid || '-' }}
            </template>
          </a-table-column>
          <a-table-column title="目标课程" :width="260">
            <template #cell="{ record }">
              <a-space wrap>
                <a-tag v-for="item in record.courses || []" :key="item">{{ item }}</a-tag>
                <a-tag v-for="item in record.course_groups || []" :key="item" color="purple">{{ item }}</a-tag>
              </a-space>
            </template>
          </a-table-column>
          <a-table-column title="状态" :width="110">
            <template #cell="{ record }">
              <a-tag :color="statusColor(record.status)">{{ statusText(record.status) }}</a-tag>
            </template>
          </a-table-column>
          <a-table-column title="结果" :width="220">
            <template #cell="{ record }">
              <AppTableEllipsis :row-key="`${record.id}-result`" :content="resultText(record)" />
            </template>
          </a-table-column>
          <a-table-column title="备注" :width="140" ellipsis tooltip>
            <template #cell="{ record }">{{ record.name || '-' }}</template>
          </a-table-column>
          <a-table-column title="更新时间" :width="180">
            <template #cell="{ record }">{{ formatTime(record.update_time) }}</template>
          </a-table-column>
          <a-table-column title="操作" :width="280" :fixed="tableFixed('right')">
            <template #cell="{ record }">
              <a-space wrap>
                <a-button v-if="canControl && canStart(record)" type="text" size="small" status="success"
                  @click="startTask(record)">
                  开启
                </a-button>
                <a-button v-if="canControl && canPause(record)" type="text" size="small" status="warning"
                  @click="pauseTask(record)">
                  暂停
                </a-button>
                <a-button v-if="canSubmit" type="text" size="small" :disabled="!canEdit(record)"
                  @click="openModal(record)">编辑</a-button>
                <a-button v-if="canSubmit" type="text" size="small" @click="copyTask(record)">复制</a-button>
                <a-popconfirm v-if="canSubmit" content="确认取消该抢课任务？" @ok="cancelTask(record)">
                  <a-button type="text" status="danger" size="small" :disabled="!canCancel(record)">取消</a-button>
                </a-popconfirm>
              </a-space>
            </template>
          </a-table-column>
        </template>
        <template #empty>
          <a-empty description="暂无抢课任务">
            <a-button v-if="canSubmit" type="primary" @click="openModal()">提交第一个任务</a-button>
          </a-empty>
        </template>
      </a-table>
    </a-card>

    <a-modal v-model:visible="visible" :title="modalTitle" :width="isMobile ? '100%' : '720px'" draggable esc-to-close
      :ok-loading="saving" :on-before-ok="submitTask">
      <a-spin :loading="detailLoading" style="width: 100%">
        <a-form :model="form" layout="vertical" class="task-form">
          <a-form-item label="备注">
            <a-textarea v-model="form.name" no-trim placeholder="添加对任务的备注（非必填）" :max-length="{ length: 50 }" allow-clear
              show-word-limit :auto-size="{ minRows: 2, maxRows: 4 }" />
          </a-form-item>
          <a-form-item label="选课批次" required>
            <a-select v-model="form.batch_id" placeholder="请选择抢课批次" allow-clear allow-search>
              <a-option v-for="item in batchOptions" :key="item.id" :value="item.id">
                {{ item.name }}
              </a-option>
            </a-select>
          </a-form-item>
          <a-form-item label="统一身份认证账号" required>
            <a-select v-model="form.jw_account_id" placeholder="请选择已验证的统一身份认证账号" allow-search allow-clear>
              <a-option v-for="item in jwAccounts" :key="item.id" :value="item.id">
                {{ item.username }}({{ item.realname || '未知' }})
              </a-option>
            </a-select>
            <template #extra>
              <span v-if="jwAccounts.length === 0">
                暂无可用账号，请先到
                <a-link @click="$router.push({ name: 'jwAccount.accountList' })">统一身份认证</a-link>
                添加并验证
              </span>
            </template>
          </a-form-item>
          <a-form-item label="课程名称（每行一个，精确匹配）">
            <a-textarea v-model="form.coursesText" :auto-size="{ minRows: 3 }" placeholder="每行填写一门课程名称" />
            <template #extra>{{ targetHint }}</template>
          </a-form-item>
          <a-form-item label="课程分组（体育课请在此填写项目名称）">
            <a-textarea v-model="form.courseGroupsText" :auto-size="{ minRows: 2 }" placeholder="每行填写一个课程分组" />
          </a-form-item>
          <a-row :gutter="16">
            <a-col :xs="24" :sm="12">
              <a-form-item label="抢课间隔（ms）">
                <a-input-number v-model="form.interval_ms" :min="minInterval" :max="10000" style="width: 100%" />
                <template #extra>当前最低 {{ minInterval }}ms</template>
              </a-form-item>
            </a-col>
            <a-col :xs="24" :sm="12">
              <a-form-item label="启用公选课接口">
                <a-switch v-model="form.enable_ggxxk" />
              </a-form-item>
            </a-col>
            <a-col :xs="24" :sm="12">
              <a-form-item label="登录失效后自动重新登录">
                <a-switch v-model="form.auto_relogin" />
                <template #extra>开启后抢课过程中会话失效将自动重新登录并继续</template>
              </a-form-item>
            </a-col>
          </a-row>
        </a-form>
      </a-spin>
    </a-modal>
  </div>
</template>

<script setup>
import { reactive, ref, onMounted, onUnmounted, computed } from 'vue'
import { Notification } from '@arco-design/web-vue'
import { getQkTask, getQkTaskDetail, saveQkTask, deleteQkTask, startQkTask, pauseQkTask, getQkBatchList } from '@/api/qk'
import { getJwAccount } from '@/api/jwAccount'
import { useResponsiveTable } from '@/hooks/useResponsiveTable'
import { hasAnyPermission, QK_ASSISTANT_CONTROL_CODES, QK_ASSISTANT_SUBMIT_CODES } from '@/utils/permission'
import {
  getMinQkInterval,
  getQkTargetHint,
  splitQkLines,
  validateQkTaskForm
} from '@/utils/qkTaskRules'
import { useRoute } from 'vue-router'
import { getNotice } from '@/utils/util'

const notice = ref('')

const GetNotice = async () => {
  const { path } = useRoute()
  const res = await getNotice(path)
  notice.value = res
}

const { tableFixed, isMobile } = useResponsiveTable()
const canSubmit = computed(() => hasAnyPermission(QK_ASSISTANT_SUBMIT_CODES))
const canControl = computed(() => hasAnyPermission(QK_ASSISTANT_CONTROL_CODES))

const loading = ref(false)
const saving = ref(false)
const detailLoading = ref(false)
const visible = ref(false)
const isCopy = ref(false)
const data = ref([])
const batchOptions = ref([])
const jwAccounts = ref([])
const query = reactive({
  status: '',
  student_num: '',
  name: '',
  batch_id: '',
  course_name: ''
})
const form = reactive({
  id: '',
  name: '',
  batch_id: '',
  jw_account_id: undefined,
  coursesText: '',
  courseGroupsText: '',
  enable_ggxxk: true,
  auto_relogin: false,
  interval_ms: 500
})

const targetCount = computed(() => {
  return splitQkLines(form.coursesText).length + splitQkLines(form.courseGroupsText).length
})
const minInterval = computed(() => getMinQkInterval(targetCount.value))
const targetHint = computed(() => getQkTargetHint(form.coursesText, form.courseGroupsText))
const modalTitle = computed(() => {
  if (form.id) return '编辑抢课任务'
  if (isCopy.value) return '复制抢课任务'
  return '提交抢课任务'
})

const splitLines = splitQkLines

const formatTime = (time) => {
  if (!time) return '-'
  return new Date(Number(time)).toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  })
}

const statusText = (status) => ({
  paused: '未开始',
  pending: '待分配',
  assigned: '已分配',
  running: '抢课中',
  success: '成功',
  failed: '失败',
  cancelled: '已取消'
}[status] || status)

const statusColor = (status) => ({
  paused: 'gray',
  pending: 'blue',
  assigned: 'arcoblue',
  running: 'orange',
  success: 'green',
  failed: 'red',
  cancelled: 'gray'
}[status] || 'gray')

const canStart = (record) => ['paused', 'failed'].includes(record.status)
const canPause = (record) => ['pending', 'assigned', 'running'].includes(record.status)
const canEdit = (record) => ['paused', 'failed', 'cancelled'].includes(record.status)
const canCancel = (record) => ['paused', 'pending', 'failed'].includes(record.status)
const resultText = (record) => record.error_msg || record.result_json?.message || record.result_json?.course || '-'

const resetForm = () => {
  isCopy.value = false
  Object.assign(form, {
    id: '',
    name: '',
    batch_id: '',
    jw_account_id: jwAccounts.value[0]?.id,
    coursesText: '',
    courseGroupsText: '',
    enable_ggxxk: true,
    auto_relogin: false,
    interval_ms: 500
  })
}

const fillFormFromTask = (task, { copy = false } = {}) => {
  Object.assign(form, {
    id: copy ? '' : task.id,
    name: task.name,
    batch_id: task.batch_id || '',
    jw_account_id: task.jw_account_id || jwAccounts.value.find(item => item.username === task.student_num)?.id,
    coursesText: (task.courses || []).join('\n'),
    courseGroupsText: (task.course_groups || []).join('\n'),
    enable_ggxxk: task.enable_ggxxk,
    auto_relogin: !!task.auto_relogin,
    interval_ms: task.interval_ms
  })
}

const loadTaskDetail = async (id) => {
  const res = await getQkTaskDetail({ id })
  if (!res || res.code !== 0) {
    throw new Error(res?.msg || '获取任务详情失败')
  }
  const task = res.data?.task
  if (!task) {
    throw new Error('任务不存在')
  }
  return task
}

const openModal = async (record) => {
  resetForm()
  visible.value = true
  if (!record) return
  try {
    detailLoading.value = true
    const task = await loadTaskDetail(record.id)
    fillFormFromTask(task)
  } catch (error) {
    visible.value = false
    Notification.error({ title: '获取任务详情失败', content: error.message || '请稍后再试' })
  } finally {
    detailLoading.value = false
  }
}

const copyTask = async (record) => {
  resetForm()
  isCopy.value = true
  visible.value = true
  try {
    detailLoading.value = true
    const task = await loadTaskDetail(record.id)
    fillFormFromTask(task, { copy: true })
  } catch (error) {
    visible.value = false
    isCopy.value = false
    Notification.error({ title: '复制失败', content: error.message || '请稍后再试' })
  } finally {
    detailLoading.value = false
  }
}

const loadJwAccounts = async () => {
  try {
    const res = await getJwAccount()
    if (res?.code === 0) {
      jwAccounts.value = (res.data || []).filter(item => item.state === 1)
      if (!form.jw_account_id && jwAccounts.value.length) {
        form.jw_account_id = jwAccounts.value[0].id
      }
    }
  } catch (_) { }
}

const loadBatches = async () => {
  try {
    const res = await getQkBatchList()
    if (res?.code === 0) {
      batchOptions.value = res.data || []
    }
  } catch (_) { }
}

const getList = async (silent = false) => {
  try {
    if (!silent) loading.value = true
    const params = {}
    if (query.status) params.status = query.status
    if (query.student_num) params.student_num = query.student_num
    if (query.name) params.name = query.name
    if (query.batch_id) params.batch_id = query.batch_id
    if (query.course_name) params.course_name = query.course_name
    const res = await getQkTask(params)
    if (!res || res.code !== 0) {
      if (!silent) {
        Notification.error({ title: '获取抢课任务失败', content: res?.msg || '请稍后再试' })
      }
      return
    }
    data.value = res.data || []
  } catch (error) {
    if (!silent) {
      Notification.error({ title: '获取抢课任务失败', content: error.message || '请稍后再试' })
    }
  } finally {
    if (!silent) loading.value = false
  }
}

const search = () => getList()

const resetQuery = () => {
  query.status = ''
  query.student_num = ''
  query.name = ''
  query.batch_id = ''
  query.course_name = ''
  getList()
}

const refreshList = () => getList()

const submitTask = async () => {
  const validated = validateQkTaskForm(form)
  if (!validated.ok) {
    Notification.error({ title: '保存抢课任务失败', content: validated.message })
    return false
  }
  try {
    saving.value = true
    const payload = {
      id: form.id || undefined,
      name: validated.name,
      batch_id: validated.batch_id,
      jw_account_id: validated.jw_account_id,
      courses: validated.courses,
      course_groups: validated.courseGroups,
      enable_ggxxk: form.enable_ggxxk,
      auto_relogin: form.auto_relogin,
      interval_ms: validated.intervalMs
    }
    const res = await saveQkTask(payload)
    if (!res || res.code !== 0) {
      Notification.error({ title: '保存抢课任务失败', content: res?.msg || '请稍后再试' })
      return false
    }
    Notification.success({ title: '保存成功' })
    await getList()
    return true
  } catch (error) {
    Notification.error({ title: '保存抢课任务失败', content: error.message || '请稍后再试' })
    return false
  } finally {
    saving.value = false
  }
}

const cancelTask = async (record) => {
  const res = await deleteQkTask({ id: record.id })
  if (!res || res.code !== 0) {
    return Notification.error({ title: '取消失败', content: res?.msg || '请稍后再试' })
  }
  Notification.success({ title: '已取消' })
  getList()
}

const startTask = async (record) => {
  const res = await startQkTask({ id: record.id })
  if (!res || res.code !== 0) {
    return Notification.error({ title: '开启失败', content: res?.msg || '请稍后再试' })
  }
  Notification.success({ title: '已开启', content: '任务已进入待分配队列' })
  getList()
}

const pauseTask = async (record) => {
  const res = await pauseQkTask({ id: record.id })
  if (!res || res.code !== 0) {
    return Notification.error({ title: '暂停失败', content: res?.msg || '请稍后再试' })
  }
  Notification.success({ title: '已暂停' })
  getList()
}

let pollTimer = null

const startPolling = () => {
  if (!pollTimer) {
    pollTimer = setInterval(() => getList(true), 5000)
  }
}

const stopPolling = () => {
  if (pollTimer) {
    clearInterval(pollTimer)
    pollTimer = null
  }
}

onMounted(() => {
  loadJwAccounts()
  loadBatches()
  getList()
  GetNotice()
  startPolling()
})

onUnmounted(() => {
  stopPolling()
})
</script>

<style scoped lang="less">
@import '@/styles/store-theme.less';

.buttonGroup {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 12px;
}

.buttonGroup-mobile {
  display: none;
}

.queryForm {
  padding: 0;
  width: 100%;
  box-sizing: border-box;

  @media (min-width: (@app-breakpoint-md + 1px)) {
    margin-top: 20px;
  }
}

.query-main {
  min-width: 0;
}

.query-actions-space {
  width: 100%;
}

.table {
  margin-top: 15px;
}

.task-form {
  max-height: 70vh;
  overflow-y: auto;
}

@media (max-width: 768px) {
  .buttonGroup-desktop {
    display: none;
  }

  .buttonGroup-mobile {
    display: flex;
    align-items: center;
  }

  .buttonGroup-mobile :deep(.arco-btn) {
    flex: 1;
  }

  .query-row {
    display: block;
  }

  .query-divider {
    display: none;
  }

  .query-actions-space {
    margin-top: 4px;
    flex-direction: row !important;
    gap: 10px !important;
  }

  .query-actions-space :deep(.arco-btn) {
    flex: 1;
  }
}
</style>
