<template>
  <el-form 
    ref="formRef"
    :model="form" 
    :rules="rules" 
    label-width="120px"
    v-loading="loading"
  >
    <el-form-item label="项目名称" prop="project">
      <el-select
        v-model="form.project"
        placeholder="请选择项目"
        clearable
        filterable
        style="width: 100%"
        @change="handleProjectChange"
      >
        <el-option
          v-for="item in projectOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
    </el-form-item>

    <el-form-item label="爬虫名称" prop="spider">
      <el-select
        v-model="form.spider"
        placeholder="请选择爬虫"
        clearable
        filterable
        style="width: 100%"
      >
        <el-option
          v-for="item in spiderOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
    </el-form-item>

    <el-form-item label="Cron表达式" prop="cron">
      <el-input
        v-model="form.cron"
        placeholder="例如: */5 * * * *"
      >
        <template #append>
          <el-popover
            placement="bottom"
            title="Cron表达式帮助"
            :width="300"
            trigger="click"
          >
            <template #reference>
              <el-button>帮助</el-button>
            </template>
            <div>
              <p>Cron表达式格式：分 时 日 月 周</p>
              <p>示例：</p>
              <ul>
                <li>每5分钟：*/5 * * * *</li>
                <li>每小时：0 * * * *</li>
                <li>每天凌晨1点：0 1 * * *</li>
                <li>每周一3点：0 3 * * 1</li>
                <li>每月1号零点：0 0 1 * *</li>
              </ul>
            </div>
          </el-popover>
        </template>
      </el-input>
    </el-form-item>

    <el-form-item label="调度服务器" prop="schedule_type">
      <el-radio-group v-model="form.schedule_type">
        <el-radio
          v-for="item in scheduleTypeOptions"
          :key="item.value"
          :label="item.value"
        >{{ item.label }}</el-radio>
      </el-radio-group>
    </el-form-item>

    <el-form-item label="选择服务器" prop="scrapyd_server_id" v-if="form.schedule_type === ScheduleTypeEnum.ONLY_ONE_SERVER">
      <el-select
        v-model="form.scrapyd_server_id"
        placeholder="请选择服务器"
        clearable
        filterable
        style="width: 100%"
      >
        <el-option
          v-for="item in serverOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
    </el-form-item>

    <el-form-item label="爬虫参数" prop="options">
      <el-input
        v-model="form.options"
        type="textarea"
        :rows="4"
        placeholder='{"param1": "value1", "param2": "value2"}'
      />
    </el-form-item>

    <el-form-item>
      <el-button 
        type="primary" 
        @click="submitForm"
        :loading="submitting"
      >
        确认
      </el-button>
      <el-button @click="cancelForm">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted, watch } from 'vue'
import { ElMessage } from 'element-plus'
import type { FormInstance } from 'element-plus'
import * as scheduleApi from '@/api/schedule'
import * as projectApi from '@/api/project'
import { ScheduleTypeOptions, ScheduleTypeEnum } from '@/enums/schedule-type-enum'
import type { QueryParams } from '@/utils/request'

const props = defineProps({
  job_id: {
    type: String,
    default: ''
  },
  scrapydServerId: {
    type: String,
    default: ''
  },
  project: {
    type: String,
    default: ''
  },
  spider: {
    type: String,
    default: ''
  }
})

const emit = defineEmits(['on-success', 'on-cancel'])

const formRef = ref<FormInstance>()
const loading = ref(false)
const submitting = ref(false)


interface OptionType {
    label: string
    value: string
}
const projectOptions = ref<OptionType[]>([])
const spiderOptions = ref<OptionType[]>([])
const serverOptions = ref<OptionType[]>([])
const scheduleTypeOptions = ref(ScheduleTypeOptions)

const form = reactive({
  project: props.project || '',
  spider: props.spider || '',
  cron: '*/5 * * * *', // 默认每5分钟执行一次
  schedule_type: ScheduleTypeEnum.ONLY_ONE_SERVER,
  scrapyd_server_id: props.scrapydServerId || '',
  options: '{}'
})

const rules = reactive({
  project: [
    { required: true, message: '请选择项目', trigger: 'change' }
  ],
  spider: [
    { required: true, message: '请选择爬虫', trigger: 'change' }
  ],
  cron: [
    { required: true, message: '请输入Cron表达式', trigger: 'blur' }
  ],
  schedule_type: [
    { required: true, message: '请选择调度方式', trigger: 'change' }
  ],
  scrapyd_server_id: [
    { 
      required: true, 
      message: '请选择服务器', 
      trigger: 'change',
      validator: (_rule: any, value: any, callback: any) => {
        if (form.schedule_type === ScheduleTypeEnum.ONLY_ONE_SERVER && !value) {
          callback(new Error('请选择服务器'))
        } else {
          callback()
        }
      }
    }
  ]
})

// 初始化数据
const initData = async () => {
  loading.value = true
  try {
    // 获取项目列表
    await getProjects()
    
    // 获取服务器列表
    await getScrapydServers()
    
    // 如果有job_id，则获取任务详情
    if (props.job_id) {
      await getJobDetail()
    }
    
    // 如果有项目名，则获取爬虫列表
    if (form.project) {
      await getSpiders()
    }
  } catch (error) {
    console.error('初始化数据失败:', error)
  } finally {
    loading.value = false
  }
}

// 获取项目列表
const getProjects = async () => {
  try {
    const scrapyd_server_id = localStorage.getItem('scrapyd_server_id')
    const res = await projectApi.getProjectList({ scrapydServerId: scrapyd_server_id! })
    if (res.code === 0) {
      projectOptions.value = res.data.map((item: any) => ({
        label: item.name,
        value: item.name
      }))
    }
  } catch (error) {
    console.error('获取项目列表失败:', error)
  }
}

// 获取爬虫列表
const getSpiders = async () => {
  if (!form.project) return
  
  try {
    const res = await projectApi.getSpiders({ project: form.project, scrapydServerId: localStorage.getItem('scrapyd_server_id')! })
    if (res.code === 0 && Array.isArray(res.data)) {
      spiderOptions.value = res.data.map((item: string) => ({
        label: item,
        value: item
      }))
    }
  } catch (error) {
    console.error('获取爬虫列表失败:', error)
  }
}

// 获取服务器列表
const getScrapydServers = async () => {
  try {
    const res = await scheduleApi.getScrapydServerPage()
    if (res.code === 0) {
      serverOptions.value = res.data.list.map((item: any) => ({
        label: item.server_name,
        value: item.id
      }))
    }
  } catch (error) {
    console.error('获取服务器列表失败:', error)
  }
}

// 获取任务详情
const getJobDetail = async () => {
  try {
    const res = await scheduleApi.getJobDetail({ job_id: props.job_id, scrapydServerId: localStorage.getItem('scrapyd_server_id')! })
    if (res.code === 0) {
      const jobData = res.data
      form.project = jobData.kwargs.project || ''
      form.spider = jobData.kwargs.spider || ''
      form.cron = jobData.kwargs.cron || ''
      form.schedule_type = jobData.kwargs.schedule_type || ScheduleTypeEnum.ONLY_ONE_SERVER
      form.scrapyd_server_id = jobData.kwargs.scrapyd_server_id || ''
      form.options = jobData.kwargs.options ? JSON.stringify(jobData.kwargs.options) : '{}'
    }
  } catch (error) {
    console.error('获取任务详情失败:', error)
  }
}

// 项目变更时获取对应的爬虫
const handleProjectChange = async () => {
  form.spider = ''
  await getSpiders()
}

// 提交表单
const submitForm = async () => {
  if (!formRef.value) return
  
  await formRef.value.validate(async (valid) => {
    if (valid) {
      submitting.value = true
      try {
        let options = {}
        try {
          options = JSON.parse(form.options)
        } catch (e) {
          ElMessage.error('爬虫参数格式错误，请检查JSON格式')
          submitting.value = false
          return
        }
        
        const params: QueryParams = {
          project: form.project,
          spider: form.spider,
          cron: form.cron,
          schedule_type: form.schedule_type,
          scrapydServerId: form.scrapyd_server_id,
          options
        }
        
        if (form.schedule_type === ScheduleTypeEnum.ONLY_ONE_SERVER) {
          params.scrapyd_server_id = form.scrapyd_server_id
        }
        
        if (props.job_id) {
          params.job_id = props.job_id
        }
        
        const res = await scheduleApi.addJob(params)
        if (res.code === 0) {
          ElMessage({
            type: 'success',
            message: props.job_id ? '修改成功!' : '添加成功!'
          })
          emit('on-success')
        }
      } catch (error) {
        console.error(props.job_id ? '修改任务失败:' : '添加任务失败:', error)
      } finally {
        submitting.value = false
      }
    }
  })
}

// 取消表单
const cancelForm = () => {
  emit('on-cancel')
}

// 监听项目变化
watch(() => form.project, async (newVal) => {
  if (newVal) {
    await getSpiders()
  }
})

onMounted(() => {
  initData()
})
</script>

<style lang="scss" scoped>
</style>
