// ─── Cron Page ───────────────────────────────────────────────────────────────
const { useState: uCRS, useEffect: uCRE } = React;

function parseCron(schedule) {
  const presets = {
    '0 2 * * *':    'Daily at 02:00',
    '0 3 * * 1':    'Every Monday at 03:00',
    '0 1 1 * *':    '1st of month at 01:00',
    '*/30 * * * *': 'Every 30 minutes',
    '0 8 * * *':    'Daily at 08:00',
    '0 4 * * 0':    'Every Sunday at 04:00',
  };
  return presets[schedule] || schedule;
}

function CronPage() {
  const [jobs, setJobs]       = uCRS([]);
  const [scripts, setScripts] = uCRS([]);
  const [addModal, setAddModal] = uCRS(false);
  const [rawModal, setRawModal] = uCRS(false);
  const [rawText, setRawText]  = uCRS('');
  const [newJob, setNewJob]    = uCRS({ name: '', script: '', schedule: '0 2 * * *', minute: '0', hour: '2', dom: '*', month: '*', dow: '*', ntfy: false });
  const [toast, setToast]      = uCRS(null);

  const showToast = (msg, color = '#00ff88') => { setToast({ msg, color }); setTimeout(() => setToast(null), 2500); };

  const fetchJobs = () => apiClient('/api/cron/jobs').then(d => { if (d) setJobs(d); }).catch(() => {});

  uCRE(() => {
    fetchJobs();
    apiClient('/api/scripts').then(d => { if (d) setScripts(d.map(s => s.name)); }).catch(() => {});
    const id = setInterval(fetchJobs, 30000);
    return () => clearInterval(id);
  }, []);

  const toggleActive = async (id) => {
    const j = jobs.find(x => x.id === id);
    if (!j) return;
    try {
      await apiClient(`/api/cron/jobs/${id}`, {
        method: 'PUT',
        body: JSON.stringify({ active: !j.active }),
      });
      fetchJobs();
    } catch (err) { showToast(`Failed: ${err.message}`, '#ff2244'); }
  };

  const toggleNtfy = async (id) => {
    const j = jobs.find(x => x.id === id);
    if (!j) return;
    try {
      await apiClient(`/api/cron/jobs/${id}`, {
        method: 'PUT',
        body: JSON.stringify({ ntfy: !j.ntfy }),
      });
      fetchJobs();
      showToast('NTFY setting updated');
    } catch (err) { showToast(`Failed: ${err.message}`, '#ff2244'); }
  };

  const deleteJob = async (id) => {
    const j = jobs.find(x => x.id === id);
    try {
      await apiClient(`/api/cron/jobs/${id}`, { method: 'DELETE' });
      showToast(`Deleted: ${j?.name}`, '#ff2244');
      fetchJobs();
    } catch (err) { showToast(`Failed: ${err.message}`, '#ff2244'); }
  };

  const addJob = async () => {
    const schedule = `${newJob.minute} ${newJob.hour} ${newJob.dom} ${newJob.month} ${newJob.dow}`;
    try {
      await apiClient('/api/cron/jobs', {
        method: 'POST',
        body: JSON.stringify({ name: newJob.name || newJob.script, schedule, script: newJob.script, ntfy: newJob.ntfy }),
      });
      setAddModal(false);
      showToast(`Job "${newJob.name || newJob.script}" added`);
      fetchJobs();
    } catch (err) { showToast(`Failed: ${err.message}`, '#ff2244'); }
  };

  const openRaw = async () => {
    const data = await apiClient('/api/cron/raw').catch(() => null);
    setRawText(data?.crontab_text || '');
    setRawModal(true);
  };

  const statusColor = { success: '#00ff88', error: '#ff2244' };
  const scriptsList = scripts.length > 0 ? scripts : ['daily-backup.sh', 'update-system.sh', 'health-check.py'];

  return (
    <div style={{ display: 'grid', gridTemplateColumns: '1fr 300px', gap: 8, padding: 10, height: '100%', boxSizing: 'border-box', overflow: 'hidden' }}>

      {/* Job Table */}
      <Panel title="CRON JOBS" style={{ display: 'flex', flexDirection: 'column', overflow: 'hidden' }}
        headerRight={
          <div style={{ display: 'flex', gap: 6 }}>
            <SCPButton small color="#888" onClick={openRaw}>RAW CRONTAB</SCPButton>
            <SCPButton small color="#00ff88" onClick={() => setAddModal(true)}>+ ADD JOB</SCPButton>
          </div>
        }>
        <div style={{ flex: 1, overflow: 'auto' }}>
          <table style={{ width: '100%', borderCollapse: 'collapse' }}>
            <thead>
              <tr>{['NAME', 'SCHEDULE', 'SCRIPT', 'LAST RUN', 'NEXT RUN', 'STATUS', 'ACTIVE', 'NTFY', ''].map(h => (
                <th key={h} style={{ fontSize: 14, letterSpacing: '0.15em', color: 'rgba(0,200,255,0.5)', textTransform: 'uppercase', padding: '6px 10px', borderBottom: '1px solid rgba(0,200,255,0.12)', textAlign: 'left', fontWeight: 400, fontFamily: "'Share Tech Mono',monospace", whiteSpace: 'nowrap' }}>{h}</th>
              ))}</tr>
            </thead>
            <tbody>
              {jobs.length === 0 && (
                <tr><td colSpan={9} style={{ padding: '20px', textAlign: 'center', fontSize: 14, color: 'rgba(0,200,255,0.25)', fontFamily: "'Share Tech Mono',monospace" }}>NO JOBS CONFIGURED</td></tr>
              )}
              {jobs.map(j => (
                <tr key={j.id} style={{ opacity: j.active ? 1 : 0.45, transition: 'opacity 0.2s' }}>
                  <td style={{ padding: '9px 10px', fontFamily: "'Share Tech Mono',monospace", fontSize: 14, color: '#e0f4ff', borderBottom: '1px solid rgba(0,200,255,0.05)', fontWeight: 600 }}>{j.name}</td>
                  <td style={{ padding: '9px 10px', fontFamily: "'Share Tech Mono',monospace", fontSize: 14, color: '#ffd700', borderBottom: '1px solid rgba(0,200,255,0.05)', whiteSpace: 'nowrap' }}>
                    <div>{j.schedule}</div>
                    <div style={{ fontSize: 14, color: 'rgba(255,215,0,0.4)', marginTop: 2 }}>{parseCron(j.schedule)}</div>
                  </td>
                  <td style={{ padding: '9px 10px', fontFamily: "'Share Tech Mono',monospace", fontSize: 14, color: 'rgba(0,200,255,0.7)', borderBottom: '1px solid rgba(0,200,255,0.05)', whiteSpace: 'nowrap' }}>{j.script}</td>
                  <td style={{ padding: '9px 10px', fontFamily: "'Share Tech Mono',monospace", fontSize: 14, color: 'rgba(180,220,255,0.4)', borderBottom: '1px solid rgba(0,200,255,0.05)', whiteSpace: 'nowrap' }}>{j.last_run || '—'}</td>
                  <td style={{ padding: '9px 10px', fontFamily: "'Share Tech Mono',monospace", fontSize: 14, color: 'rgba(0,200,255,0.5)', borderBottom: '1px solid rgba(0,200,255,0.05)', whiteSpace: 'nowrap' }}>{j.next_run ? j.next_run.replace('T',' ').slice(0,16) : '—'}</td>
                  <td style={{ padding: '9px 10px', borderBottom: '1px solid rgba(0,200,255,0.05)' }}>
                    {j.last_status && <span style={{ fontSize: 14, color: statusColor[j.last_status] || '#00c8ff', fontFamily: "'Share Tech Mono',monospace" }}>● {j.last_status.toUpperCase()}</span>}
                  </td>
                  <td style={{ padding: '9px 10px', borderBottom: '1px solid rgba(0,200,255,0.05)' }}>
                    <Toggle value={j.active} onChange={() => toggleActive(j.id)} />
                  </td>
                  <td style={{ padding: '9px 10px', borderBottom: '1px solid rgba(0,200,255,0.05)' }}>
                    <Toggle value={j.ntfy} onChange={() => toggleNtfy(j.id)} />
                  </td>
                  <td style={{ padding: '9px 10px', borderBottom: '1px solid rgba(0,200,255,0.05)' }}>
                    <SCPButton small color="#ff2244" onClick={() => deleteJob(j.id)}>DEL</SCPButton>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </Panel>

      {/* Stats Panel */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        <Panel title="OVERVIEW" style={{ padding: 14 }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
            {[
              ['TOTAL', jobs.length, '#00c8ff'],
              ['ACTIVE', jobs.filter(j=>j.active).length, '#00ff88'],
              ['NTFY ON', jobs.filter(j=>j.ntfy).length, '#ffd700'],
              ['ERRORS', jobs.filter(j=>j.last_status==='error').length, '#ff2244'],
            ].map(([l, v, c]) => (
              <div key={l} style={{ background: `${c}08`, border: `1px solid ${c}20`, padding: '8px 10px', textAlign: 'center' }}>
                <div style={{ fontSize: 22, fontWeight: 700, color: c, fontFamily: "'Share Tech Mono',monospace", textShadow: `0 0 6px ${c}` }}>{v}</div>
                <div style={{ fontSize: 14, color: `${c}60`, letterSpacing: '0.15em', fontFamily: "'Share Tech Mono',monospace" }}>{l}</div>
              </div>
            ))}
          </div>
        </Panel>

        <Panel title="UPCOMING RUNS" style={{ flex: 1, overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
          <div style={{ flex: 1, overflow: 'auto', padding: '4px 0' }}>
            {jobs.filter(j => j.active && j.next_run).sort((a,b) => a.next_run.localeCompare(b.next_run)).map(j => (
              <div key={j.id} style={{ padding: '8px 14px', borderBottom: '1px solid rgba(0,200,255,0.06)' }}>
                <div style={{ fontSize: 14, color: '#e0f4ff', fontFamily: "'Share Tech Mono',monospace" }}>{j.name}</div>
                <div style={{ fontSize: 14, color: 'rgba(0,200,255,0.5)', fontFamily: "'Share Tech Mono',monospace", marginTop: 2 }}>{j.next_run.replace('T',' ').slice(0,16)}</div>
              </div>
            ))}
          </div>
        </Panel>
      </div>

      {/* Add Job Modal */}
      <Modal open={addModal} onClose={() => setAddModal(false)} title="ADD CRON JOB" width={560}>
        <InputField label="JOB NAME" value={newJob.name} onChange={v => setNewJob(p => ({...p, name: v}))} placeholder="e.g. Weekly Report" />
        <FormRow label="SCRIPT">
          <select className="scp-select" value={newJob.script} onChange={e => setNewJob(p => ({...p, script: e.target.value}))}>
            <option value="">-- select script --</option>
            {scriptsList.map(s => <option key={s} value={s}>{s}</option>)}
          </select>
        </FormRow>
        <div style={{ marginBottom: 10 }}><SectionLabel>SCHEDULE (CRON EXPRESSION)</SectionLabel></div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5,1fr)', gap: 6, marginBottom: 12 }}>
          {[['MINUTE', 'minute', '0-59'], ['HOUR', 'hour', '0-23'], ['DOM', 'dom', '1-31'], ['MONTH', 'month', '1-12'], ['DOW', 'dow', '0-6']].map(([l, k, hint]) => (
            <div key={k}>
              <div style={{ fontSize: 14, color: 'rgba(0,200,255,0.4)', letterSpacing: '0.1em', fontFamily: "'Share Tech Mono',monospace", marginBottom: 3 }}>{l}</div>
              <input className="scp-input" value={newJob[k]} onChange={e => setNewJob(p => ({...p, [k]: e.target.value, schedule: `${k === 'minute' ? e.target.value : p.minute} ${k === 'hour' ? e.target.value : p.hour} ${k === 'dom' ? e.target.value : p.dom} ${k === 'month' ? e.target.value : p.month} ${k === 'dow' ? e.target.value : p.dow}` }))} placeholder={hint} style={{ textAlign: 'center' }} />
            </div>
          ))}
        </div>
        <div style={{ background: 'rgba(0,200,255,0.05)', border: '1px solid rgba(0,200,255,0.15)', padding: '8px 12px', marginBottom: 14, fontFamily: "'Share Tech Mono',monospace", fontSize: 14, color: '#ffd700' }}>
          {newJob.schedule} — /opt/scripts/{newJob.script}
        </div>
        <FormRow label="NTFY ALERT"><Toggle value={newJob.ntfy} onChange={v => setNewJob(p => ({...p, ntfy: v}))} label="Send NTFY on completion" /></FormRow>
        <div style={{ display: 'flex', gap: 8, marginTop: 14, justifyContent: 'flex-end' }}>
          <SCPButton color="#888" onClick={() => setAddModal(false)}>CANCEL</SCPButton>
          <SCPButton color="#00ff88" onClick={addJob} disabled={!newJob.script}>ADD JOB</SCPButton>
        </div>
      </Modal>

      {/* Raw Crontab Modal */}
      <Modal open={rawModal} onClose={() => setRawModal(false)} title="RAW CRONTAB VIEW" width={680}>
        <CodeEditor value={rawText} onChange={() => {}} rows={16} />
        <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 12 }}>
          <SCPButton color="#00c8ff" onClick={() => setRawModal(false)}>CLOSE</SCPButton>
        </div>
      </Modal>

      {toast && (
        <div style={{ position: 'fixed', bottom: 24, right: 24, background: 'rgba(0,15,35,0.95)', border: `1px solid ${toast.color}50`, padding: '10px 20px', zIndex: 9999, fontFamily: "'Share Tech Mono',monospace", fontSize: 14, color: toast.color }}>
          {toast.msg}
        </div>
      )}
    </div>
  );
}

Object.assign(window, { CronPage });
