// Calendar view — interview schedule

const DOW_SHORT = ['Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab', 'Min'];
const DOW_LONG = ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu', 'Minggu'];
const MONTHS = ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'];

function fmtDate(d) {
  // Local YYYY-MM-DD — avoid toISOString which shifts to UTC
  return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;
}
function parseTime(hhmm) {
  const [h, m] = hhmm.split(':').map(Number);
  return h * 60 + m;
}
function startOfWeek(d) {
  const x = new Date(d);
  const dow = (x.getDay() + 6) % 7; // 0 = Mon
  x.setDate(x.getDate() - dow);
  x.setHours(0,0,0,0);
  return x;
}

function CalendarView({ openCandidate, candidates, interviews, addInterview, updateInterview, cancelInterview, go, scheduleFor }) {
  const { HR_USERS } = window.TalentirData;
  const [anchor, setAnchor] = useState(() => { const d = new Date(); d.setHours(0, 0, 0, 0); return d; });
  const [mode, setMode] = useState('week'); // week | month
  const [filterHR, setFilterHR] = useState('all');
  const [showSched, setShowSched] = useState(scheduleFor || null);
  const [selectedIv, setSelectedIv] = useState(null);

  useEffect(() => { if (scheduleFor) setShowSched(scheduleFor); }, [scheduleFor]);

  const visibleInterviews = useMemo(() => {
    return interviews.filter(iv => filterHR === 'all' || iv.hrId === filterHR);
  }, [interviews, filterHR]);

  const ws = startOfWeek(anchor);
  const we = new Date(ws); we.setDate(we.getDate() + 6);

  const navWeek = (dir) => {
    const n = new Date(anchor);
    n.setDate(n.getDate() + dir * 7);
    setAnchor(n);
  };
  const navMonth = (dir) => {
    const n = new Date(anchor);
    n.setMonth(n.getMonth() + dir);
    setAnchor(n);
  };

  const today = new Date(); today.setHours(0, 0, 0, 0);

  return (
    <div className="view">
      <div className="view-head">
        <div>
          <div className="title">Kalender Wawancara</div>
          <div className="subtitle">Jadwalkan dan kelola sesi wawancara kandidat. Color per HR memudahkan lihat workload tiap interviewer sekaligus.</div>
        </div>
        <div className="row-flex">
          <Btn kind="accent" icon="plus" onClick={() => setShowSched(true)}>Jadwalkan Wawancara</Btn>
        </div>
      </div>

      {/* Toolbar */}
      <div className="cal-toolbar">
        <div className="nav">
          <button onClick={() => mode === 'week' ? navWeek(-1) : navMonth(-1)}><Icon name="arrowL" size={14}/></button>
          <button onClick={() => setAnchor(new Date(today))}>Hari ini</button>
          <button onClick={() => mode === 'week' ? navWeek(1) : navMonth(1)}><Icon name="chevron" size={14}/></button>
        </div>
        <div className="range">
          {mode === 'week'
            ? `${ws.getDate()} – ${we.getDate()} ${MONTHS[we.getMonth()]} ${we.getFullYear()}`
            : `${MONTHS[anchor.getMonth()]} ${anchor.getFullYear()}`}
        </div>
        <div className="modes">
          <button className={mode === 'week' ? 'active' : ''} onClick={() => setMode('week')}>Minggu</button>
          <button className={mode === 'month' ? 'active' : ''} onClick={() => setMode('month')}>Bulan</button>
        </div>
        <div style={{ flex: 1 }}/>

        {/* HR filter */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: 3, background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 8 }}>
          <FilterChip active={filterHR === 'all'} onClick={() => setFilterHR('all')}>Semua HR</FilterChip>
          {HR_USERS.filter(h => !h.isOwner).map(hr => (
            <FilterChip key={hr.id} active={filterHR === hr.id} onClick={() => setFilterHR(hr.id)}>
              <HRAvatar hr={hr} size={14}/>
              {hr.name.split(' ')[0]}
            </FilterChip>
          ))}
        </div>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 300px', gap: 18, alignItems: 'start' }}>
        <div>
          {mode === 'week'
            ? <WeekView weekStart={ws} interviews={visibleInterviews} candidates={candidates} today={today} onClick={setSelectedIv} onSlotClick={() => setShowSched(true)}/>
            : <MonthView anchor={anchor} interviews={visibleInterviews} candidates={candidates} today={today} onClick={setSelectedIv}/>}
        </div>

        {/* Sidebar */}
        <div className="cal-side">
          <div className="card">
            <div className="section-title" style={{ marginBottom: 6 }}>Wawancara hari ini</div>
            <div style={{ fontSize: 12, color: 'var(--muted)', marginBottom: 6 }}>{DOW_LONG[(today.getDay()+6)%7]}, {today.getDate()} {MONTHS[today.getMonth()]}</div>
            <UpcomingList
              date={today}
              interviews={visibleInterviews}
              candidates={candidates}
              onClick={setSelectedIv}/>
          </div>

          <div className="card">
            <div className="section-title" style={{ marginBottom: 10 }}>Mode wawancara</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 12.5 }}>
              {Object.entries(window.TalentirData.INTERVIEW_MODES).map(([k, m]) => {
                const ct = visibleInterviews.filter(iv => iv.mode === k).length;
                return (
                  <div key={k} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <span style={{ width: 8, height: 8, borderRadius: 99, background: m.color }}/>
                    <span>{m.icon} {m.label}</span>
                    <span style={{ marginLeft: 'auto', fontWeight: 700, color: 'var(--muted)' }} className="mono">{ct}</span>
                  </div>
                );
              })}
            </div>
          </div>

          <div className="ai-block">
            <div className="lbl"><Icon name="sparkles" size={12}/>Saran Slot Otomatis</div>
            <div className="body" style={{ fontSize: 12.5 }}>
              AI mendeteksi 3 kandidat skor ≥85 belum diundang wawancara minggu ini. Mau auto-suggest slot ke HR yang paling longgar?
              <div style={{ marginTop: 8 }}>
                <Btn size="sm" kind="accent">+ Auto-jadwalkan 3 kandidat</Btn>
              </div>
            </div>
          </div>
        </div>
      </div>

      {showSched && <ScheduleModal
        prefilledCandidateId={typeof showSched === 'string' ? showSched : null}
        candidates={candidates}
        onClose={() => setShowSched(null)}
        onSave={(iv) => { addInterview(iv); setShowSched(null); }}/>}

      {selectedIv && <InterviewDetailModal
        interview={selectedIv}
        candidates={candidates}
        onClose={() => setSelectedIv(null)}
        onCancel={(id) => { cancelInterview(id); setSelectedIv(null); }}
        onReschedule={(iv) => { updateInterview(iv); setSelectedIv(iv); }}
        onOpenCandidate={(c) => { setSelectedIv(null); openCandidate(c); }}/>}
    </div>
  );
}

// ====== WEEK VIEW ======
function WeekView({ weekStart, interviews, candidates, today, onClick, onSlotClick }) {
  const days = Array.from({ length: 7 }, (_, i) => {
    const d = new Date(weekStart); d.setDate(d.getDate() + i); return d;
  });
  const hours = Array.from({ length: 10 }, (_, i) => 8 + i); // 08:00 - 17:00 (last row label 17, but cells go through 18)
  const todayStr = fmtDate(today);

  // For positioning events: 1 hour = 56px (.cw-daycell height)
  const PX_PER_MIN = 56 / 60;

  return (
    <div className="cal-week">
      {/* Header row */}
      <div className="cw-headrow">
        <div className="cw-cell" style={{ background: 'var(--bg-soft)' }}/>
        {days.map((d, i) => {
          const isToday = fmtDate(d) === todayStr;
          const isWeekend = i >= 5;
          return (
            <div key={i} className={'cw-cell ' + (isToday ? 'today' : '') + (isWeekend ? ' weekend' : '')}>
              <div className="dow">{DOW_SHORT[i]}</div>
              <div className="dnum">{d.getDate()}</div>
            </div>
          );
        })}
      </div>

      {/* Time rows */}
      {hours.map(h => (
        <React.Fragment key={h}>
          <div className="cw-timecell">{h.toString().padStart(2, '0')}:00</div>
          {days.map((d, i) => {
            const dateStr = fmtDate(d);
            const isWeekend = i >= 5;
            const isToday = dateStr === todayStr;
            // events that fall in this hour-cell (start within)
            const hourEvents = interviews.filter(iv => {
              if (iv.date !== dateStr) return false;
              const start = parseTime(iv.start);
              return start >= h * 60 && start < (h + 1) * 60;
            });
            return (
              <div key={i} className={'cw-daycell ' + (isWeekend ? 'weekend ' : '') + (isToday ? 'today-col' : '')} onClick={onSlotClick}>
                {hourEvents.map(iv => {
                  const c = candidates.find(x => x.id === iv.candidateId);
                  const hr = window.TalentirData.HR_USERS.find(x => x.id === iv.hrId);
                  const start = parseTime(iv.start);
                  const offsetTop = (start - h * 60) * PX_PER_MIN;
                  const height = iv.durationMin * PX_PER_MIN - 2;
                  return (
                    <div key={iv.id}
                         className={'cw-event ' + iv.status}
                         style={{
                           top: offsetTop,
                           height: height,
                           borderLeftColor: hr?.color || 'var(--accent)',
                           background: 'oklch(from ' + (hr?.avatar || 'var(--accent-2)') + ' l c h / 0.55)',
                         }}
                         onClick={(e) => { e.stopPropagation(); onClick(iv); }}>
                      <div className="ev-title">
                        {window.TalentirData.INTERVIEW_MODES[iv.mode].icon} {c?.name || 'Kandidat'}
                      </div>
                      <div className="ev-meta">{iv.start} · {hr?.name.split(' ')[0]}</div>
                    </div>
                  );
                })}
              </div>
            );
          })}
        </React.Fragment>
      ))}
    </div>
  );
}

// ====== MONTH VIEW ======
function MonthView({ anchor, interviews, candidates, today, onClick }) {
  const firstOfMonth = new Date(anchor.getFullYear(), anchor.getMonth(), 1);
  const gridStart = startOfWeek(firstOfMonth);
  const days = Array.from({ length: 42 }, (_, i) => {
    const d = new Date(gridStart); d.setDate(d.getDate() + i); return d;
  });
  const todayStr = fmtDate(today);
  return (
    <div className="cal-month">
      <div className="cm-headrow">
        {DOW_SHORT.map(d => <div key={d} className="h">{d}</div>)}
      </div>
      <div className="cm-grid">
        {days.map((d, i) => {
          const dateStr = fmtDate(d);
          const isOther = d.getMonth() !== anchor.getMonth();
          const isToday = dateStr === todayStr;
          const dayEvents = interviews.filter(iv => iv.date === dateStr).sort((a,b) => a.start.localeCompare(b.start));
          return (
            <div key={i} className={'cm-day ' + (isOther ? 'other ' : '') + (isToday ? 'today' : '')}>
              <div className="dn">{d.getDate()}</div>
              {dayEvents.slice(0, 3).map(iv => {
                const c = candidates.find(x => x.id === iv.candidateId);
                const hr = window.TalentirData.HR_USERS.find(x => x.id === iv.hrId);
                return (
                  <div key={iv.id} className="ev-pip" onClick={() => onClick(iv)}
                       style={{
                         borderLeftColor: hr?.color || 'var(--accent)',
                         background: 'oklch(from ' + (hr?.avatar || 'var(--accent-2)') + ' l c h / 0.55)',
                       }}>
                    <span style={{ fontFamily: 'var(--font-mono)', fontWeight: 700 }}>{iv.start}</span> {c?.name.split(' ')[0]}
                  </div>
                );
              })}
              {dayEvents.length > 3 && <div className="more">+{dayEvents.length - 3} lainnya</div>}
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ====== UPCOMING LIST ======
function UpcomingList({ date, interviews, candidates, onClick }) {
  const dateStr = fmtDate(date);
  const todays = interviews.filter(iv => iv.date === dateStr).sort((a,b) => a.start.localeCompare(b.start));
  if (todays.length === 0) return <div style={{ color: 'var(--muted)', fontSize: 12.5, padding: '10px 0' }}>Tidak ada jadwal hari ini.</div>;
  return (
    <>
      {todays.map(iv => {
        const c = candidates.find(x => x.id === iv.candidateId);
        const hr = window.TalentirData.HR_USERS.find(x => x.id === iv.hrId);
        return (
          <div key={iv.id} className="upcoming-row" onClick={() => onClick(iv)} style={{ cursor: 'pointer' }}>
            <div className="time-block">
              <div className="t">{iv.start}</div>
              <div className="dur">{iv.durationMin}min</div>
            </div>
            <div className="pill" style={{ background: hr?.color || 'var(--accent)' }}/>
            <div className="body">
              <div className="nm">{c?.name || 'Kandidat'}</div>
              <div className="meta">{window.TalentirData.INTERVIEW_MODES[iv.mode].icon} {window.TalentirData.INTERVIEW_MODES[iv.mode].label} · {hr?.name.split(' ')[0]}</div>
            </div>
          </div>
        );
      })}
    </>
  );
}

// ====== SCHEDULE MODAL ======
function ScheduleModal({ prefilledCandidateId, candidates, onClose, onSave }) {
  const { HR_USERS, INTERVIEW_MODES, JOBS } = window.TalentirData;
  const [cId, setCId] = useState(prefilledCandidateId || '');
  const [hrId, setHrId] = useState('');
  const [date, setDate] = useState(fmtDate(new Date()));
  const [time, setTime] = useState('10:00');
  const [dur, setDur] = useState(45);
  const [mode, setMode] = useState('zoom');
  const [meetingUrl, setMeetingUrl] = useState('');
  const [notes, setNotes] = useState('');

  const c = candidates.find(x => x.id === cId);
  useEffect(() => { if (c && c.assignedTo) setHrId(c.assignedTo); }, [cId]);

  // Candidates that make sense (wawancara stage or AI screened)
  const eligible = candidates.filter(x => ['wawancara-hr', 'wawancara-user', 'ai', 'baru'].includes(x.status));

  const save = () => {
    if (!cId || !hrId) return;
    onSave({
      id: 'iv-' + Date.now(),
      candidateId: cId,
      hrId, jobId: c?.jobId,
      date, start: time, durationMin: dur, mode,
      meetingUrl: (mode === 'zoom' || mode === 'wa-call') ? meetingUrl.trim() || null : null,
      status: 'confirmed', notes,
    });
  };

  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="modal" style={{ width: 640 }} onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h3 style={{ margin: 0, fontSize: 16, letterSpacing: '-0.01em' }}>Jadwalkan Wawancara</h3>
          <div style={{ flex: 1 }}/>
          <button className="btn icon ghost" onClick={onClose}><Icon name="x" size={14}/></button>
        </div>
        <div className="modal-body">
          <div className="field">
            <label>Kandidat</label>
            <select className="select" value={cId} onChange={(e) => setCId(e.target.value)}>
              <option value="">Pilih kandidat…</option>
              {eligible.map(x => {
                const j = JOBS.find(j => j.id === x.jobId);
                return <option key={x.id} value={x.id}>{x.name} — {j?.title} · skor {x.score}</option>;
              })}
            </select>
          </div>

          <div className="field">
            <label>HR Interviewer</label>
            {/* Show every HR on the account including the owner — small teams
                where the owner does interviews themselves are common, and
                hiding them left the list empty. */}
            {HR_USERS.length === 0 ? (
              <div style={{ padding: 12, border: '1px dashed var(--border)', borderRadius: 7, fontSize: 12.5, color: 'var(--muted)' }}>
                Belum ada HR. Tambahkan anggota tim di halaman <b>Tim</b> dulu.
              </div>
            ) : (
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6 }}>
                {HR_USERS.map(hr => (
                  <label key={hr.id}
                         style={{
                           display: 'flex', gap: 8, alignItems: 'center',
                           padding: '8px 12px',
                           border: '1px solid ' + (hrId === hr.id ? 'var(--accent)' : 'var(--border)'),
                           background: hrId === hr.id ? 'var(--accent-2)' : 'var(--surface)',
                           borderRadius: 7, cursor: 'pointer',
                         }}>
                    <input type="radio" checked={hrId === hr.id} onChange={() => setHrId(hr.id)} style={{ accentColor: 'var(--accent)' }}/>
                    <HRAvatar hr={hr} size={22}/>
                    <div style={{ minWidth: 0, flex: 1 }}>
                      <div style={{ fontWeight: 700, fontSize: 12.5 }}>{hr.name}{hr.isOwner && <span style={{ marginLeft: 6, fontSize: 10, color: 'var(--muted)', fontWeight: 500 }}>(owner)</span>}</div>
                      <div style={{ fontSize: 10.5, color: 'var(--muted)' }}>{hr.branch || hr.role}</div>
                    </div>
                  </label>
                ))}
              </div>
            )}
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
            <div className="field">
              <label>Tanggal</label>
              <input className="input" type="date" value={date} onChange={(e) => setDate(e.target.value)}/>
            </div>
            <div className="field">
              <label>Jam mulai</label>
              <input className="input" type="time" value={time} onChange={(e) => setTime(e.target.value)}/>
            </div>
            <div className="field">
              <label>Durasi</label>
              <select className="select" value={dur} onChange={(e) => setDur(+e.target.value)}>
                <option value={30}>30 menit</option>
                <option value={45}>45 menit</option>
                <option value={60}>60 menit</option>
                <option value={90}>90 menit</option>
              </select>
            </div>
          </div>

          <div className="field">
            <label>Mode wawancara</label>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 6 }}>
              {Object.entries(INTERVIEW_MODES).map(([k, m]) => (
                <label key={k}
                       style={{
                         display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
                         padding: '10px 8px',
                         border: '1px solid ' + (mode === k ? 'var(--accent)' : 'var(--border)'),
                         background: mode === k ? 'var(--accent-2)' : 'var(--surface)',
                         borderRadius: 7, cursor: 'pointer',
                       }}>
                  <input type="radio" checked={mode === k} onChange={() => setMode(k)} style={{ display: 'none' }}/>
                  <div style={{ fontSize: 22 }}>{m.icon}</div>
                  <div style={{ fontSize: 11.5, fontWeight: 600 }}>{m.label}</div>
                </label>
              ))}
            </div>
          </div>

          {(mode === 'zoom' || mode === 'wa-call') && (
            <div className="field">
              <label>Link meeting {mode === 'zoom' ? '(Zoom / Google Meet)' : '(WhatsApp call)'}</label>
              <input className="input" value={meetingUrl} onChange={(e) => setMeetingUrl(e.target.value)}
                     placeholder="https://zoom.us/j/…"/>
              <span className="hint">Dikirim ke kandidat bersama undangan. Kosongkan jika belum ada.</span>
            </div>
          )}

          <div className="field">
            <label>Catatan untuk kandidat (opsional)</label>
            <textarea className="textarea" value={notes} onChange={(e) => setNotes(e.target.value)}
                      placeholder="Mis. agenda, lokasi cabang, dll. AI akan otomatis mengirim ke kandidat via WhatsApp."/>
          </div>

          <div className="ai-block">
            <div className="lbl"><Icon name="message" size={12}/>Auto-send via WhatsApp</div>
            <div className="body" style={{ fontSize: 12.5 }}>
              Setelah disimpan, Talentir Bot akan otomatis kirim konfirmasi jadwal + reminder H-1 ke nomor kandidat.
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <Btn onClick={onClose}>Batal</Btn>
          <Btn kind="accent" icon="check" onClick={save} disabled={!cId || !hrId}>Jadwalkan & Kirim Undangan</Btn>
        </div>
      </div>
    </div>
  );
}

// ====== Interview detail modal ======
function InterviewDetailModal({ interview, candidates, onClose, onCancel, onReschedule, onOpenCandidate }) {
  const { HR_USERS, INTERVIEW_MODES, JOBS } = window.TalentirData;
  const c = candidates.find(x => x.id === interview.candidateId);
  const hr = HR_USERS.find(x => x.id === interview.hrId);
  const job = JOBS.find(j => j.id === interview.jobId);
  const m = INTERVIEW_MODES[interview.mode];
  const [edit, setEdit] = useState(false);
  const [form, setForm] = useState({
    date: interview.date, start: interview.start, durationMin: interview.durationMin,
    mode: interview.mode, status: interview.status, hrId: interview.hrId,
    meetingUrl: interview.meetingUrl || '',
  });
  const setF = (k) => (e) => setForm(s => ({ ...s, [k]: e.target.value }));
  const saveEdit = () => {
    onReschedule({ ...interview, ...form, durationMin: Number(form.durationMin), meetingUrl: form.meetingUrl.trim() || null });
    setEdit(false);
  };

  // Copy the meeting link.
  const [copied, setCopied] = useState(false);
  const copyLink = async () => {
    try { await navigator.clipboard.writeText(interview.meetingUrl); setCopied(true); setTimeout(() => setCopied(false), 1500); }
    catch (e) { console.error('Gagal menyalin link:', e); }
  };

  // Send a WhatsApp reminder to the candidate via the backend (queued + logged).
  const [reminding, setReminding] = useState(''); // '' | sending | sent | error
  const sendReminder = async () => {
    if (!c) return;
    setReminding('sending');
    const d = new Date(interview.date + 'T00:00:00');
    const tgl = `${DOW_LONG[(d.getDay() + 6) % 7]}, ${d.getDate()} ${MONTHS[d.getMonth()]}`;
    const modeLabel = (INTERVIEW_MODES[interview.mode] || {}).label || interview.mode;
    const msg = [
      `Halo ${c.name.split(' ')[0]}! 👋 Pengingat jadwal wawancara Anda` + (job ? ` untuk posisi ${job.title}` : '') + '.',
      `🗓️ ${tgl}, pukul ${interview.start} (${interview.durationMin} menit)`,
      `📍 Mode: ${modeLabel}`,
      interview.meetingUrl ? `🔗 Link: ${interview.meetingUrl}` : null,
      `Mohon konfirmasi kehadiran ya. Terima kasih! 🙏`,
    ].filter(Boolean).join('\n');
    try {
      await window.TalentirAPI.post('/api/candidates/' + c.id + '/wa-send', { content: msg });
      setReminding('sent'); setTimeout(() => setReminding(''), 2500);
    } catch (e) { console.error('Gagal mengirim reminder:', e); setReminding('error'); setTimeout(() => setReminding(''), 3000); }
  };

  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="modal" style={{ width: 520 }} onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h3 style={{ margin: 0, fontSize: 16, letterSpacing: '-0.01em' }}>Detail Wawancara</h3>
          <Badge kind={interview.status === 'confirmed' ? 'good' : interview.status === 'pending' ? 'warn' : 'accent'} style={{ marginLeft: 8 }}>
            <span className="dot"/>
            {interview.status === 'confirmed' ? 'Confirmed' : interview.status === 'pending' ? 'Pending' : 'Dijadwal ulang'}
          </Badge>
          <div style={{ flex: 1 }}/>
          <button className="btn icon ghost" onClick={onClose}><Icon name="x" size={14}/></button>
        </div>
        <div className="modal-body">
          {c && (
            <div className="row-flex" style={{ padding: '12px 14px', background: 'var(--bg-soft)', border: '1px solid var(--border)', borderRadius: 8 }}>
              <Avatar name={c.name}/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontWeight: 700 }}>{c.name}</div>
                <div style={{ fontSize: 12, color: 'var(--muted)' }}>{job?.title} · skor AI {c.score}</div>
              </div>
              <Btn size="sm" onClick={() => onOpenCandidate(c)}>Buka profil →</Btn>
            </div>
          )}

          {edit ? (
            <div className="col-flex" style={{ gap: 12, marginTop: 4 }}>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                <div className="field"><label>Tanggal</label><input className="input" type="date" value={form.date} onChange={setF('date')}/></div>
                <div className="field"><label>Jam mulai</label><input className="input" type="time" value={form.start} onChange={setF('start')}/></div>
                <div className="field"><label>Durasi (menit)</label><input className="input" type="number" value={form.durationMin} onChange={setF('durationMin')}/></div>
                <div className="field"><label>Mode</label>
                  <select className="select" value={form.mode} onChange={setF('mode')}>
                    {Object.entries(INTERVIEW_MODES).map(([k, v]) => <option key={k} value={k}>{v.icon} {v.label}</option>)}
                  </select>
                </div>
                <div className="field"><label>Interviewer</label>
                  <select className="select" value={form.hrId || ''} onChange={setF('hrId')}>
                    {HR_USERS.map(h => <option key={h.id} value={h.id}>{h.name}</option>)}
                  </select>
                </div>
                <div className="field"><label>Status</label>
                  <select className="select" value={form.status} onChange={setF('status')}>
                    <option value="confirmed">Confirmed</option>
                    <option value="pending">Pending</option>
                    <option value="rescheduled">Dijadwal ulang</option>
                  </select>
                </div>
              </div>
              {(form.mode === 'zoom' || form.mode === 'wa-call') && (
                <div className="field"><label>Link meeting</label>
                  <input className="input" value={form.meetingUrl} onChange={setF('meetingUrl')} placeholder="https://zoom.us/j/…"/>
                </div>
              )}
            </div>
          ) : (
          <dl className="kv">
            <dt>Tanggal</dt><dd>{(() => {
              const d = new Date(interview.date + 'T00:00:00');
              return `${DOW_LONG[(d.getDay()+6)%7]}, ${d.getDate()} ${MONTHS[d.getMonth()]} ${d.getFullYear()}`;
            })()}</dd>
            <dt>Waktu</dt><dd className="mono">{interview.start} – {(() => {
              const t = parseTime(interview.start) + interview.durationMin;
              const h = Math.floor(t / 60), m = t % 60;
              return `${h.toString().padStart(2,'0')}:${m.toString().padStart(2,'0')}`;
            })()} ({interview.durationMin} menit)</dd>
            <dt>Mode</dt><dd>{m.icon} {m.label}</dd>
            <dt>Interviewer</dt>
            <dd>
              <div className="row-flex">
                <HRAvatar hr={hr} size={22}/>
                <strong>{hr?.name}</strong>
                <span style={{ color: 'var(--muted)', fontSize: 12 }}>· {hr?.branch}</span>
              </div>
            </dd>
            {interview.notes && <><dt>Catatan</dt><dd style={{ fontSize: 12.5 }}>{interview.notes}</dd></>}
          </dl>
          )}

          {!edit && interview.meetingUrl && (
            <div className="row-flex" style={{ padding: 10, background: 'var(--bg-soft)', border: '1px solid var(--border)', borderRadius: 7 }}>
              <Icon name="link" size={14}/>
              <a href={interview.meetingUrl} target="_blank" rel="noopener" className="mono" style={{ fontSize: 12, flex: 1, color: 'var(--ink-2)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{interview.meetingUrl.replace(/^https?:\/\//, '')}</a>
              <button className="btn ghost sm" onClick={copyLink}><Icon name={copied ? 'check' : 'copy'} size={12}/>{copied ? 'Tersalin' : 'Salin'}</button>
            </div>
          )}
        </div>
        <div className="modal-foot">
          {edit ? (
            <>
              <Btn onClick={() => setEdit(false)}>Batal</Btn>
              <div style={{ flex: 1 }}/>
              <Btn kind="accent" icon="check" onClick={saveEdit}>Simpan jadwal</Btn>
            </>
          ) : (
            <>
              <Btn icon="message" kind="wa" onClick={sendReminder} disabled={!c || !c.phone || reminding === 'sending'}>
                {reminding === 'sent' ? 'Terkirim ✓' : reminding === 'sending' ? 'Mengirim…' : reminding === 'error' ? 'Gagal — ulangi' : 'Kirim Reminder'}
              </Btn>
              <div style={{ flex: 1 }}/>
              <Btn icon="pencil" onClick={() => setEdit(true)}>Edit</Btn>
              <Btn icon="trash" onClick={() => onCancel(interview.id)}>Batalkan</Btn>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

window.CalendarView = CalendarView;
