import React, { useState, useEffect, useRef } from 'react';
import {
  AlarmClock,
  Plus,
  X,
  MoreHorizontal,
  Pencil,
  Trash2,
  Play,
} from 'lucide-react';
import type { CronJob } from '@/types/api';
import {
  getCronJobs,
  addCronJob,
  deleteCronJob,
  patchCronJob,
  runCronJobNow,
  pauseCronJob,
  resumeCronJob,
} from '@/lib/api';
import { t } from '@/lib/i18n';

function formatDate(iso: string | null): string {
  if (!iso) return '-';
  const d = new Date(iso);
  return `${d.getFullYear()}/${d.getMonth() + 1}/${d.getDate()} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')}`;
}

// ---------- Toggle Switch ----------
function Toggle({ checked, onChange, disabled }: { checked: boolean; onChange: () => void; disabled?: boolean }) {
  return (
    <button
      onClick={onChange}
      disabled={disabled}
      style={{
        position: 'relative',
        display: 'inline-flex',
        alignItems: 'center',
        width: 40,
        height: 22,
        borderRadius: 11,
        background: checked ? '#1890ff' : '#d9d9d9',
        border: 'none',
        cursor: disabled ? 'not-allowed' : 'pointer',
        transition: 'background 0.25s',
        flexShrink: 0,
        opacity: disabled ? 0.5 : 1,
        padding: 0,
      }}
    >
      <span style={{
        position: 'absolute',
        left: checked ? 20 : 2,
        width: 18,
        height: 18,
        borderRadius: '50%',
        background: '#fff',
        boxShadow: '0 1px 4px rgba(0,0,0,0.2)',
        transition: 'left 0.25s',
      }} />
    </button>
  );
}

// ---------- Status Badge ----------
function StatusBadge({ status }: { status: string | null }) {
  if (!status) return <span style={{ color: '#bbb', fontSize: 13 }}>-</span>;
  const s = status.toLowerCase();
  const ok = s === 'ok' || s === 'success';
  const color = ok ? '#00cc66' : '#ff4d4f';
  const bgColor = ok ? 'rgba(0, 204, 102, 0.1)' : 'rgba(255, 77, 79, 0.1)';
  const label = ok ? t('cron.status_success') : t('cron.status_failed');

  return (
    <span style={{
      display: 'inline-flex',
      alignItems: 'center',
      gap: 4,
      color,
      background: bgColor,
      padding: '3px 8px',
      borderRadius: 12,
      fontSize: 12,
      fontWeight: 500
    }}>
      <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" style={{ flexShrink: 0 }}>
        <circle cx="7" cy="7" r="7" fill={color} />
        {ok ? (
          <path d="M4.5 7.5L6 9L9.5 5" stroke="#fff" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
        ) : (
          <path d="M4.5 4.5L9.5 9.5M9.5 4.5L4.5 9.5" stroke="#fff" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
        )}
      </svg>
      {label}
    </span>
  );
}

// ---------- Row Dropdown Menu ----------
function RowMenu({ onEdit, onDelete, onRunNow }: {
  onEdit: () => void;
  onDelete: () => void;
  onRunNow: () => void;
}) {
  const [open, setOpen] = useState(false);
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!open) return;
    const handler = (e: MouseEvent) => {
      if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [open]);

  const item = (label: string, icon: React.ReactNode, action: () => void, danger = false) => (
    <button
      onClick={() => { action(); setOpen(false); }}
      style={{
        display: 'flex', alignItems: 'center', gap: 8,
        width: '100%', padding: '7px 14px',
        background: 'none', border: 'none', cursor: 'pointer',
        fontSize: 13, color: danger ? '#ff4d4f' : '#333',
        textAlign: 'left',
        transition: 'background 0.15s',
      }}
      onMouseEnter={e => (e.currentTarget.style.background = '#f5f5f5')}
      onMouseLeave={e => (e.currentTarget.style.background = 'none')}
    >
      {icon}{label}
    </button>
  );

  return (
    <div ref={ref} style={{ position: 'relative', display: 'inline-block' }}>
      <button
        onClick={() => setOpen(v => !v)}
        style={{
          background: 'none', border: 'none', cursor: 'pointer',
          padding: '4px 6px', borderRadius: 6, color: '#999',
          display: 'inline-flex', alignItems: 'center',
        }}
        title={t('cron.actions')}
      >
        <MoreHorizontal size={18} />
      </button>
      {open && (
        <div style={{
          position: 'absolute', right: 0, top: '100%', zIndex: 100,
          background: '#fff', border: '1px solid #e8e8e8',
          borderRadius: 8, boxShadow: '0 4px 16px rgba(0,0,0,0.12)',
          minWidth: 130, padding: '4px 0',
        }}>
          {item(t('cron.run_now'), <Play size={13} />, onRunNow)}
          {item(t('cron.edit'), <Pencil size={13} />, onEdit)}
          {item(t('cron.delete'), <Trash2 size={13} />, onDelete, true)}
        </div>
      )}
    </div>
  );
}

// ---------- Add/Edit Modal ----------
function CronModal({ job, onClose, onSaved }: {
  job: CronJob | 'add';
  onClose: () => void;
  onSaved: (updated: CronJob) => void;
}) {
  const isEdit = job !== 'add';
  const existing = isEdit ? (job as CronJob) : null;

  const [formName, setFormName] = useState(existing?.name ?? '');
  const [formScheduleKind, setFormScheduleKind] = useState<'at' | 'every'>(
    existing?.schedule?.kind === 'at' ? 'at' : 'every'
  );
  const [formScheduleAt, setFormScheduleAt] = useState(existing?.schedule?.kind === 'at' ? (existing.schedule.at ?? '') : '');
  const [formScheduleEveryMs, setFormScheduleEveryMs] = useState(
    existing?.schedule?.kind === 'every' ? String(existing.schedule.every_ms ?? 60000) : '60000'
  );
  const [formCommand, setFormCommand] = useState(existing ? (existing.prompt ?? existing.command) : '');
  const [formJobType, setFormJobType] = useState<'shell' | 'agent'>(existing?.job_type === 'agent' ? 'agent' : 'shell');
  const [formEnabled, setFormEnabled] = useState(existing?.enabled ?? true);
  const [formModel, setFormModel] = useState(existing?.model ?? '');
  const [formError, setFormError] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState(false);

  const handleSubmit = async () => {
    const atValue = formScheduleAt.trim();
    const everyMsValue = Number(formScheduleEveryMs);
    const atUtc = atValue ? new Date(atValue).toISOString() : '';
    const schedule = formScheduleKind === 'at'
      ? { kind: 'at' as const, at: atUtc }
      : { kind: 'every' as const, every_ms: everyMsValue };
    const invalid =
      (formScheduleKind === 'at' && !atValue) ||
      (formScheduleKind === 'every' && (!Number.isFinite(everyMsValue) || everyMsValue <= 0));
    if (invalid || !formCommand.trim()) { setFormError(t('cron.validation_error')); return; }

    setSubmitting(true); setFormError(null);
    try {
      let result: CronJob;
      if (isEdit) {
        result = await patchCronJob((existing as CronJob).id, {
          name: formName.trim() || undefined,
          schedule,
          command: formJobType === 'shell' ? formCommand.trim() : undefined,
          prompt: formJobType === 'agent' ? formCommand.trim() : undefined,
          enabled: formEnabled,
          model: formModel.trim() || undefined,
        });
      } else {
        result = await addCronJob({
          name: formName.trim() || undefined,
          schedule,
          command: formJobType === 'shell' ? formCommand.trim() : undefined,
          prompt: formJobType === 'agent' ? formCommand.trim() : undefined,
          job_type: formJobType,
          enabled: formEnabled,
          model: formModel.trim() || undefined,
        });
      }
      onSaved(result);
    } catch (err) {
      setFormError(err instanceof Error ? err.message : t(isEdit ? 'cron.edit_error' : 'cron.add_error'));
    } finally {
      setSubmitting(false);
    }
  };

  const label = (txt: string) => (
    <label style={{ display: 'block', fontSize: 13, color: '#555', marginBottom: 4 }}>{txt}</label>
  );

  const input = (props: React.InputHTMLAttributes<HTMLInputElement>) => (
    <input
      {...props}
      style={{
        width: '100%', boxSizing: 'border-box',
        padding: '8px 10px', border: '1px solid #d9d9d9',
        borderRadius: 6, fontSize: 13, color: '#333',
        background: '#fff', outline: 'none',
        transition: 'border-color 0.2s',
        ...props.style,
      }}
      onFocus={e => (e.currentTarget.style.borderColor = '#1890ff')}
      onBlur={e => (e.currentTarget.style.borderColor = '#d9d9d9')}
    />
  );

  return (
    <div style={{
      position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.45)',
      display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 200,
    }}>
      <div style={{
        background: '#fff', borderRadius: 12, width: 460,
        maxHeight: '85vh', display: 'flex', flexDirection: 'column',
        boxShadow: '0 8px 32px rgba(0,0,0,0.18)',
      }}>
        {/* Modal header */}
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '18px 20px 14px' }}>
          <span style={{ fontSize: 15, fontWeight: 600, color: '#222' }}>
            {isEdit ? t('cron.edit_modal_title') : t('cron.add_modal_title')}
          </span>
          <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: '#999', padding: 4 }}>
            <X size={18} />
          </button>
        </div>

        {/* Modal body */}
        <div style={{ padding: '0 20px', overflowY: 'auto', flex: 1 }}>
          {formError && (
            <div style={{ background: '#fff2f0', border: '1px solid #ffa39e', borderRadius: 6, padding: '8px 12px', marginBottom: 12, fontSize: 13, color: '#cf1322' }}>
              {formError}
            </div>
          )}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            <div>
              {label(t('cron.name_optional'))}
              {input({ type: 'text', value: formName, onChange: e => setFormName(e.target.value), placeholder: t('cron.name_placeholder') })}
            </div>
            <div>
              {label(t('cron.job_type'))}
              <select
                value={formJobType}
                onChange={e => setFormJobType(e.target.value as 'shell' | 'agent')}
                style={{ width: '100%', padding: '8px 10px', border: '1px solid #d9d9d9', borderRadius: 6, fontSize: 13, color: '#333', background: '#fff' }}
              >
                <option value="shell">{t('cron.job_type_shell')}</option>
                <option value="agent">{t('cron.job_type_agent')}</option>
              </select>
            </div>
            <div>
              {label(t('cron.schedule_required'))}
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                <select
                  value={formScheduleKind}
                  onChange={e => setFormScheduleKind(e.target.value as 'at' | 'every')}
                  style={{ width: '100%', padding: '8px 10px', border: '1px solid #d9d9d9', borderRadius: 6, fontSize: 13, color: '#333', background: '#fff' }}
                >
                  <option value="at">{t('cron.schedule_kind_at')}</option>
                  <option value="every">{t('cron.schedule_kind_every')}</option>
                </select>
                {formScheduleKind === 'at' && input({ type: 'datetime-local', value: formScheduleAt, onChange: e => setFormScheduleAt(e.target.value) })}
                {formScheduleKind === 'every' && input({ type: 'number', min: 1, value: formScheduleEveryMs, onChange: e => setFormScheduleEveryMs(e.target.value), placeholder: t('cron.schedule_every_ms_placeholder') })}
              </div>
            </div>
            <div>
              {label(t('cron.command_required'))}
              <textarea
                value={formCommand}
                onChange={e => setFormCommand(e.target.value)}
                placeholder={formJobType === 'agent' ? t('cron.command_agent_placeholder') : t('cron.command_shell_placeholder')}
                rows={4}
                style={{
                  width: '100%', boxSizing: 'border-box',
                  padding: '8px 10px', border: '1px solid #d9d9d9',
                  borderRadius: 6, fontSize: 13, color: '#333',
                  background: '#fff', outline: 'none', resize: 'vertical',
                }}
                onFocus={e => (e.currentTarget.style.borderColor = '#1890ff')}
                onBlur={e => (e.currentTarget.style.borderColor = '#d9d9d9')}
              />
            </div>
            <div>
              {label(t('cron.model_optional'))}
              {input({ type: 'text', value: formModel, onChange: e => setFormModel(e.target.value), placeholder: t('cron.model_placeholder') })}
            </div>
            <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: '#555', cursor: 'pointer' }}>
              <input type="checkbox" checked={formEnabled} onChange={e => setFormEnabled(e.target.checked)} />
              {t('cron.enable_job')}
            </label>
          </div>
        </div>

        {/* Modal footer */}
        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 10, padding: '14px 20px 18px' }}>
          <button
            onClick={onClose}
            style={{ padding: '8px 18px', borderRadius: 6, border: '1px solid #d9d9d9', background: '#fff', fontSize: 13, color: '#555', cursor: 'pointer' }}
          >
            {t('cron.cancel')}
          </button>
          <button
            onClick={handleSubmit}
            disabled={submitting}
            style={{
              padding: '8px 18px', borderRadius: 6, border: 'none',
              background: submitting ? '#69c0ff' : '#1890ff',
              color: '#fff', fontSize: 13, cursor: submitting ? 'not-allowed' : 'pointer',
            }}
          >
            {submitting ? t(isEdit ? 'cron.saving' : 'cron.adding') : t(isEdit ? 'cron.save' : 'cron.add_job')}
          </button>
        </div>
      </div>
    </div>
  );
}

// ---------- Confirm Delete Dialog ----------
function ConfirmDeleteModal({ onConfirm, onCancel }: { onConfirm: () => void; onCancel: () => void }) {
  return (
    <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.45)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 300 }}>
      <div style={{ background: '#fff', borderRadius: 10, padding: 28, width: 320, boxShadow: '0 8px 32px rgba(0,0,0,0.18)' }}>
        <p style={{ margin: '0 0 20px', fontSize: 14, color: '#333' }}>{t('cron.confirm_delete')}</p>
        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 10 }}>
          <button onClick={onCancel} style={{ padding: '7px 16px', borderRadius: 6, border: '1px solid #d9d9d9', background: '#fff', fontSize: 13, color: '#555', cursor: 'pointer' }}>{t('cron.no')}</button>
          <button onClick={onConfirm} style={{ padding: '7px 16px', borderRadius: 6, border: 'none', background: '#ff4d4f', color: '#fff', fontSize: 13, cursor: 'pointer' }}>{t('cron.yes')}</button>
        </div>
      </div>
    </div>
  );
}

// ---------- Main Page ----------
export default function Cron() {
  const [jobs, setJobs] = useState<CronJob[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [modalJob, setModalJob] = useState<CronJob | 'add' | null>(null);
  const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);
  const [togglingId, setTogglingId] = useState<string | null>(null);
  const [runningId, setRunningId] = useState<string | null>(null);

  const fetchJobs = () => {
    setLoading(true);
    getCronJobs()
      .then(setJobs)
      .catch(err => setError(err.message))
      .finally(() => setLoading(false));
  };

  useEffect(() => { fetchJobs(); }, []);

  const handleToggle = async (job: CronJob) => {
    setTogglingId(job.id);
    try {
      const updated = job.enabled ? await pauseCronJob(job.id) : await resumeCronJob(job.id);
      setJobs(prev => prev.map(j => j.id === updated.id ? updated : j));
    } catch (err) {
      setError(err instanceof Error ? err.message : t('cron.toggle_error'));
    } finally {
      setTogglingId(null);
    }
  };

  const handleDelete = async (id: string) => {
    try {
      await deleteCronJob(id);
      setJobs(prev => prev.filter(j => j.id !== id));
    } catch (err) {
      setError(err instanceof Error ? err.message : t('cron.delete_error'));
    } finally {
      setConfirmDeleteId(null);
    }
  };

  const handleRunNow = async (job: CronJob) => {
    setRunningId(job.id);
    try {
      await runCronJobNow(job.id);
      fetchJobs();
    } catch (err) {
      setError(err instanceof Error ? err.message : t('cron.run_error'));
    } finally {
      setRunningId(null);
    }
  };

  const handleSaved = (updated: CronJob) => {
    setJobs(prev => {
      const idx = prev.findIndex(j => j.id === updated.id);
      if (idx >= 0) {
        const next = [...prev];
        next[idx] = updated;
        return next;
      }
      return [...prev, updated];
    });
    setModalJob(null);
  };

  // Shared page wrapper style
  const page: React.CSSProperties = {
    padding: '16px 20px',
    fontFamily: 'var(--pc-font-ui)',
    color: '#333',
    height: '100%',
    boxSizing: 'border-box',
    display: 'flex',
    flexDirection: 'column',
    gap: 8,
  };

  const thStyle: React.CSSProperties = {
    padding: '0 14px',
    height: 36,
    boxSizing: 'border-box',
    textAlign: 'left',
    fontSize: 13,
    fontWeight: 500,
    color: 'rgba(0, 0, 0, 0.6)',
    whiteSpace: 'nowrap',
    background: '#f5f5f5',
    borderBottom: '2px solid #fff',
  };

  const tdStyle: React.CSSProperties = {
    padding: '0 14px',
    height: 60,
    boxSizing: 'border-box',
    fontSize: 13,
    color: '#333',
    verticalAlign: 'middle',
    background: '#f5f5f5',
    borderBottom: '2px solid #fff',
  };

  if (error) {
    return (
      <div style={page}>
        <div style={{ background: '#fff2f0', border: '1px solid #ffa39e', borderRadius: 8, padding: '12px 16px', color: '#cf1322', fontSize: 13 }}>
          {t('cron.load_error')}: {error}
        </div>
      </div>
    );
  }

  if (loading) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: 200 }}>
        <div style={{ width: 28, height: 28, border: '2px solid #e0e0e0', borderTopColor: '#1890ff', borderRadius: '50%', animation: 'spin 0.8s linear infinite' }} />
        <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
      </div>
    );
  }

  return (
    <div style={page}>
      {/* Header */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 14px' }}>
        <span style={{ fontSize: 14, color: 'rgba(0, 0, 0, 0.85)', fontWeight: 500 }}>
          {t('cron.task_list')}（{jobs.length}）
        </span>
        {jobs.length > 0 && (
          <button
            onClick={() => setModalJob('add')}
            style={{
              display: 'inline-flex', alignItems: 'center', gap: 5,
              padding: '6px 0',
              border: 'none', background: 'none', color: 'rgba(0, 0, 0, 0.85)',
              fontSize: 13, cursor: 'pointer',
            }}
          >
            <Plus size={14} />{t('cron.add_job')}
          </button>
        )}
      </div>

      {/* Content */}
      {jobs.length === 0 ? (
        /* Empty state */
        <div
          style={{
            border: '1px solid #f0f0f0', borderRadius: 8,
            background: '#fafafa',
          }}
        >
          <button
            onClick={() => setModalJob('add')}
            style={{
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              gap: 6, width: '100%', padding: '16px',
              background: 'none', border: 'none', cursor: 'pointer',
              fontSize: 14, color: '#666',
            }}
          >
            <Plus size={16} />{t('cron.add_job')}
          </button>
        </div>
      ) : (
        /* Table */
        <div style={{ borderRadius: 8, background: '#fff', overflow: 'hidden', flex: 1 }}>
          <table style={{ width: '100%', borderCollapse: 'separate', borderSpacing: 0 }}>
            <thead>
              <tr>
                <th style={thStyle}>{t('cron.name')}</th>
                <th style={{ ...thStyle, width: '38%' }}>{t('cron.prompt_col')}</th>
                <th style={{ ...thStyle, whiteSpace: 'nowrap' }}>{t('cron.next_run')}</th>
                <th style={{ ...thStyle, whiteSpace: 'nowrap' }}>{t('cron.last_status')}</th>
                <th style={{ ...thStyle, whiteSpace: 'nowrap' }}>{t('cron.actions')}</th>
              </tr>
            </thead>
            <tbody>
              {jobs.map((job, idx) => {
                const isLast = idx === jobs.length - 1;
                const sep: React.CSSProperties = isLast ? { borderBottom: 'none' } : {};
                const firstTd: React.CSSProperties = isLast ? { ...sep, borderRadius: '0 0 0 6px' } : sep;
                const lastTd: React.CSSProperties = isLast ? { ...sep, borderRadius: '0 0 6px 0' } : sep;
                return (
                  <tr key={job.id}>
                    {/* Name */}
                    <td style={{ ...tdStyle, ...firstTd }}>
                      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, color: 'rgba(0, 0, 0, 0.85)', fontWeight: 400 }}>
                        <AlarmClock size={14} style={{ color: '#262626', flexShrink: 0 }} />
                        {job.name ?? job.id.slice(0, 8)}
                      </span>
                    </td>
                    {/* Prompt / command */}
                    <td style={{ ...tdStyle, ...sep, color: 'rgba(0, 0, 0, 0.6)', maxWidth: 0 }}>
                      <span style={{ display: 'block', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                        {job.prompt ?? job.command}
                      </span>
                    </td>
                    {/* Next run */}
                    <td style={{ ...tdStyle, ...sep, color: 'rgba(0, 0, 0, 0.6)', whiteSpace: 'nowrap' }}>
                      {formatDate(job.next_run)}
                    </td>
                    {/* Last status */}
                    <td style={{ ...tdStyle, ...sep }}>
                      <StatusBadge status={job.last_status} />
                    </td>
                    {/* Actions */}
                    <td style={{ ...tdStyle, ...lastTd }}>
                      <div style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
                        <RowMenu
                          onEdit={() => setModalJob(job)}
                          onDelete={() => setConfirmDeleteId(job.id)}
                          onRunNow={() => handleRunNow(job)}
                        />
                        <Toggle
                          checked={job.enabled}
                          onChange={() => handleToggle(job)}
                          disabled={togglingId === job.id || runningId === job.id}
                        />
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}

      {/* Add / Edit Modal */}
      {modalJob !== null && (
        <CronModal
          job={modalJob}
          onClose={() => setModalJob(null)}
          onSaved={handleSaved}
        />
      )}

      {/* Confirm Delete */}
      {confirmDeleteId !== null && (
        <ConfirmDeleteModal
          onConfirm={() => handleDelete(confirmDeleteId)}
          onCancel={() => setConfirmDeleteId(null)}
        />
      )}
    </div>
  );
}
