{% extends "service_monitor/base.html" %}
{% block title %}定时任务{% endblock %}

{% block extra_css %}
<style>
    /* 表格（8 列：新增"上次执行"） */
    .table { background: #fff; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,.06); border: 1px solid var(--gray-200); overflow: hidden; }
    .table-head, .table-row { display: grid; grid-template-columns: 2fr 1.1fr 0.9fr 1.4fr 0.9fr 1.3fr 1.2fr 1.6fr; gap: 10px; padding: 12px 16px; align-items: center; }
    .table-head { background: var(--gray-50); font-size: 13px; color: var(--gray-500); font-weight: 600; border-bottom: 1px solid var(--gray-200); }
    .table-row { border-bottom: 1px solid var(--gray-100); font-size: 14px; }
    .table-row:last-child { border-bottom: none; }
    .name { font-weight: 600; color: var(--gray-900); }
    .schedule-desc { color: var(--gray-700); font-size: 13px; }
    .schedule-desc .date-range { color: var(--gray-500); font-size: 12px; }

    /* 状态徽章（启用/禁用） */
    .status-badge { font-size: 12px; padding: 3px 10px; border-radius: 6px; font-weight: 600; }
    .badge-enabled { background: #dcfce7; color: #15803d; }
    .badge-disabled { background: var(--gray-100); color: var(--gray-500); }

    /* 执行状态徽章 */
    .badge-running { background: #dbeafe; color: #1d4ed8; }
    .badge-success { background: #dcfce7; color: #15803d; }
    .badge-failed, .badge-error { background: #fee2e2; color: #dc2626; }
    .badge-idle { background: var(--gray-100); color: var(--gray-500); }

    /* 上次执行单元格 */
    .last-run { display: flex; flex-direction: column; gap: 3px; }
    .last-run-time { font-size: 12px; color: var(--gray-700); }
    .last-run-actions { display: flex; align-items: center; gap: 6px; }
    .report-link { font-size: 12px; color: var(--primary); text-decoration: none; }
    .report-link:hover { text-decoration: underline; }

    .actions { display: flex; gap: 6px; flex-wrap: wrap; }
    .btn-sm { padding: 5px 10px; border-radius: 6px; font-size: 12px; font-weight: 600; cursor: pointer; border: none; text-decoration: none; display: inline-block; }
    .btn-run { background: #dbeafe; color: #1d4ed8; }
    .btn-toggle { background: #fef3c7; color: #92400e; }
    .btn-edit { background: var(--gray-100); color: var(--gray-700); }
    .btn-del { background: #fee2e2; color: var(--red); }

    /* 弹窗 */
    .modal-mask { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.4); z-index: 200; align-items: center; justify-content: center; padding: 20px; }
    .modal-mask.show { display: flex; }
    .modal { background: #fff; border-radius: 14px; padding: 28px; width: 100%; max-width: 520px; max-height: 90vh; overflow-y: auto; }
    .modal h3 { font-size: 18px; color: var(--gray-900); margin-bottom: 18px; }
    .form-group { margin-bottom: 14px; }
    .form-group label { display: block; font-size: 13px; color: var(--gray-700); margin-bottom: 5px; font-weight: 600; }
    .form-group input, .form-group select { width: 100%; padding: 9px 12px; border: 1px solid var(--gray-200); border-radius: 8px; font-size: 14px; }
    .form-group input:focus, .form-group select:focus { outline: none; border-color: var(--primary); }
    .form-hint { font-size: 12px; color: var(--gray-500); margin-top: 4px; }

    /* 重复周期单选组 */
    .repeat-group { display: flex; gap: 8px; }
    .repeat-btn { flex: 1; padding: 10px 0; text-align: center; border: 2px solid var(--gray-200); border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 600; color: var(--gray-600); background: #fff; transition: all .15s; }
    .repeat-btn:hover { border-color: var(--primary); color: var(--primary); }
    .repeat-btn.active { border-color: var(--primary); background: var(--primary); color: #fff; }

    /* 时间选择器 */
    .time-picker { display: flex; align-items: center; gap: 6px; }
    .time-picker select { width: 80px; padding: 9px 8px; border: 1px solid var(--gray-200); border-radius: 8px; font-size: 14px; text-align: center; }
    .time-picker select:focus { outline: none; border-color: var(--primary); }
    .time-sep { font-size: 18px; font-weight: 700; color: var(--gray-400); }

    /* 星期多选按钮 */
    .weekday-group { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
    .weekday-btn { width: 44px; height: 36px; display: flex; align-items: center; justify-content: center; border: 2px solid var(--gray-200); border-radius: 8px; cursor: pointer; font-size: 13px; font-weight: 600; color: var(--gray-600); background: #fff; transition: all .15s; }
    .weekday-btn:hover { border-color: var(--primary); color: var(--primary); }
    .weekday-btn.active { border-color: var(--primary); background: var(--primary); color: #fff; }

    /* 日期行 */
    .date-row { display: flex; gap: 12px; }
    .date-row .form-group { flex: 1; margin-bottom: 0; }
    .date-section { margin-bottom: 14px; }
    .date-section > label { display: block; font-size: 13px; color: var(--gray-700); margin-bottom: 5px; font-weight: 600; }

    .modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px; }
    .btn-cancel { background: var(--gray-100); color: var(--gray-700); border: none; padding: 9px 18px; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 600; }
    .btn-save { background: var(--primary); color: #fff; border: none; padding: 9px 18px; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 600; }
    .btn-save:disabled { opacity: .6; cursor: not-allowed; }

    @media screen and (max-width: 1024px) {
        .table-head, .table-row { grid-template-columns: 1fr 1fr 1fr 1.2fr; }
        /* 隐藏：套件(3)、启用(5)、上次执行(6)、下次执行(7) */
        .table-head span:nth-child(3), .table-head span:nth-child(5), .table-head span:nth-child(6), .table-head span:nth-child(7),
        .table-row > span:nth-child(3), .table-row > span:nth-child(5), .table-row > span:nth-child(6), .table-row > span:nth-child(7) { display: none; }
    }
    @media screen and (max-width: 768px) {
        .table-head { display: none; }
        .table-row {
            grid-template-columns: 1fr 1fr;
            gap: 6px; padding: 14px;
            border-bottom: 2px solid var(--gray-200);
        }
        .table-row .name { font-size: 15px; }
        .schedule-desc { font-size: 12px; }
        .actions { flex-wrap: wrap; gap: 4px; }
        .btn-sm { padding: 4px 8px; font-size: 11px; }
        .modal { padding: 16px; max-width: 100%; border-radius: 12px; }
        .modal h3 { font-size: 16px; }
        .repeat-group { flex-direction: column; gap: 6px; }
        .repeat-btn { padding: 8px 0; font-size: 13px; }
        .date-row { flex-direction: column; gap: 0; }
        .date-row .form-group { margin-bottom: 14px; }
        .time-picker select { width: 70px; padding: 8px 6px; font-size: 13px; }
        .weekday-btn { width: 38px; height: 32px; font-size: 12px; }
        .section-head { flex-direction: column; align-items: flex-start; gap: 10px; }
        .btn-add { width: 100%; text-align: center; }
    }
    @media screen and (max-width: 480px) {
        .table-row { padding: 12px; gap: 4px; }
        .table-row .name { font-size: 14px; }
        .schedule-desc { font-size: 11px; }
        .actions { gap: 3px; }
        .btn-sm { padding: 3px 6px; font-size: 10px; }
        .modal { padding: 14px; }
        .modal h3 { font-size: 15px; }
        .form-group input, .form-group select { padding: 7px 10px; font-size: 13px; }
        .repeat-btn { padding: 7px 0; font-size: 12px; }
        .weekday-btn { width: 36px; height: 30px; font-size: 11px; }
        .time-picker select { width: 60px; padding: 6px 4px; font-size: 12px; }
        .btn-cancel, .btn-save { padding: 7px 14px; font-size: 13px; }
        .section-title { font-size: 15px; }
        .btn-add { font-size: 12px; padding: 7px 12px; }
    }
</style>
{% endblock %}

{% block content %}
<div class="section-head">
    <div class="section-title">⏰ 定时任务</div>
    {% if is_admin %}
    <button class="btn-add" onclick="openCreate()">+ 新增定时任务</button>
    {% endif %}
</div>

{% if schedules %}
<div class="table">
    <div class="table-head">
        <span>任务名称</span>
        <span>目标</span>
        <span>套件</span>
        <span>调度周期</span>
        <span>启用</span>
        <span>上次执行</span>
        <span>下次执行</span>
        <span>操作</span>
    </div>
    {% for s in schedules %}
    <div class="table-row" data-id="{{ s.id }}" data-schedule='{{ s | tojson | safe }}'>
        <span class="name">{{ s.name }}</span>
        <span>{{ s.target_name or s.target_id }}</span>
        <span>{{ '快速' if s.suite == 'quick' else '全量' }}</span>
        <span class="schedule-desc">{{ s.description or s.cron }}</span>
        <span><span class="status-badge {{ 'badge-enabled' if s.enabled else 'badge-disabled' }}">{{ '启用' if s.enabled else '禁用' }}</span></span>
        <span class="last-run">
            {% if s.last_run_at %}
            <span class="last-run-time">{{ s.last_run_at[:16].replace('T', ' ') }}</span>
            <div class="last-run-actions">
                <span class="status-badge {{ s.run_badge }}">{{ s.run_label }}</span>
                {% if s.last_report_id %}
                <a class="report-link" href="/service-monitor/report/{{ s.last_report_id }}">报告</a>
                {% endif %}
            </div>
            {% else %}
            <span class="last-run-time" style="color: var(--gray-400);">未执行</span>
            {% endif %}
        </span>
        <span>{{ s.next_run_at[:16].replace('T', ' ') if s.next_run_at else '-' }}</span>
        <div class="actions">
            {% if is_admin %}
            <button class="btn-sm btn-run" onclick="runSchedule('{{ s.id }}')">执行</button>
            <button class="btn-sm btn-toggle" onclick="toggleSchedule('{{ s.id }}')">{{ '禁用' if s.enabled else '启用' }}</button>
            <button class="btn-sm btn-edit" onclick="openEdit('{{ s.id }}')">编辑</button>
            <button class="btn-sm btn-del" onclick="deleteSchedule('{{ s.id }}')">删除</button>
            {% else %}
            <span class="btn-sm" style="opacity:.5; cursor:default;">查看</span>
            {% endif %}
        </div>
    </div>
    {% endfor %}
</div>
{% else %}
<div class="empty">📭 暂无定时任务，点击"新增定时任务"创建</div>
{% endif %}

<!-- 新增/编辑弹窗 -->
<div class="modal-mask" id="modal">
    <div class="modal">
        <h3 id="modal-title">新增定时任务</h3>

        <div class="form-group">
            <label>任务名称</label>
            <input type="text" id="f-name" placeholder="如：每日全量巡检">
        </div>

        <div class="form-group">
            <label>监测目标</label>
            <select id="f-target">
                {% for t in targets %}
                <option value="{{ t.id }}">{{ t.name }}</option>
                {% endfor %}
            </select>
        </div>

        <div class="form-group">
            <label>巡检套件</label>
            <select id="f-suite">
                <option value="quick">快速巡检</option>
                <option value="full">全量巡检</option>
            </select>
        </div>

        <div class="form-group">
            <label>重复周期</label>
            <div class="repeat-group">
                <div class="repeat-btn active" data-mode="daily" onclick="setRepeatMode('daily')">每天</div>
                <div class="repeat-btn" data-mode="weekday" onclick="setRepeatMode('weekday')">工作日</div>
                <div class="repeat-btn" data-mode="weekly" onclick="setRepeatMode('weekly')">每周</div>
            </div>
        </div>

        <div class="form-group">
            <label>执行时间</label>
            <div class="time-picker">
                <select id="f-hour"></select>
                <span class="time-sep">:</span>
                <select id="f-minute"></select>
            </div>
        </div>

        <div class="form-group" id="weekday-section" style="display:none;">
            <label>星期几</label>
            <div class="weekday-group">
                <div class="weekday-btn" data-day="1" onclick="toggleWeekday(this)">一</div>
                <div class="weekday-btn" data-day="2" onclick="toggleWeekday(this)">二</div>
                <div class="weekday-btn" data-day="3" onclick="toggleWeekday(this)">三</div>
                <div class="weekday-btn" data-day="4" onclick="toggleWeekday(this)">四</div>
                <div class="weekday-btn" data-day="5" onclick="toggleWeekday(this)">五</div>
                <div class="weekday-btn" data-day="6" onclick="toggleWeekday(this)">六</div>
                <div class="weekday-btn" data-day="7" onclick="toggleWeekday(this)">日</div>
            </div>
            <div class="form-hint" id="weekday-hint" style="display:none; color: #dc2626;">请选择至少一个星期</div>
        </div>

        <div class="date-section">
            <label>有效期（可选）</label>
            <div class="date-row">
                <div class="form-group">
                    <input type="date" id="f-start-date" title="生效日期">
                </div>
                <div class="form-group">
                    <input type="date" id="f-end-date" title="失效日期">
                </div>
            </div>
            <div class="form-hint">不设置则永久有效</div>
        </div>

        <div class="modal-actions">
            <button class="btn-cancel" onclick="closeModal()">取消</button>
            <button class="btn-save" id="btn-save" onclick="saveSchedule()">保存</button>
        </div>
    </div>
</div>
{% endblock %}

{% block extra_js %}
<script>
const SCHEDULES_DATA = {{ schedules | tojson | safe }};
let editingId = null;
let currentMode = 'daily';
let selectedWeekdays = new Set();
let refreshTimer = null;

// 状态映射（与后端 routes.py 同步）
const STATUS_MAP = {
    running: {badge: 'badge-running', label: '🔄 执行中'},
    success: {badge: 'badge-success', label: '✅ 成功'},
    failed:  {badge: 'badge-failed',  label: '❌ 失败'},
    error:   {badge: 'badge-error',   label: '⚠️ 异常'},
    idle:    {badge: 'badge-idle',    label: '⏸ 待执行'},
};

// 初始化时间选择器
(function initTimePicker() {
    const hourSel = document.getElementById('f-hour');
    const minSel = document.getElementById('f-minute');
    for (let h = 0; h < 24; h++) {
        const opt = document.createElement('option');
        opt.value = h;
        opt.textContent = String(h).padStart(2, '0');
        hourSel.appendChild(opt);
    }
    // 分钟：每5分钟
    for (let m = 0; m < 60; m += 5) {
        const opt = document.createElement('option');
        opt.value = m;
        opt.textContent = String(m).padStart(2, '0');
        minSel.appendChild(opt);
    }
    // 默认 08:00
    hourSel.value = 8;
    minSel.value = 0;
})();

// 页面加载时检查是否有 running 状态，有则启动轮询
(function initAutoRefresh() {
    const hasRunning = SCHEDULES_DATA.some(s => s.current_status === 'running');
    if (hasRunning) startAutoRefresh();
})();

function startAutoRefresh() {
    if (refreshTimer) return;
    refreshTimer = setInterval(refreshSchedules, 3000);
}

function stopAutoRefresh() {
    if (refreshTimer) {
        clearInterval(refreshTimer);
        refreshTimer = null;
    }
}

async function refreshSchedules() {
    try {
        const r = await fetch('/api/service-monitor/schedules', {credentials: 'include'});
        const d = await r.json();
        if (!d.success) return;

        const schedules = d.schedules || [];
        let hasRunning = false;

        schedules.forEach(s => {
            const row = document.querySelector(`.table-row[data-id="${s.id}"]`);
            if (!row) return;

            const statusKey = s.current_status || s.last_run_status || 'idle';
            const info = STATUS_MAP[statusKey] || STATUS_MAP.idle;
            const lastRunCell = row.querySelector('.last-run');

            if (s.last_run_at) {
                lastRunCell.innerHTML = `
                    <span class="last-run-time">${s.last_run_at.slice(0, 16).replace('T', ' ')}</span>
                    <div class="last-run-actions">
                        <span class="status-badge ${info.badge}">${info.label}</span>
                        ${s.last_report_id ? `<a class="report-link" href="/service-monitor/report/${s.last_report_id}">报告</a>` : ''}
                    </div>
                `;
            } else {
                lastRunCell.innerHTML = `<span class="last-run-time" style="color: var(--gray-400);">未执行</span>`;
            }

            // 更新下次执行时间
            const nextRunSpan = row.querySelector('span:nth-child(7)');
            if (nextRunSpan && s.next_run_at) {
                nextRunSpan.textContent = s.next_run_at.slice(0, 16).replace('T', ' ');
            }

            if (s.current_status === 'running') hasRunning = true;
        });

        // 无 running 状态则停止轮询
        if (!hasRunning) stopAutoRefresh();
    } catch (e) {
        console.error('刷新失败', e);
    }
}

function setRepeatMode(mode) {
    currentMode = mode;
    document.querySelectorAll('.repeat-btn').forEach(btn => {
        btn.classList.toggle('active', btn.dataset.mode === mode);
    });
    // 星期区域显隐
    document.getElementById('weekday-section').style.display = mode === 'weekly' ? '' : 'none';
    // 清除星期校验提示
    document.getElementById('weekday-hint').style.display = 'none';
}

function toggleWeekday(el) {
    const day = parseInt(el.dataset.day);
    if (selectedWeekdays.has(day)) {
        selectedWeekdays.delete(day);
        el.classList.remove('active');
    } else {
        selectedWeekdays.add(day);
        el.classList.add('active');
    }
    // 清除提示
    document.getElementById('weekday-hint').style.display = 'none';
}

function openCreate() {
    editingId = null;
    document.getElementById('modal-title').textContent = '新增定时任务';
    document.getElementById('f-name').value = '';
    document.getElementById('f-target').selectedIndex = 0;
    document.getElementById('f-suite').value = 'quick';
    document.getElementById('f-hour').value = 8;
    document.getElementById('f-minute').value = 0;
    document.getElementById('f-start-date').value = '';
    document.getElementById('f-end-date').value = '';
    setRepeatMode('daily');
    selectedWeekdays.clear();
    document.querySelectorAll('.weekday-btn').forEach(b => b.classList.remove('active'));
    document.getElementById('modal').classList.add('show');
}

function openEdit(id) {
    editingId = id;
    document.getElementById('modal-title').textContent = '编辑定时任务';

    // 从行数据中获取完整 schedule 对象
    const row = document.querySelector(`.table-row[data-id="${id}"]`);
    const sched = JSON.parse(row.dataset.schedule);

    document.getElementById('f-name').value = sched.name || '';
    // 设置目标
    const targetSel = document.getElementById('f-target');
    for (let i = 0; i < targetSel.options.length; i++) {
        if (targetSel.options[i].value === sched.target_id) {
            targetSel.selectedIndex = i;
            break;
        }
    }
    document.getElementById('f-suite').value = sched.suite || 'quick';

    // 调度字段回填
    const mode = sched.repeat_mode || 'daily';
    setRepeatMode(mode);
    document.getElementById('f-hour').value = sched.hour != null ? sched.hour : 8;
    document.getElementById('f-minute').value = sched.minute != null ? sched.minute : 0;

    // 星期回填
    selectedWeekdays.clear();
    document.querySelectorAll('.weekday-btn').forEach(b => b.classList.remove('active'));
    if (sched.weekdays && sched.weekdays.length) {
        sched.weekdays.forEach(d => {
            selectedWeekdays.add(d);
            const btn = document.querySelector(`.weekday-btn[data-day="${d}"]`);
            if (btn) btn.classList.add('active');
        });
    }

    // 日期回填
    document.getElementById('f-start-date').value = sched.start_date || '';
    document.getElementById('f-end-date').value = sched.end_date || '';

    document.getElementById('modal').classList.add('show');
}

function closeModal() {
    document.getElementById('modal').classList.remove('show');
}

async function saveSchedule() {
    const name = document.getElementById('f-name').value.trim();
    const target_id = document.getElementById('f-target').value;
    const suite = document.getElementById('f-suite').value;
    const hour = parseInt(document.getElementById('f-hour').value);
    const minute = parseInt(document.getElementById('f-minute').value);
    const start_date = document.getElementById('f-start-date').value || null;
    const end_date = document.getElementById('f-end-date').value || null;

    if (!name) { alert('请输入任务名称'); return; }

    // 星期校验
    if (currentMode === 'weekly' && selectedWeekdays.size === 0) {
        document.getElementById('weekday-hint').style.display = '';
        return;
    }

    // 日期校验
    if (end_date && start_date && end_date < start_date) {
        alert('失效日期必须晚于生效日期');
        return;
    }

    const data = {
        name,
        target_id,
        suite,
        repeat_mode: currentMode,
        hour,
        minute,
        weekdays: currentMode === 'weekly' ? Array.from(selectedWeekdays) : [],
        start_date,
        end_date,
    };

    const url = editingId
        ? '/api/service-monitor/schedules/' + editingId
        : '/api/service-monitor/schedules';
    const method = editingId ? 'PUT' : 'POST';

    try {
        const r = await fetch(url, {
            method: method,
            headers: {'Content-Type': 'application/json'},
            credentials: 'include',
            body: JSON.stringify(data),
        });
        const d = await r.json();
        if (d.success) {
            closeModal();
            alert(editingId ? '保存成功' : '创建成功');
            location.reload();
        } else {
            alert(d.error?.message || '保存失败');
        }
    } catch (e) {
        alert('请求失败');
    }
}

async function runSchedule(id) {
    const row = document.querySelector(`.table-row[data-id="${id}"]`);
    const btn = row.querySelector('.btn-run');
    const lastRunCell = row.querySelector('.last-run');

    // 按钮禁用防止重复点击
    btn.disabled = true;
    btn.textContent = '执行中...';

    try {
        const r = await fetch('/api/service-monitor/schedules/' + id + '/run', {
            method: 'POST',
            credentials: 'include',
        });
        const d = await r.json();
        if (d.success) {
            // 立即更新徽章为"执行中"
            lastRunCell.innerHTML = `
                <span class="last-run-time">刚刚</span>
                <div class="last-run-actions">
                    <span class="status-badge badge-running">🔄 执行中</span>
                </div>
            `;
            // 启动轮询
            startAutoRefresh();
        } else {
            alert(d.error?.message || '执行失败');
        }
    } catch (e) {
        alert('请求失败');
    } finally {
        btn.disabled = false;
        btn.textContent = '执行';
    }
}

async function toggleSchedule(id) {
    try {
        const r = await fetch('/api/service-monitor/schedules/' + id + '/toggle', {
            method: 'POST',
            credentials: 'include',
        });
        const d = await r.json();
        if (d.success) {
            location.reload();
        } else {
            alert(d.error?.message || '操作失败');
        }
    } catch (e) {
        alert('请求失败');
    }
}

async function deleteSchedule(id) {
    if (!confirm('确定删除该定时任务？')) return;
    try {
        const r = await fetch('/api/service-monitor/schedules/' + id, {
            method: 'DELETE',
            credentials: 'include',
        });
        const d = await r.json();
        if (d.success) {
            alert('删除成功');
            location.reload();
        } else {
            alert(d.error?.message || '删除失败');
        }
    } catch (e) {
        alert('请求失败');
    }
}
</script>
{% endblock %}