<template>
  <div class="page-content">
    <div class="mb-5 flex items-start justify-between">
      <div>
        <h2 class="text-xl font-semibold">定时任务</h2>
        <p class="text-g-500 mt-1 text-sm">Cron 调度应用或数字员工；执行记录持久化，支持多副本安全抢占与超时回收</p>
      </div>
      <ElButton type="primary" @click="openCreate">新建任务</ElButton>
    </div>

    <ElAlert class="mb-4" :closable="false" type="info" title="Cron 使用 5 段格式：分 时 日 月 周，例如 0 9 * * 1-5；任务 API Key 由平台主密钥加密保存。" />
    <ElTable v-loading="loading" :data="items" row-key="id">
      <ElTableColumn label="状态" width="90"><template #default="{row}"><ElTag :type="row.enabled ? 'success' : 'info'">{{ row.enabled ? '运行中' : '已暂停' }}</ElTag></template></ElTableColumn>
      <ElTableColumn prop="name" label="任务" min-width="170"><template #default="{row}"><div class="font-medium">{{row.name}}</div><div class="text-g-500 text-xs">{{row.code}}</div></template></ElTableColumn>
      <ElTableColumn label="调度" min-width="160"><template #default="{row}"><code>{{row.cron_expression}}</code><div class="text-g-500 text-xs">{{row.timezone}}</div></template></ElTableColumn>
      <ElTableColumn label="执行目标" min-width="180"><template #default="{row}">{{row.target_type === 'application' ? '应用' : '数字员工'}} · {{row.target_code}}</template></ElTableColumn>
      <ElTableColumn label="下次执行" width="180"><template #default="{row}">{{formatTime(row.next_run_at)}}</template></ElTableColumn>
      <ElTableColumn label="最近结果" width="120"><template #default="{row}"><ElTag v-if="row.last_status" :type="row.last_status === 'success' ? 'success' : 'danger'">{{row.last_status === 'success' ? '成功' : '失败'}}</ElTag><span v-else>-</span></template></ElTableColumn>
      <ElTableColumn label="操作" width="285" fixed="right"><template #default="{row}">
        <ElButton link type="primary" @click="edit(row)">编辑</ElButton>
        <ElButton link :type="row.enabled ? 'warning' : 'success'" @click="toggle(row)">{{row.enabled ? '暂停' : '启动'}}</ElButton>
        <ElButton link type="primary" @click="runNow(row)">立即执行</ElButton>
        <ElButton link type="primary" @click="showRuns(row)">历史</ElButton>
        <ElButton link type="danger" @click="remove(row)">删除</ElButton>
      </template></ElTableColumn>
    </ElTable>

    <ElDialog v-model="visible" :title="editing ? '编辑定时任务' : '新建定时任务'" width="780px" destroy-on-close>
      <ElForm label-width="110px">
        <div class="grid grid-cols-2 gap-x-4">
          <ElFormItem label="任务编码" required><ElInput v-model="form.code" :disabled="!!editing" placeholder="daily_security_report" /></ElFormItem>
          <ElFormItem label="任务名称" required><ElInput v-model="form.name" /></ElFormItem>
          <ElFormItem label="Cron" required><ElInput v-model="form.cron_expression" placeholder="0 9 * * 1-5" /></ElFormItem>
          <ElFormItem label="时区" required><ElSelect v-model="form.timezone" filterable allow-create class="w-full"><ElOption label="中国标准时间" value="Asia/Shanghai"/><ElOption label="UTC" value="UTC"/></ElSelect></ElFormItem>
          <ElFormItem label="目标类型"><ElSelect v-model="form.target_type" class="w-full" @change="targetChanged"><ElOption label="AI 应用" value="application"/><ElOption label="数字员工" value="digital_employee"/></ElSelect></ElFormItem>
          <ElFormItem label="执行目标" required><ElSelect v-model="form.target_code" filterable class="w-full" @change="targetChanged"><ElOption v-for="target in targets" :key="target.code" :label="`${target.name} (${target.code})`" :value="target.code"/></ElSelect></ElFormItem>
        </div>
        <ElFormItem label="任务描述"><ElInput v-model="form.description" type="textarea" :rows="2" maxlength="4000" /></ElFormItem>
        <ElFormItem label="提示词" required><ElInput v-model="form.prompt" type="textarea" :rows="4" maxlength="100000" show-word-limit placeholder="每次执行发送给目标的用户提示词" /></ElFormItem>
        <ElFormItem label="变量 JSON"><ElInput v-model="variablesText" type="textarea" :rows="3" placeholder='{"department":"security"}' /></ElFormItem>
        <template v-if="form.target_type === 'digital_employee'">
          <ElFormItem label="Skill 范围"><ElSelect v-model="form.skill_ids" multiple clearable class="w-full" placeholder="留空使用数字员工全部 Skill"><ElOption v-for="item in availableSkills" :key="item.id" :label="item.name" :value="item.id"/></ElSelect></ElFormItem>
          <ElFormItem label="MCP 范围"><ElSelect v-model="form.mcp_server_ids" multiple clearable class="w-full" placeholder="留空使用数字员工全部 MCP"><ElOption v-for="item in availableMCP" :key="item.id" :label="item.name" :value="item.id"/></ElSelect></ElFormItem>
        </template>
        <div class="grid grid-cols-2 gap-x-4">
          <ElFormItem label="会话 ID"><ElInput v-model="form.conversation_id" placeholder="可选；相同任务保留最近 5 轮上下文" /></ElFormItem>
          <ElFormItem label="通知渠道"><ElSelect v-model="form.notification_channel_id" clearable class="w-full"><ElOption v-for="channel in channels" :key="channel.id" :label="channel.name" :value="channel.id"/></ElSelect></ElFormItem>
        </div>
        <ElFormItem label="执行 API Key" :required="!editing"><ElInput v-model="form.api_key" type="password" show-password :placeholder="editing ? '留空保留当前密钥' : '具有目标调用权限的 Gateway API Key'" /></ElFormItem>
        <ElFormItem label="创建后启动"><ElSwitch v-model="form.enabled" /></ElFormItem>
      </ElForm>
      <template #footer><ElButton @click="visible=false">取消</ElButton><ElButton type="primary" :loading="saving" @click="save">保存</ElButton></template>
    </ElDialog>

    <ElDialog v-model="runsVisible" :title="`${selected?.name ?? ''} · 执行历史`" width="900px">
      <ElTable :data="runs" max-height="520">
        <ElTableColumn label="状态" width="90"><template #default="{row}"><ElTag :type="runType(row.status)">{{runLabel(row.status)}}</ElTag></template></ElTableColumn>
        <ElTableColumn prop="trigger_type" label="触发" width="90" />
        <ElTableColumn label="计划时间" width="180"><template #default="{row}">{{formatTime(row.scheduled_for)}}</template></ElTableColumn>
        <ElTableColumn prop="attempts" label="尝试" width="70" />
        <ElTableColumn prop="error" label="错误" min-width="220" show-overflow-tooltip />
        <ElTableColumn label="结果" width="90"><template #default="{row}"><ElButton v-if="row.response" link type="primary" @click="inspectResponse(row)">查看</ElButton></template></ElTableColumn>
      </ElTable>
    </ElDialog>
    <ElDialog v-model="responseVisible" title="执行结果 JSON" width="760px"><pre class="max-h-[520px] overflow-auto rounded bg-black/5 p-4 text-xs">{{responseText}}</pre></ElDialog>
  </div>
</template>

<script setup lang="ts">
import { ElMessage, ElMessageBox } from 'element-plus'
import { fetchApplications, fetchNotificationChannels, type Application, type NotificationChannel } from '@/api/workbench'
import { fetchDigitalEmployees, fetchMCPServers, fetchSkills, type DigitalEmployee, type MCPServer, type Skill } from '@/api/marketplace'
import { createScheduledTask, deleteScheduledTask, fetchScheduledTaskRuns, fetchScheduledTasks, pauseScheduledTask, runScheduledTask, startScheduledTask, updateScheduledTask, type ScheduledTask, type ScheduledTaskInput, type ScheduledTaskRun } from '@/api/scheduled-tasks'

const loading=ref(false),saving=ref(false),visible=ref(false),runsVisible=ref(false),responseVisible=ref(false)
const editing=ref(''),items=ref<ScheduledTask[]>([]),runs=ref<ScheduledTaskRun[]>([]),selected=ref<ScheduledTask>()
const applications=ref<Application[]>([]),employees=ref<DigitalEmployee[]>([]),skills=ref<Skill[]>([]),mcpServers=ref<MCPServer[]>([]),channels=ref<NotificationChannel[]>([])
const variablesText=ref('{}'),responseText=ref('')
const blank=():ScheduledTaskInput=>({code:'',name:'',description:'',cron_expression:'0 9 * * 1-5',timezone:'Asia/Shanghai',target_type:'digital_employee',target_code:'',prompt:'',variables:{},skill_ids:[],mcp_server_ids:[],conversation_id:'',notification_channel_id:null,api_key:'',enabled:false})
const form=reactive<ScheduledTaskInput>(blank())
const targets=computed(()=>form.target_type==='application'?applications.value.filter(v=>v.status==='active'&&v.published_version):employees.value.filter(v=>v.enabled&&v.status==='published'))
const currentEmployee=computed(()=>employees.value.find(v=>v.code===form.target_code))
const availableSkills=computed(()=>skills.value.filter(v=>currentEmployee.value?.skill_ids.includes(v.id)))
const availableMCP=computed(()=>mcpServers.value.filter(v=>currentEmployee.value?.mcp_server_ids.includes(v.id)))
function targetChanged(){form.skill_ids=[];form.mcp_server_ids=[]}
function formatTime(v?:string){return v?new Date(v).toLocaleString():'-'}
function runType(s:string){return s==='success'?'success':s==='failed'?'danger':s==='running'?'warning':'info'}
function runLabel(s:string){return({success:'成功',failed:'失败',running:'执行中',pending:'排队中'} as Record<string,string>)[s]??s}
async function load(){loading.value=true;try{[items.value,applications.value,employees.value,skills.value,mcpServers.value,channels.value]=await Promise.all([fetchScheduledTasks(),fetchApplications(),fetchDigitalEmployees(),fetchSkills(),fetchMCPServers(),fetchNotificationChannels()])}finally{loading.value=false}}
function openCreate(){editing.value='';Object.assign(form,blank());variablesText.value='{}';visible.value=true}
function edit(row:ScheduledTask){editing.value=row.id;Object.assign(form,{code:row.code,name:row.name,description:row.description,cron_expression:row.cron_expression,timezone:row.timezone,target_type:row.target_type,target_code:row.target_code,prompt:row.prompt,variables:{...row.variables},skill_ids:[...row.skill_ids],mcp_server_ids:[...row.mcp_server_ids],conversation_id:row.conversation_id,notification_channel_id:row.notification_channel_id??null,api_key:'',enabled:row.enabled});variablesText.value=JSON.stringify(row.variables??{},null,2);visible.value=true}
async function save(){if(!form.code||!form.name||!form.target_code||!form.prompt)return ElMessage.warning('请填写必填项');let variables:Record<string,unknown>;try{variables=JSON.parse(variablesText.value||'{}')}catch{return ElMessage.warning('变量 JSON 格式无效')}if(Array.isArray(variables)||variables===null)return ElMessage.warning('变量必须是 JSON 对象');saving.value=true;try{const payload={...form,variables};editing.value?await updateScheduledTask(editing.value,payload):await createScheduledTask(payload);visible.value=false;ElMessage.success('任务已保存');await load()}finally{saving.value=false}}
async function toggle(row:ScheduledTask){row.enabled?await pauseScheduledTask(row.id):await startScheduledTask(row.id);await load()}
async function runNow(row:ScheduledTask){await runScheduledTask(row.id);ElMessage.success('已进入执行队列');setTimeout(()=>showRuns(row),800)}
async function showRuns(row:ScheduledTask){selected.value=row;runs.value=await fetchScheduledTaskRuns(row.id);runsVisible.value=true}
function inspectResponse(row:ScheduledTaskRun){responseText.value=JSON.stringify(row.response,null,2);responseVisible.value=true}
async function remove(row:ScheduledTask){await ElMessageBox.confirm(`删除任务“${row.name}”及全部执行历史？`,'确认删除',{type:'warning'});await deleteScheduledTask(row.id);await load()}
onMounted(load)
</script>
