<template>
  <el-dialog v-model="visibleProxy" title="Cron表达式生成器" width="900px" append-to-body destroy-on-close>
    <div class="cron-generator">
      <!-- 快捷选择 -->
      <div class="quick-select mb-6">
        <div class="section-title">快捷选择</div>
        <div class="quick-options">
          <el-button
            v-for="quick in quickOptions"
            :key="quick.name"
            size="small"
            :type="selectedQuick === quick.name ? 'primary' : 'default'"
            @click="applyQuickOption(quick)"
          >
            {{ quick.name }}
          </el-button>
        </div>
      </div>

      <!-- 详细配置 -->
      <div class="detail-config">
        <div class="section-title">详细配置</div>
        <el-tabs v-model="activeTab" @tab-click="handleTabClick">
          <!-- 秒 -->
          <el-tab-pane label="秒" name="second">
            <cron-field v-model="cronObj.second" :min="0" :max="59" field-name="秒" @change="updateCronExpression" />
          </el-tab-pane>

          <!-- 分 -->
          <el-tab-pane label="分" name="minute">
            <cron-field v-model="cronObj.minute" :min="0" :max="59" field-name="分" @change="updateCronExpression" />
          </el-tab-pane>

          <!-- 时 -->
          <el-tab-pane label="时" name="hour">
            <cron-field v-model="cronObj.hour" :min="0" :max="23" field-name="时" @change="updateCronExpression" />
          </el-tab-pane>

          <!-- 日 -->
          <el-tab-pane label="日" name="day">
            <cron-field v-model="cronObj.day" :min="1" :max="31" field-name="日" :has-last="true" @change="updateCronExpression" />
          </el-tab-pane>

          <!-- 月 -->
          <el-tab-pane label="月" name="month">
            <cron-field
              v-model="cronObj.month"
              :min="1"
              :max="12"
              field-name="月"
              :has-last="true"
              :custom-options="monthOptions"
              @change="updateCronExpression"
            />
          </el-tab-pane>

          <!-- 周 -->
          <el-tab-pane label="周" name="week">
            <cron-field
              v-model="cronObj.week"
              :min="1"
              :max="7"
              field-name="周"
              :has-last="true"
              :custom-options="weekOptions"
              @change="updateCronExpression"
            />
          </el-tab-pane>

          <!-- 年（可选） -->
          <el-tab-pane label="年" name="year">
            <cron-field v-model="cronObj.year" :min="1970" :max="2099" field-name="年" :is-year="true" @change="updateCronExpression" />
          </el-tab-pane>
        </el-tabs>
      </div>

      <!-- 表达式预览 -->
      <div class="expression-preview mt-6">
        <div class="section-title">表达式预览</div>
        <div class="preview-content">
          <el-input v-model="cronExpression" readonly size="large">
            <template #prepend>Cron表达式</template>
            <template #append>
              <el-button icon="CopyDocument" @click="copyExpression">复制</el-button>
            </template>
          </el-input>
        </div>
      </div>

      <!-- 执行时间预览 -->
      <div class="execution-preview mt-4">
        <div class="section-title">执行时间预览</div>
        <div class="preview-times">
          <el-tag v-for="(time, index) in previewTimes" :key="index" class="time-tag">
            {{ time }}
          </el-tag>
          <div v-if="previewTimes.length === 0" class="no-times">暂无执行时间预览</div>
        </div>
      </div>

      <!-- 表达式说明 -->
      <div class="expression-help mt-4">
        <el-collapse>
          <el-collapse-item title="Cron表达式说明" name="help">
            <div class="help-content">
              <div class="help-section">
                <h4>表达式格式</h4>
                <p>Cron表达式是一个字符串，包含6或7个时间字段，用空格分隔：</p>
                <p><code>秒 分 时 日 月 周 [年]</code></p>
              </div>

              <div class="help-section">
                <h4>字段说明</h4>
                <el-table :data="fieldHelp" size="small" border>
                  <el-table-column prop="field" label="字段" width="80" />
                  <el-table-column prop="range" label="取值范围" width="120" />
                  <el-table-column prop="special" label="特殊字符" />
                </el-table>
              </div>

              <div class="help-section">
                <h4>特殊字符说明</h4>
                <ul>
                  <li><strong>*</strong> - 匹配所有值</li>
                  <li><strong>?</strong> - 用于日和周字段，表示不指定值</li>
                  <li><strong>-</strong> - 表示范围，如1-5表示1到5</li>
                  <li><strong>,</strong> - 表示列举，如1,3,5表示1或3或5</li>
                  <li><strong>/</strong> - 表示增量，如*/5表示每5个单位</li>
                  <li><strong>L</strong> - 表示最后，用于日和周字段</li>
                  <li><strong>W</strong> - 表示工作日，用于日字段</li>
                  <li><strong>#</strong> - 表示第几个，用于周字段，如6#3表示第3个周五</li>
                </ul>
              </div>
            </div>
          </el-collapse-item>
        </el-collapse>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="confirmExpression">确定</el-button>
        <el-button @click="cancel">取消</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { nextTriggerTime } from '@/api/xxljob/job';
import CronField from './CronField.vue';

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  modelValue: {
    type: String,
    default: ''
  }
});

const emit = defineEmits(['update:visible', 'update:modelValue', 'confirm']);

// 可见性双向绑定
const visibleProxy = computed({
  get: () => props.visible,
  set: (val) => emit('update:visible', val)
});

const activeTab = ref('second');
const selectedQuick = ref('');
const cronExpression = ref('0 0 0 * * ?');
const previewTimes = ref<string[]>([]);

// Cron对象
const cronObj = ref({
  second: { type: 'every', value: '*' },
  minute: { type: 'every', value: '*' },
  hour: { type: 'every', value: '*' },
  day: { type: 'every', value: '*' },
  month: { type: 'every', value: '*' },
  week: { type: 'unset', value: '?' },
  year: { type: 'every', value: '*' }
});

// 快捷选项
const quickOptions = [
  {
    name: '每秒执行',
    cron: '* * * * * ?',
    obj: {
      second: { type: 'every', value: '*' },
      minute: { type: 'every', value: '*' },
      hour: { type: 'every', value: '*' },
      day: { type: 'every', value: '*' },
      month: { type: 'every', value: '*' },
      week: { type: 'unset', value: '?' },
      year: { type: 'every', value: '*' }
    }
  },
  {
    name: '每分钟执行',
    cron: '0 * * * * ?',
    obj: {
      second: { type: 'specify', value: '0' },
      minute: { type: 'every', value: '*' },
      hour: { type: 'every', value: '*' },
      day: { type: 'every', value: '*' },
      month: { type: 'every', value: '*' },
      week: { type: 'unset', value: '?' },
      year: { type: 'every', value: '*' }
    }
  },
  {
    name: '每小时执行',
    cron: '0 0 * * * ?',
    obj: {
      second: { type: 'specify', value: '0' },
      minute: { type: 'specify', value: '0' },
      hour: { type: 'every', value: '*' },
      day: { type: 'every', value: '*' },
      month: { type: 'every', value: '*' },
      week: { type: 'unset', value: '?' },
      year: { type: 'every', value: '*' }
    }
  },
  {
    name: '每天执行',
    cron: '0 0 0 * * ?',
    obj: {
      second: { type: 'specify', value: '0' },
      minute: { type: 'specify', value: '0' },
      hour: { type: 'specify', value: '0' },
      day: { type: 'every', value: '*' },
      month: { type: 'every', value: '*' },
      week: { type: 'unset', value: '?' },
      year: { type: 'every', value: '*' }
    }
  },
  {
    name: '每周执行',
    cron: '0 0 0 ? * 1',
    obj: {
      second: { type: 'specify', value: '0' },
      minute: { type: 'specify', value: '0' },
      hour: { type: 'specify', value: '0' },
      day: { type: 'unset', value: '?' },
      month: { type: 'every', value: '*' },
      week: { type: 'specify', value: '1' },
      year: { type: 'every', value: '*' }
    }
  },
  {
    name: '每月执行',
    cron: '0 0 0 1 * ?',
    obj: {
      second: { type: 'specify', value: '0' },
      minute: { type: 'specify', value: '0' },
      hour: { type: 'specify', value: '0' },
      day: { type: 'specify', value: '1' },
      month: { type: 'every', value: '*' },
      week: { type: 'unset', value: '?' },
      year: { type: 'every', value: '*' }
    }
  }
];

// 月份选项
const monthOptions = [
  { label: '一月', value: '1' },
  { label: '二月', value: '2' },
  { label: '三月', value: '3' },
  { label: '四月', value: '4' },
  { label: '五月', value: '5' },
  { label: '六月', value: '6' },
  { label: '七月', value: '7' },
  { label: '八月', value: '8' },
  { label: '九月', value: '9' },
  { label: '十月', value: '10' },
  { label: '十一月', value: '11' },
  { label: '十二月', value: '12' }
];

// 星期选项
const weekOptions = [
  { label: '周日', value: '1' },
  { label: '周一', value: '2' },
  { label: '周二', value: '3' },
  { label: '周三', value: '4' },
  { label: '周四', value: '5' },
  { label: '周五', value: '6' },
  { label: '周六', value: '7' }
];

// 字段帮助
const fieldHelp = [
  { field: '秒', range: '0-59', special: ', - * /' },
  { field: '分', range: '0-59', special: ', - * /' },
  { field: '时', range: '0-23', special: ', - * /' },
  { field: '日', range: '1-31', special: ', - * / ? L W' },
  { field: '月', range: '1-12', special: ', - * /' },
  { field: '周', range: '1-7', special: ', - * / ? L #' },
  { field: '年', range: '1970-2099', special: ', - * /' }
];

/** 应用快捷选项 */
const applyQuickOption = (quick: any) => {
  selectedQuick.value = quick.name;
  cronObj.value = { ...quick.obj };
  cronExpression.value = quick.cron;
  updatePreviewTimes();
};

/** 处理标签页点击 */
const handleTabClick = () => {
  selectedQuick.value = '';
};

/** 更新Cron表达式 */
const updateCronExpression = () => {
  selectedQuick.value = '';

  const parts = [
    cronObj.value.second.value,
    cronObj.value.minute.value,
    cronObj.value.hour.value,
    cronObj.value.day.value,
    cronObj.value.month.value,
    cronObj.value.week.value
  ];

  // 如果设置了年份且不是*，则添加年份
  if (cronObj.value.year.value !== '*') {
    parts.push(cronObj.value.year.value);
  }

  cronExpression.value = parts.join(' ');
  updatePreviewTimes();
};

/** 更新预览时间 */
const updatePreviewTimes = async () => {
  try {
    if (cronExpression.value) {
      const res = await nextTriggerTime('CRON', cronExpression.value);
      previewTimes.value = res.data || [];
    }
  } catch (error) {
    previewTimes.value = [];
  }
};

/** 复制表达式 */
const copyExpression = async () => {
  try {
    await navigator.clipboard.writeText(cronExpression.value);
    ElMessage.success('已复制到剪贴板');
  } catch (error) {
    ElMessage.error('复制失败');
  }
};

/** 确认表达式 */
const confirmExpression = () => {
  emit('update:modelValue', cronExpression.value);
  emit('confirm', cronExpression.value);
  visibleProxy.value = false;
};

/** 取消 */
const cancel = () => {
  visibleProxy.value = false;
};

// 监听props变化
watch(
  () => props.visible,
  (visible) => {
    if (visible && props.modelValue) {
      cronExpression.value = props.modelValue;
      // 可以在这里解析现有的Cron表达式到cronObj
      updatePreviewTimes();
    }
  }
);

// 组件挂载时初始化
onMounted(() => {
  if (props.modelValue) {
    cronExpression.value = props.modelValue;
    updatePreviewTimes();
  }
});
</script>

<style scoped>
.cron-generator {
  padding: 0 8px;
}

.section-title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 16px;
  padding-left: 8px;
  border-left: 4px solid #409eff;
}

.quick-options {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.quick-options .el-button {
  margin: 0;
}

.preview-content {
  margin-top: 8px;
}

.preview-times {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
  padding: 12px;
  background-color: #f8f9fa;
  border-radius: 6px;
  min-height: 60px;
}

.time-tag {
  margin: 0;
}

.no-times {
  color: #909399;
  font-size: 14px;
  width: 100%;
  text-align: center;
  line-height: 36px;
}

.help-content {
  line-height: 1.6;
}

.help-section {
  margin-bottom: 20px;
}

.help-section h4 {
  margin: 0 0 8px 0;
  color: #303133;
  font-size: 14px;
  font-weight: 600;
}

.help-section p {
  margin: 4px 0;
  color: #606266;
}

.help-section code {
  background-color: #f4f4f5;
  padding: 2px 6px;
  border-radius: 3px;
  font-family: 'Monaco', 'Consolas', monospace;
  font-size: 12px;
}

.help-section ul {
  margin: 8px 0;
  padding-left: 20px;
}

.help-section li {
  margin: 4px 0;
  color: #606266;
}

.dialog-footer {
  text-align: center;
}
</style>
