/* global React, window */
const { useState: useLeaveState, useEffect: useLeaveEffect } = React;

const LEAVE_TYPE_META = {
  sick:     { label: 'ลาป่วย',  chip: 'c-coral' },
  personal: { label: 'ลากิจ',   chip: 'c-amber' },
  vacation: { label: 'พักร้อน', chip: 'c-green' },
  other:    { label: 'อื่นๆ',    chip: 'c-blue' },
};
const LEAVE_STATUS = {
  pending:  { label: 'รออนุมัติ', chip: 'c-amber' },
  approved: { label: 'อนุมัติ',    chip: 'c-green' },
  rejected: { label: 'ปฏิเสธ',     chip: 'c-gray' },
};
function leaveDays(a, b) {
  try { const d1 = new Date(a), d2 = new Date(b); const n = Math.round((d2 - d1) / 86400000) + 1; return n > 0 ? n : 1; } catch (e) { return 1; }
}

// Circular face avatar (clickable → profile).
function LvAvatar({ id, size = 44 }) {
  const [err, setErr] = useLeaveState(false);
  const src = (err || !id) ? '/img/avatar-person.svg' : `/faces/${id}.jpg`;
  return <img src={src} alt="" onError={() => setErr(true)}
    onClick={() => id && window.openProfile && window.openProfile(id)} title={id ? 'ดูโปรไฟล์' : ''}
    style={{ width: size, height: size, borderRadius: '50%', objectFit: 'cover', flex: 'none',
      cursor: id ? 'pointer' : 'default', border: '1px solid var(--line)' }} />;
}

// ระบบลา — request + approve. HR/admin/manager can approve; everyone can request.
function LeavePage({ role }) {
  const [list, setList] = useLeaveState([]);
  const [statusFilter, setStatusFilter] = useLeaveState('all');
  const [requesting, setRequesting] = useLeaveState(false);
  const [balEmp, setBalEmp] = useLeaveState((window.CURRENT_USER && window.CURRENT_USER.employee_id) || ((window.EMPLOYEES || [])[0] || {}).id || '');
  const [balance, setBalance] = useLeaveState([]);
  const canApprove = role === 'admin' || role === 'hr' || role === 'manager';

  const load = async () => {
    const q = statusFilter === 'all' ? '' : `?status=${statusFilter}`;
    const r = await fetch('/api/leaves' + q, { credentials: 'include' });
    if (r.ok) setList(await r.json());
  };
  useLeaveEffect(() => { load(); }, [statusFilter]);

  const loadBalance = async () => {
    if (!balEmp) { setBalance([]); return; }
    const r = await fetch(`/api/leaves/balance?employee_id=${encodeURIComponent(balEmp)}`, { credentials: 'include' });
    if (r.ok) { const d = await r.json(); setBalance(d.balance || []); }
  };
  useLeaveEffect(() => { loadBalance(); }, [balEmp]);

  const approve = async (id) => {
    await fetch(`/api/leaves/${id}/approve`, { method: 'PUT', credentials: 'include' });
    window.appToast && window.appToast('อนุมัติแล้ว', { tone: 'success' }); load(); loadBalance();
  };
  const reject = async (id) => {
    const reason = await window.appPrompt({ title: 'เหตุผลที่ไม่อนุมัติ', placeholder: 'ระบุเหตุผล (ไม่บังคับ)' });
    if (reason === null) return;
    await fetch(`/api/leaves/${id}/reject`, { method: 'PUT', credentials: 'include',
      headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ reason }) });
    window.appToast && window.appToast('ปฏิเสธแล้ว', { tone: 'info' }); load(); loadBalance();
  };

  const fmtRange = (a, b) => a === b ? a : `${a} – ${b}`;
  const countBy = (s) => list.filter((l) => l.status === s).length;
  const stats = [['รออนุมัติ', countBy('pending'), 'var(--yellow-ink)'], ['อนุมัติแล้ว', countBy('approved'), 'var(--mint)'], ['ปฏิเสธ', countBy('rejected'), 'var(--ink-4)']];

  return (
    <div data-screen-label="Leave">
      <div style={{ marginBottom: 16 }}>
        <h1 style={{ fontFamily: 'var(--font-display)', fontSize: 22, fontWeight: 700, margin: 0 }}>การลา / Leave</h1>
        <div style={{ fontSize: 12.5, color: 'var(--ink-4)', marginTop: 4 }}>ยื่นใบลา · อนุมัติ · ยอดวันลาคงเหลือ</div>
      </div>

      {/* stats */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 14, marginBottom: 16 }}>
        {stats.map(([k, v, c]) => (
          <div key={k} className="gv-card" style={{ padding: '16px 20px', boxShadow: 'var(--shadow-sm)', display: 'flex', alignItems: 'baseline', gap: 12 }}>
            <div className="tnum" style={{ fontFamily: 'var(--font-display)', fontSize: 34, fontWeight: 700, lineHeight: 1, color: c }}>{v}</div>
            <div style={{ fontSize: 13, color: 'var(--ink-4)', fontWeight: 500 }}>{k}</div>
          </div>
        ))}
      </div>

      {canApprove && <CorrectionsPanel/>}

      {/* leave requests */}
      <div className="gv-card" style={{ marginBottom: 16 }}>
        <div className="gv-card-h" style={{ flexWrap: 'wrap', gap: 10 }}>
          <b>คำขอลา</b>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
            <div className="gv-seg">
              {['all', 'pending', 'approved', 'rejected'].map((s) => (
                <button key={s} className={statusFilter === s ? 'on' : ''} onClick={() => setStatusFilter(s)}>{s === 'all' ? 'ทั้งหมด' : LEAVE_STATUS[s].label}</button>
              ))}
            </div>
            <button className="gv-btn ok sm" onClick={() => setRequesting(true)}>＋ ยื่นใบลา</button>
          </div>
        </div>
        <div className="gv-card-b" style={{ paddingTop: 6 }}>
          {list.length === 0 ? <div className="gv-empty">— ไม่มีใบลา —</div>
            : list.map((l) => {
              const t = LEAVE_TYPE_META[l.leave_type] || LEAVE_TYPE_META.other;
              const st = LEAVE_STATUS[l.status] || LEAVE_STATUS.pending;
              return (
                <div key={l.id} className="gv-row">
                  <LvAvatar id={l.employee_id} />
                  <div style={{ minWidth: 140 }}>
                    <div style={{ fontSize: 14.5, fontWeight: 600 }}>{l.first_name} {l.last_name}</div>
                    <div style={{ fontSize: 11.5, color: 'var(--ink-4)', marginTop: 2 }}>{l.employee_id}{l.department_name ? ` · ${l.department_name}` : ''}</div>
                  </div>
                  <div style={{ minWidth: 150 }}>
                    <span className={`gv-chip ${t.chip}`}>{t.label}</span>
                    <div style={{ fontSize: 11.5, color: 'var(--ink-4)', marginTop: 4 }}>{fmtRange(l.start_date, l.end_date)} · {leaveDays(l.start_date, l.end_date)} วัน</div>
                  </div>
                  <div style={{ flex: 1, fontSize: 13, color: 'var(--ink-4)', minWidth: 0 }}>{l.reason || '—'}</div>
                  {canApprove && l.status === 'pending' ? (
                    <div style={{ display: 'flex', gap: 6, flexShrink: 0 }}>
                      <button className="gv-btn no sm" onClick={() => reject(l.id)}>ปฏิเสธ</button>
                      <button className="gv-btn ok sm" onClick={() => approve(l.id)}>อนุมัติ</button>
                    </div>
                  ) : (
                    <span className={`gv-chip ${st.chip}`} style={{ flexShrink: 0 }}>{st.label}</span>
                  )}
                </div>
              );
            })}
        </div>
      </div>

      {/* leave balance */}
      <div className="gv-card">
        <div className="gv-card-h" style={{ flexWrap: 'wrap', gap: 10 }}>
          <b>ยอดวันลาคงเหลือปีนี้</b>
          <select className="gv-select" value={balEmp} onChange={(e) => setBalEmp(e.target.value)} style={{ maxWidth: 260, width: 'auto' }}>
            <option value="">— เลือกพนักงาน —</option>
            {(window.EMPLOYEES || []).map((e) => <option key={e.id} value={e.id}>{e.first_name} {e.last_name} ({e.id})</option>)}
          </select>
        </div>
        <div className="gv-card-b">
          {balance.length === 0 ? <div className="gv-empty">เลือกพนักงานเพื่อดูยอดคงเหลือ</div>
            : <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))', gap: 12 }}>
                {balance.map((b) => {
                  const pct = b.quota ? Math.round((b.used / b.quota) * 100) : 0;
                  const barColor = b.color === 'coral' ? 'var(--coral)' : b.color === 'yellow' ? 'var(--yellow)' : b.color === 'mint' ? 'var(--mint)' : 'var(--primary)';
                  return (
                    <div key={b.code} style={{ padding: 14, background: 'var(--surface-2)', borderRadius: 'var(--r-md)' }}>
                      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
                        <span className="gv-chip c-gray">{b.name}</span>
                        {!b.paid && <span style={{ fontSize: 10.5, color: 'var(--ink-5)' }}>ไม่จ่าย</span>}
                      </div>
                      {b.quota ? (
                        <>
                          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
                            <span className="tnum" style={{ fontFamily: 'var(--font-display)', fontSize: 26, fontWeight: 700 }}>{b.remaining}</span>
                            <span style={{ fontSize: 11.5, color: 'var(--ink-4)' }}>/ {b.quota} วัน</span>
                          </div>
                          <div className="gv-bar" style={{ marginTop: 8 }}><i style={{ width: `${pct}%`, background: barColor }} /></div>
                          <div style={{ fontSize: 11, color: 'var(--ink-4)', marginTop: 5 }}>ใช้ไป {b.used} วัน</div>
                        </>
                      ) : <div style={{ fontSize: 12.5, color: 'var(--ink-4)' }}>ใช้ไป {b.used} · ไม่จำกัด</div>}
                    </div>
                  );
                })}
              </div>}
        </div>
      </div>

      {requesting && <LeaveModal onClose={() => setRequesting(false)} onSaved={() => { setRequesting(false); load(); }}/>}
    </div>
  );
}

function LeaveModal({ onClose, onSaved }) {
  const [empId, setEmpId] = useLeaveState((window.CURRENT_USER && window.CURRENT_USER.employee_id) || '');
  const [type, setType] = useLeaveState('sick');
  const [start, setStart] = useLeaveState(window.TODAY || new Date().toISOString().slice(0, 10));
  const [end, setEnd] = useLeaveState(window.TODAY || new Date().toISOString().slice(0, 10));
  const [reason, setReason] = useLeaveState('');
  const [busy, setBusy] = useLeaveState(false);
  const [err, setErr] = useLeaveState('');

  const save = async () => {
    if (!empId) { setErr('กรุณาเลือกพนักงาน'); return; }
    if (end < start) { setErr('วันสิ้นสุดต้องไม่ก่อนวันเริ่ม'); return; }
    setBusy(true); setErr('');
    try {
      const r = await fetch('/api/leaves', { method: 'POST', credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ employee_id: empId, leave_type: type, start_date: start, end_date: end, reason: reason.trim() }) });
      const d = await r.json().catch(() => ({}));
      if (!r.ok) throw new Error(d.error || `error ${r.status}`);
      window.appToast && window.appToast('ยื่นใบลาแล้ว', { tone: 'success' });
      onSaved();
    } catch (e) { setErr(e.message); } finally { setBusy(false); }
  };

  return (
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 200, background: 'rgba(15,23,42,.45)', display: 'grid', placeItems: 'center', padding: 20 }}>
      <div className="gv-card" onClick={(e) => e.stopPropagation()} style={{ width: 'min(500px,100%)', maxHeight: '90vh', overflow: 'auto' }}>
        <div className="gv-card-h"><b>ยื่นใบลา</b></div>
        <div className="gv-card-b" style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <div className="gv-field">
            <label>พนักงาน *</label>
            <select className="gv-select" value={empId} onChange={(e) => setEmpId(e.target.value)}>
              <option value="">— เลือกพนักงาน —</option>
              {(window.EMPLOYEES || []).map((e) => <option key={e.id} value={e.id}>{e.first_name} {e.last_name} ({e.id})</option>)}
            </select>
          </div>
          <div className="gv-field">
            <label>ประเภทการลา</label>
            <div style={{ display: 'flex', gap: 6 }}>
              {Object.keys(LEAVE_TYPE_META).map((k) => (
                <button key={k} type="button" onClick={() => setType(k)}
                  className={`gv-btn ${type === k ? 'dark' : 'no'} sm`} style={{ flex: 1 }}>{LEAVE_TYPE_META[k].label}</button>
              ))}
            </div>
          </div>
          <div style={{ display: 'flex', gap: 12 }}>
            <div className="gv-field" style={{ flex: 1, marginBottom: 0 }}>
              <label>วันเริ่ม</label>
              <input className="gv-input" type="date" value={start} onChange={(e) => setStart(e.target.value)}/>
            </div>
            <div className="gv-field" style={{ flex: 1, marginBottom: 0 }}>
              <label>วันสิ้นสุด</label>
              <input className="gv-input" type="date" value={end} onChange={(e) => setEnd(e.target.value)}/>
            </div>
          </div>
          <div className="gv-field">
            <label>เหตุผล</label>
            <input className="gv-input" value={reason} onChange={(e) => setReason(e.target.value)} placeholder="(ไม่บังคับ)"/>
          </div>
          {err && <div style={{ padding: '10px 14px', borderRadius: 10, background: 'var(--coral-soft)', color: 'var(--coral-ink)', fontSize: 12.5, fontWeight: 600 }}>{err}</div>}
          <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 4 }}>
            <button className="gv-btn no" onClick={onClose} disabled={busy}>ยกเลิก</button>
            <button className="gv-btn ok" onClick={save} disabled={busy}>{busy ? 'กำลังส่ง…' : 'ยื่นใบลา'}</button>
          </div>
        </div>
      </div>
    </div>
  );
}

// HR/admin approval of "ลืมสแกน" time-correction requests.
function CorrectionsPanel() {
  const [list, setList] = useLeaveState([]);
  const load = async () => {
    const r = await fetch('/api/corrections?status=pending', { credentials: 'include' });
    if (r.ok) setList(await r.json());
  };
  useLeaveEffect(() => { load(); }, []);
  const act = async (id, action) => {
    if (action === 'reject') {
      const reason = await window.appPrompt({ title: 'เหตุผลที่ปฏิเสธ', placeholder: '(ไม่บังคับ)' });
      if (reason === null) return;
      await fetch(`/api/corrections/${id}/reject`, { method: 'PUT', credentials: 'include', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ reason }) });
      window.appToast && window.appToast('ปฏิเสธแล้ว', { tone: 'info' });
    } else {
      const r = await fetch(`/api/corrections/${id}/approve`, { method: 'PUT', credentials: 'include' });
      const d = await r.json().catch(() => ({}));
      if (!r.ok) { window.appToast && window.appToast(d.error || 'อนุมัติไม่สำเร็จ', { tone: 'error' }); return; }
      window.appToast && window.appToast('อนุมัติ + ลงเวลาให้แล้ว', { tone: 'success' });
    }
    load();
  };
  if (list.length === 0) return null;
  return (
    <div className="gv-card" style={{ marginBottom: 16 }}>
      <div className="gv-card-h">
        <b>⏱️ ขอแก้เวลา (ลืมสแกน)</b>
        <span className="gv-chip c-amber">{list.length} รออนุมัติ</span>
      </div>
      <div className="gv-card-b" style={{ paddingTop: 6 }}>
        {list.map((c) => (
          <div key={c.id} className="gv-row">
            <LvAvatar id={c.employee_id} size={40} />
            <div style={{ minWidth: 140 }}>
              <div style={{ fontSize: 14, fontWeight: 600 }}>{`${c.first_name || ''} ${c.last_name || ''}`.trim() || c.employee_id}</div>
              <div style={{ fontSize: 11.5, color: 'var(--ink-4)', marginTop: 2 }}>{c.employee_id}{c.department_name ? ` · ${c.department_name}` : ''}</div>
            </div>
            <div style={{ minWidth: 140 }}>
              <div style={{ fontSize: 13.5 }}><span style={{ color: c.punch_type === 'out' ? 'var(--primary)' : 'var(--mint-ink)', fontWeight: 600 }}>{c.punch_type === 'out' ? 'ออกงาน' : 'เข้างาน'}</span> {c.proposed_time}</div>
              <div style={{ fontSize: 11.5, color: 'var(--ink-4)', marginTop: 2 }}>{c.date}</div>
            </div>
            <div style={{ flex: 1, fontSize: 13, color: 'var(--ink-4)', minWidth: 0 }}>{c.reason || '—'}</div>
            <div style={{ display: 'flex', gap: 6, flexShrink: 0 }}>
              <button className="gv-btn no sm" onClick={() => act(c.id, 'reject')}>ปฏิเสธ</button>
              <button className="gv-btn ok sm" onClick={() => act(c.id, 'approve')}>อนุมัติ</button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

window.LeavePage = LeavePage;
