jingrow.ui.form.ControlCronEditor = class ControlCronEditor extends jingrow.ui.form.ControlData {
    make_input() {
        if (this.$container) return;
        this.$container = document.createElement('div');
        this.$container.className = 'cron-editor-modern';
        this.$container.style.cssText = `
            border: 1px solid #e1e5e9;
            border-radius: 12px;
            padding: 20px;
            background: #fff;
            box-shadow: 0 2px 8px rgba(0,0,0,0.08);
            max-width: 480px;
            margin: 0 auto;
        `;

        this.$type = document.createElement('select');
        this.$type.className = 'cron-type';
        this.$type.style.cssText = `
            width: 100%;
            padding: 10px 14px;
            border: 1.5px solid #1fc76f;
            border-radius: 8px;
            font-size: 15px;
            background: #f3f3f3 url('data:image/svg+xml;utf8,<svg fill="%231fc76f" height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><path d=\"M7 10l5 5 5-5z\"/></svg>') no-repeat right 16px center/18px 18px;
            padding-right: 40px;
            margin-bottom: 16px;
            outline: none;
            transition: border-color 0.2s;
            appearance: none;
            -webkit-appearance: none;
            -moz-appearance: none;
        `;
        this.$type.innerHTML = `
            <option value="" selected disabled hidden>触发时间</option>
            <option value="every_minute">每分钟</option>
            <option value="every_n_minute">每N分钟</option>
            <option value="every_hour">每小时</option>
            <option value="every_n_hour">每N小时</option>
            <option value="every_day">每天</option>
            <option value="every_week">每周</option>
            <option value="every_month">每月</option>
        `;
        this.$container.appendChild(this.$type);

        this.$params = document.createElement('div');
        this.$params.className = 'cron-params';
        this.$params.style.cssText = `
            margin-bottom: 16px;
            padding: 14px;
            background: #f3f3f3;
            border-radius: 8px;
            border: 1.5px solid #e3e7ed;
        `;
        this.$container.appendChild(this.$params);
        this.$params.style.display = 'none';

        this.$preview = document.createElement('div');
        this.$preview.className = 'cron-preview';
        this.$preview.style.cssText = `
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 10px 14px;
            background: #f3f3f3;
            border-radius: 6px;
            font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
            font-size: 14px;
            color: #333;
            margin-bottom: 16px;
            border-left: 4px solid #1fc76f;
            position: relative;
        `;
        this.$copyBtn = document.createElement('button');
        this.$copyBtn.type = 'button';
        this.$copyBtn.innerHTML = '复制';
        this.$copyBtn.style.cssText = `
            background: #e3e7ed;
            color: #1fc76f;
            border: none;
            padding: 4px 10px;
            border-radius: 4px;
            font-size: 13px;
            cursor: pointer;
            margin-left: 8px;
            transition: background 0.2s;
        `;
        this.$copyBtn.addEventListener('mouseenter', () => this.$copyBtn.style.background = '#d1d5db');
        this.$copyBtn.addEventListener('mouseleave', () => this.$copyBtn.style.background = '#e3e7ed');
        this.$copyBtn.addEventListener('click', () => {
            navigator.clipboard.writeText(this.get_input_value());
            this.$copyBtn.innerText = '已复制!';
            setTimeout(() => { this.$copyBtn.innerText = '复制'; }, 1200);
        });
        this.$container.appendChild(this.$preview);
        this.$preview.style.display = 'none';

        this.$advanced = document.createElement('div');
        this.$advanced.className = 'cron-advanced';
        this.$advanced.style.display = 'none';
        this.$advanced.style.cssText = `
            margin-bottom: 16px;
        `;
        this.$input = $(document.createElement('input'));
        this.$input.attr('type', 'text');
        this.$input.addClass('input-with-preview');
        this.$input.attr('placeholder', '如：*/5 * * * *');
        this.$input.css({
            'width': '100%',
            'padding': '10px 14px',
            'border': '1.5px solid #bfc8d6',
            'border-radius': '8px',
            'font-size': '15px',
            'font-family': "'Monaco', 'Menlo', 'Ubuntu Mono', monospace",
            'outline': 'none',
            'transition': 'border-color 0.2s',
            'background': '#f3f3f3',
        });
        this.$advanced.appendChild(this.$input[0]);
        this.$container.appendChild(this.$advanced);

        this.$toggle = document.createElement('button');
        this.$toggle.type = 'button';
        this.$toggle.className = 'cron-toggle-mode';
        this.$toggle.innerText = 'Cron表达式';
        this.$toggle.style.cssText = `
            background: #1fc76f;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 8px;
            font-size: 15px;
            cursor: pointer;
            transition: background-color 0.2s;
            outline: none;
        `;
        this.$container.appendChild(this.$toggle);

        this.input_area.appendChild(this.$container);

        this.$input = $(document.createElement('input'));
        this.$input.attr('type', 'hidden');
        this.$input.attr('name', this.df && this.df.fieldname ? this.df.fieldname : '');
        this.input_area.appendChild(this.$input[0]);

        this.$advanced.style.display = 'none';

        this.bind_events();
        this.render_params();
        this.set_preview(this.get_input_value());
        if (this.get_input_value() && this.get_input_value() !== '* * * * *') {
            this.$preview.style.display = '';
        }
        this.bind_change_event();
    }

    bind_events() {
        this.$type.addEventListener('change', () => {
            this.$params.style.display = '';
            this.$preview.style.display = '';
            this.render_params();
            this.update_cron(true);
            this.$advanced.style.display = 'none';
        });
        this.$toggle.addEventListener('click', () => {
            if (this.$advanced.style.display === 'none') {
                this.$advanced.style.display = '';
                this.$params.style.display = 'none';
                this.$type.style.display = 'none';
                this.$toggle.innerText = '可视化设置';
                this.$toggle.style.background = '#1fc76f';
            } else {
                this.$advanced.style.display = 'none';
                this.$params.style.display = '';
                this.$type.style.display = '';
                this.$toggle.innerText = 'Cron表达式';
                this.$toggle.style.background = '#1fc76f';
            }
        });
        this.$advanced.addEventListener('input', (e) => {
            if (e.target.tagName === 'INPUT') {
                this.set_preview(e.target.value);
                this.$input.val(e.target.value);
                this.$input.trigger('change');
                this.validate_cron(e.target.value);
            }
        });
        this.$type.addEventListener('focus', () => {
            this.$type.style.borderColor = '#1fc76f';
        });
        this.$type.addEventListener('blur', () => {
            this.$type.style.borderColor = '#bfc8d6';
        });
    }

    validate_cron(expr) {
        let valid = /^\s*([0-9\*\/\-,]+\s+){4,6}[0-9\*\/\-,]+\s*$/.test(expr);
        if (!valid) {
            this.$input.css('border-color', '#e74c3c');
            this.$input.css('background', '#fff6f6');
        } else {
            this.$input.css('border-color', '#bfc8d6');
            this.$input.css('background', '#f9fafb');
        }
        return valid;
    }

    cron_to_text(expr) {
        if (expr === '* * * * *') return '每分钟';
        if (/^\*\/(\d+) \* \* \* \*$/.test(expr)) return `每${expr.match(/^\*\/(\d+)/)[1]}分钟`;
        if (expr === '0 * * * *') return '每小时';
        if (/^0 \*\/(\d+) \* \* \*$/.test(expr)) return `每${expr.match(/^0 \*\/(\d+)/)[1]}小时`;
        if (/^\d+ \d+ \* \* \*$/.test(expr)) {
            let [m, h] = expr.split(' ');
            return `每天 ${h}时${m}分`;
        }
        if (/^\d+ \d+ \* \* \d+$/.test(expr)) {
            let [m, h, , , w] = expr.split(' ');
            const week = ['周日','周一','周二','周三','周四','周五','周六'];
            return `每${week[parseInt(w)||0]} ${h}时${m}分`;
        }
        if (/^\d+ \d+ \d+ \* \*$/.test(expr)) {
            let [m, h, d] = expr.split(' ');
            return `每月${d}日 ${h}时${m}分`;
        }
        return '';
    }

    render_params() {
        if (!this.$type.value) {
            this.$params.style.display = 'none';
            if (this.get_input_value() && this.get_input_value() !== '* * * * *') {
                this.$preview.style.display = '';
            } else {
                this.$preview.style.display = 'none';
            }
            return;
        }
        this.$params.innerHTML = '';
        let type = this.$type.value;
        
        const createInput = (type, className, min, max, value, width = '60px') => {
            let input = document.createElement('input');
            input.type = type;
            input.className = className;
            input.min = min;
            if (max !== null && max !== undefined) input.max = max;
            input.value = value;
            input.style.cssText = `
                width: ${width};
                padding: 6px 8px;
                border: 1.5px solid #bfc8d6;
                border-radius: 4px;
                font-size: 14px;
                text-align: center;
                outline: none;
                transition: border-color 0.2s;
                background: #fff;
            `;
            input.addEventListener('focus', () => input.style.borderColor = '#1fc76f');
            input.addEventListener('input', () => {
                let cron = this.get_cron_from_params();
                this.$input.val(cron);
                this.set_preview(cron);
                this.$input.trigger('change');
            });
            input.addEventListener('blur', () => {
                input.style.borderColor = '#bfc8d6';
                let val = parseInt(input.value);
                if (isNaN(val) || val < min) input.value = min;
                if (max !== null && max !== undefined && val > max) input.value = max;
                let cron = this.get_cron_from_params();
                this.$input.val(cron);
                this.set_preview(cron);
                this.$input.trigger('change');
            });
            return input;
        };
        
        const createSelect = (className, options) => {
            let select = document.createElement('select');
            select.className = className;
            select.innerHTML = options;
            select.style.cssText = `
                padding: 6px 8px;
                border: 1px solid #d1d5db;
                border-radius: 4px;
                font-size: 14px;
                outline: none;
                transition: border-color 0.2s;
            `;
            select.addEventListener('focus', () => select.style.borderColor = '#1fc76f');
            select.addEventListener('blur', () => select.style.borderColor = '#d1d5db');
            return select;
        };
        
        if (type === 'every_n_minute') {
            let n = createInput('number', 'n-minute', 1, 59, 5);
            this.$params.appendChild(document.createTextNode('每 '));
            this.$params.appendChild(n);
            this.$params.appendChild(document.createTextNode(' 分钟'));
            n.addEventListener('input', () => this.update_cron(true));
        } else if (type === 'every_n_hour') {
            let n = createInput('number', 'n-hour', 1, 23, 1);
            this.$params.appendChild(document.createTextNode('每 '));
            this.$params.appendChild(n);
            this.$params.appendChild(document.createTextNode(' 小时'));
            n.addEventListener('input', () => this.update_cron(true));
        } else if (type === 'every_day') {
            let h = createInput('number', 'hour', 0, 23, 0);
            let m = createInput('number', 'minute', 0, 59, 0);
            this.$params.appendChild(document.createTextNode('每天 '));
            this.$params.appendChild(h);
            this.$params.appendChild(document.createTextNode(' 时 '));
            this.$params.appendChild(m);
            this.$params.appendChild(document.createTextNode(' 分'));
            h.addEventListener('input', () => this.update_cron(true));
            m.addEventListener('input', () => this.update_cron(true));
        } else if (type === 'every_week') {
            let week = createSelect('weekday', 
                '<option value="0">周日</option><option value="1">周一</option><option value="2">周二</option><option value="3">周三</option><option value="4">周四</option><option value="5">周五</option><option value="6">周六</option>');
            let h = createInput('number', 'hour', 0, 23, 0);
            let m = createInput('number', 'minute', 0, 59, 0);
            this.$params.appendChild(document.createTextNode('每周 '));
            this.$params.appendChild(week);
            this.$params.appendChild(document.createTextNode(' '));
            this.$params.appendChild(h);
            this.$params.appendChild(document.createTextNode(' 时 '));
            this.$params.appendChild(m);
            this.$params.appendChild(document.createTextNode(' 分'));
            week.addEventListener('change', () => this.update_cron(true));
            h.addEventListener('input', () => this.update_cron(true));
            m.addEventListener('input', () => this.update_cron(true));
        } else if (type === 'every_month') {
            let d = createInput('number', 'day', 1, 31, 1);
            let h = createInput('number', 'hour', 0, 23, 0);
            let m = createInput('number', 'minute', 0, 59, 0);
            this.$params.appendChild(document.createTextNode('每月 '));
            this.$params.appendChild(d);
            this.$params.appendChild(document.createTextNode(' 日 '));
            this.$params.appendChild(h);
            this.$params.appendChild(document.createTextNode(' 时 '));
            this.$params.appendChild(m);
            this.$params.appendChild(document.createTextNode(' 分'));
            d.addEventListener('input', () => this.update_cron(true));
            h.addEventListener('input', () => this.update_cron(true));
            m.addEventListener('input', () => this.update_cron(true));
        }
        this.update_cron(false);
    }

    update_cron(user_action = false, advanced = false) {
        let type = this.$type.value;
        let cron = '';
        if (type === 'every_minute') {
            cron = '* * * * *';
        } else if (type === 'every_n_minute') {
            let n = this.$params.querySelector('.n-minute').value || 5;
            cron = `*/${n} * * * *`;
        } else if (type === 'every_hour') {
            cron = '0 * * * *';
        } else if (type === 'every_n_hour') {
            let n = this.$params.querySelector('.n-hour').value || 1;
            cron = `0 */${n} * * *`;
        } else if (type === 'every_day') {
            let h = this.$params.querySelector('.hour')?.value || 0;
            let m = this.$params.querySelector('.minute')?.value || 0;
            cron = `${m} ${h} * * *`;
        } else if (type === 'every_week') {
            let w = this.$params.querySelector('.weekday')?.value || 0;
            let h = this.$params.querySelector('.hour')?.value || 0;
            let m = this.$params.querySelector('.minute')?.value || 0;
            cron = `${m} ${h} * * ${w}`;
        } else if (type === 'every_month') {
            let d = this.$params.querySelector('.day')?.value || 1;
            let h = this.$params.querySelector('.hour')?.value || 0;
            let m = this.$params.querySelector('.minute')?.value || 0;
            cron = `${m} ${h} ${d} * *`;
        }
        this.set_preview(cron);
        this.$input.val(cron);
        if (user_action) {
            this.$input.trigger('change');
        }
    }

    set_value(value) {
        this.set_input(value);
        this.value = value;
        if (this.input) {
            this.input.value = value;
            this.input.dispatchEvent(new Event('change', { bubbles: true }));
        }
    }
    get_value() {
        const v = this.get_input_value();
        return v;
    }

    set_input(value) {
        if (!this.$container) return;
        if (!value) value = '* * * * *';
        this.$input.val(value);
        this.set_preview(value);
        let type = this.$type.value;
        if (type === 'every_n_minute') {
            let n = value.match(/^\*\/(\d+)/);
            let nInput = this.$params.querySelector('.n-minute');
            if (n && nInput) nInput.value = n[1];
        } else if (type === 'every_n_hour') {
            let n = value.match(/^0 \*\/(\d+)/);
            let nInput = this.$params.querySelector('.n-hour');
            if (n && nInput) nInput.value = n[1];
        } else if (type === 'every_day') {
            let m_h = value.match(/^(\d+) (\d+) \* \* \*$/);
            let hInput = this.$params.querySelector('.hour');
            let mInput = this.$params.querySelector('.minute');
            if (m_h && hInput && mInput) {
                mInput.value = m_h[1];
                hInput.value = m_h[2];
            }
        } else if (type === 'every_week') {
            let m_h_w = value.match(/^(\d+) (\d+) \* \* (\d+)$/);
            let wInput = this.$params.querySelector('.weekday');
            let hInput = this.$params.querySelector('.hour');
            let mInput = this.$params.querySelector('.minute');
            if (m_h_w && wInput && hInput && mInput) {
                mInput.value = m_h_w[1];
                hInput.value = m_h_w[2];
                wInput.value = m_h_w[3];
            }
        } else if (type === 'every_month') {
            let m_h_d = value.match(/^(\d+) (\d+) (\d+) \* \*$/);
            let dInput = this.$params.querySelector('.day');
            let hInput = this.$params.querySelector('.hour');
            let mInput = this.$params.querySelector('.minute');
            if (m_h_d && dInput && hInput && mInput) {
                mInput.value = m_h_d[1];
                hInput.value = m_h_d[2];
                dInput.value = m_h_d[3];
            }
        }
        if (value && value !== '* * * * *') {
            this.$preview.style.display = '';
        }
    }

    get_input_value() {
        const v = this.$input ? this.$input.val() : '';
        return v;
    }

    set_preview(value) {
        this.$preview.innerHTML = `<strong>Cron 表达式：</strong><code>${value}</code>`;
        let text = this.cron_to_text(value);
        if (text) {
            this.$preview.innerHTML += `<span style="color:#888;margin-left:10px;">(${text})</span>`;
        }
        this.$preview.appendChild(this.$copyBtn);
    }

    get_cron_from_params() {
        let type = this.$type.value;
        if (type === 'every_minute') {
            return '* * * * *';
        } else if (type === 'every_n_minute') {
            let n = this.$params.querySelector('.n-minute').value || 5;
            return `*/${n} * * * *`;
        } else if (type === 'every_hour') {
            return '0 * * * *';
        } else if (type === 'every_n_hour') {
            let n = this.$params.querySelector('.n-hour').value || 1;
            return `0 */${n} * * *`;
        } else if (type === 'every_day') {
            let h = this.$params.querySelector('.hour').value || 0;
            let m = this.$params.querySelector('.minute').value || 0;
            return `${m} ${h} * * *`;
        } else if (type === 'every_week') {
            let w = this.$params.querySelector('.weekday').value || 0;
            let h = this.$params.querySelector('.hour').value || 0;
            let m = this.$params.querySelector('.minute').value || 0;
            return `${m} ${h} * * ${w}`;
        } else if (type === 'every_month') {
            let d = this.$params.querySelector('.day').value || 1;
            let h = this.$params.querySelector('.hour').value || 0;
            let m = this.$params.querySelector('.minute').value || 0;
            return `${m} ${h} ${d} * *`;
        }
        return '* * * * *';
    }
} 