<template>
  <el-tabs v-model="tab">
    <el-tab-pane label="CRON表达式" name="cron">
      <div style="margin-bottom: 10px;">
        <el-input v-model="cronStr" readonly style="width: 400px; font-weight: bold;" :key="'cronStr'" />
      </div>
      <div style="display: flex; gap: 8px; margin-bottom: 8px;">
        <el-input v-model="fields.second" placeholder="秒" style="width: 80px;" :key="'second'" />
        <el-input v-model="fields.minute" placeholder="分" style="width: 80px;" :key="'minute'" />
        <el-input v-model="fields.hour" placeholder="时" style="width: 80px;" :key="'hour'" />
        <el-input v-model="fields.day" placeholder="天" style="width: 80px;" :key="'day'" />
        <el-input v-model="fields.month" placeholder="月" style="width: 80px;" :key="'month'" />
        <el-input v-model="fields.week" placeholder="周" style="width: 80px;" :key="'week'" />
        <el-input v-model="fields.year" placeholder="年" style="width: 80px;" :key="'year'" />
      </div>
      <el-tabs v-model="activeField" type="card" style="margin-bottom: 8px;">
        <el-tab-pane v-for="f in cronFieldList" :label="f.label" :name="f.key" :key="f.key">
          <div style="margin-bottom: 8px;">
            <el-radio-group v-model="cronMode[f.key]" :key="'radio-'+f.key">
              <el-radio label="every" :key="'every-'+f.key">每{{f.label}}</el-radio>
              <el-radio label="range" :key="'range-'+f.key">从 <el-input-number v-model="cronRange[f.key][0]" :min="f.min" :max="f.max" size="small" style="width:60px" :key="'range0-'+f.key" /> 到 <el-input-number v-model="cronRange[f.key][1]" :min="f.min" :max="f.max" size="small" style="width:60px" :key="'range1-'+f.key" /> 之间每{{f.label}}</el-radio>
              <el-radio label="step" :key="'step-'+f.key">从第 <el-input-number v-model="cronStep[f.key][0]" :min="f.min" :max="f.max" size="small" style="width:60px" :key="'step0-'+f.key" /> 开始每 <el-input-number v-model="cronStep[f.key][1]" :min="1" :max="f.max" size="small" style="width:60px" :key="'step1-'+f.key" /> {{f.label}}</el-radio>
              <el-radio label="appoint" :key="'appoint-'+f.key">指定</el-radio>
            </el-radio-group>
          </div>
          <div v-if="cronMode[f.key]==='appoint'">
            <el-checkbox-group v-model="cronAppoint[f.key]" :key="'group-'+f.key">
              <el-checkbox v-for="n in f.max+1" :label="pad(n-1)" :key="'cb-'+f.key+'-'+(n-1)">{{pad(n-1)}}</el-checkbox>
            </el-checkbox-group>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-tab-pane>
    <el-tab-pane label="标准格式" name="iso" :key="'iso-tab'">
      <div style="margin-bottom: 10px;">
        <el-input v-model="isoStr" placeholder="如R1/2025-05-21T21:59:54/P3DT30M30S" style="width: 400px; font-weight: bold;" :key="'isoStr'" />
      </div>
      <div style="margin-bottom: 10px;">循环次数：<el-input-number v-model="repeat" :min="1" style="width: 100px;" :key="'repeat'" /></div>
      <div style="margin-bottom: 10px;">日期时间：<el-date-picker v-model="isoDate" type="datetime" placeholder="选择日期时间" style="width: 200px;" :key="'isoDate'" /></div>
      <div style="margin-bottom: 10px;">当前时长：<el-input v-model="isoDuration" placeholder="如P3DT30M30S" style="width: 200px;" :key="'isoDuration'" /></div>
      <div>
        <div>秒：<el-button v-for="s in [5,10,30,50]" @click="setDuration('S',s)" :key="'sec-'+s">{{s}}</el-button>自定义</div>
        <div>分：<el-button v-for="m in [5,10,30,50]" @click="setDuration('M',m)" :key="'min-'+m">{{m}}</el-button>自定义</div>
        <div>小时：<el-button v-for="h in [4,8,12,24]" @click="setDuration('H',h)" :key="'hour-'+h">{{h}}</el-button>自定义</div>
        <div>天：<el-button v-for="d in [1,2,3,4]" @click="setDuration('D',d)" :key="'day-'+d">{{d}}</el-button>自定义</div>
        <div>月：<el-button v-for="mo in [1,2,3,4]" @click="setDuration('M',mo)" :key="'mon-'+mo">{{mo}}</el-button>自定义</div>
        <div>年：<el-button v-for="y in [1,2,3,4]" @click="setDuration('Y',y)" :key="'year-'+y">{{y}}</el-button>自定义</div>
      </div>
    </el-tab-pane>
  </el-tabs>
</template>
<script setup>
import { ref, watch, computed } from 'vue'
const props = defineProps({ value: String })
const emit = defineEmits(['change'])

const tab = ref('cron')
const cronStr = ref(props.value || '* * * * * ?')
const fields = ref({ second: '*', minute: '*', hour: '*', day: '*', month: '*', week: '?', year: '' })
const cronFieldList = [
  { key: 'second', label: '秒', min: 0, max: 59 },
  { key: 'minute', label: '分', min: 0, max: 59 },
  { key: 'hour', label: '时', min: 0, max: 23 },
  { key: 'day', label: '天', min: 1, max: 31 },
  { key: 'month', label: '月', min: 1, max: 12 },
  { key: 'week', label: '周', min: 1, max: 7 },
  { key: 'year', label: '年', min: 1970, max: 2099 }
]
const activeField = ref('second')
const cronMode = ref({ second: 'appoint', minute: 'every', hour: 'every', day: 'every', month: 'every', week: 'every', year: 'every' })
const cronAppoint = ref({ second: ['00','01'], minute: [], hour: [], day: [], month: [], week: [], year: [] })
const cronRange = ref({ second: [0,1], minute: [0,1], hour: [0,1], day: [1,2], month: [1,2], week: [1,2], year: [1970,1971] })
const cronStep = ref({ second: [1,1], minute: [1,1], hour: [1,1], day: [1,1], month: [1,1], week: [1,1], year: [1970,1] })

function pad(n) { return n<10 ? '0'+n : ''+n }

watch([fields, cronMode, cronAppoint, cronRange, cronStep], () => {
  // 组装cron表达式
  let arr = cronFieldList.map(f => {
    if (cronMode.value[f.key]==='every') return '*'
    if (cronMode.value[f.key]==='appoint') return cronAppoint.value[f.key].join(',') || '*'
    if (cronMode.value[f.key]==='range') return `${cronRange.value[f.key][0]}-${cronRange.value[f.key][1]}`
    if (cronMode.value[f.key]==='step') return `${cronStep.value[f.key][0]}/${cronStep.value[f.key][1]}`
    return fields.value[f.key] || '*'
  })
  // week和year特殊处理
  arr[5] = arr[5] || '?'
  cronStr.value = arr.join(' ')
  if (tab.value==='cron') emit('change', cronStr.value)
}, { deep: true })

// 标准格式
const isoStr = ref('')
const repeat = ref(1)
const isoDate = ref('')
const isoDuration = ref('')
function setDuration(type, val) {
  // 组装ISO 8601字符串
  let d = isoDuration.value
  if (!d.includes(type)) d += val + type
  else d = d.replace(new RegExp(`\\d+${type}`), val + type)
  isoDuration.value = d
  updateIsoStr()
}
function updateIsoStr() {
  let str = `R${repeat.value}`
  if (isoDate.value) str += '/' + (typeof isoDate.value==='string'?isoDate.value:new Date(isoDate.value).toISOString())
  if (isoDuration.value) str += '/' + isoDuration.value
  isoStr.value = str
  if (tab.value==='iso') emit('change', isoStr.value)
}
watch([repeat, isoDate, isoDuration], updateIsoStr)
watch(() => props.value, (val) => {
  if (!val) return
  if (tab.value==='cron') cronStr.value = val
  if (tab.value==='iso') isoStr.value = val
}, { immediate: true })
</script> 