const { useState, useEffect, useCallback } = React;

const AttendanceRegister = ({ registerContext, faculty, onBack }) => {
  // registerContext: { course, exam_id, lecture_type, batch_id, dept_id, sem }
  const { course, exam_id, lecture_type, batch_id, dept_id, sem } = registerContext;

  const [sessions, setSessions] = useState([]);
  const [students, setStudents] = useState([]);
  const [records, setRecords] = useState({}); // { session_id: { enrollment_no: true/false } }
  const [dirty, setDirty] = useState({}); // same shape — only changed cells
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [saveMsg, setSaveMsg] = useState('');
  const [togglingLock, setTogglingLock] = useState(null); // session id being toggled

  // New lecture modal
  const [showModal, setShowModal] = useState(false);
  const [newLecture, setNewLecture] = useState({
    date: new Date().toISOString().split('T')[0],
    start_time: '09:00',
    duration: 1,
    topic: ''
  });
  const [creating, setCreating] = useState(false);
  const [createError, setCreateError] = useState('');

  // ── Load register data ──────────────────────────────────────────────────────
  const loadRegister = useCallback(async () => {
    setLoading(true);
    try {
      const params = new URLSearchParams({ course_id: course.id, exam_id, lecture_type, dept_id, sem });
      if (lecture_type !== 'Theory' && batch_id) params.set('batch_id', batch_id);

      const res = await fetch(`/api/attendance/register?${params}`);
      if (!res.ok) throw new Error('Failed to load');
      const data = await res.json();
      setSessions(data.sessions || []);
      setStudents(data.students || []);
      setRecords(data.records || {});
      setDirty({});
    } catch (e) {
      console.error(e);
    } finally {
      setLoading(false);
    }
  }, [course.id, exam_id, lecture_type, batch_id, dept_id, sem]);

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

  // ── Get cell value (dirty overrides persisted) ──────────────────────────────
  const getCellValue = (sessionId, enrollmentNo) => {
    if (dirty[sessionId] && dirty[sessionId][enrollmentNo] !== undefined) {
      return dirty[sessionId][enrollmentNo];
    }
    return !!(records[sessionId] && records[sessionId][enrollmentNo]);
  };

  // ── Toggle checkbox ─────────────────────────────────────────────────────────
  const handleCellToggle = (sessionId, enrollmentNo, currentValue) => {
    const session = sessions.find(s => s.id === sessionId);
    if (session?.is_locked) return; // locked — do nothing
    setDirty(prev => ({
      ...prev,
      [sessionId]: { ...(prev[sessionId] || {}), [enrollmentNo]: !currentValue }
    }));
  };

  // ─── Save all dirty records ───
  const handleSave = async () => {
    const dirtySessionIds = Object.keys(dirty);
    if (dirtySessionIds.length === 0) return;

    setSaving(true);
    setSaveMsg('Saving changes...');
    let errors = 0;
    let lastErrorMessage = '';

    try {
      for (const sessionId of dirtySessionIds) {
        const sessionDirty = dirty[sessionId];
        const recordsPayload = Object.entries(sessionDirty).map(([enrollment_no, is_present]) => ({
          student_enrollment_no: enrollment_no,
          is_present
        }));

        const res = await fetch('/api/attendance/records', {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ session_id: parseInt(sessionId), records: recordsPayload })
        });

        if (!res.ok) {
          errors++;
          const errorData = await res.json();
          lastErrorMessage = errorData.error || 'Failed to save some records.';
        } else {
          // Merge dirty into records
          setRecords(prev => ({
            ...prev,
            [sessionId]: { ...(prev[sessionId] || {}), ...sessionDirty }
          }));
          // Remove from dirty once saved successfully
          setDirty(prev => {
            const next = { ...prev };
            delete next[sessionId];
            return next;
          });
        }
      }

      if (errors > 0) {
        setSaveMsg(`⚠️ ${errors} session(s) failed: ${lastErrorMessage}`);
      } else {
        setSaveMsg('✅ All changes saved successfully!');
      }
    } catch (e) {
      setSaveMsg('Network error while saving.');
    } finally {
      setSaving(false);
      setTimeout(() => setSaveMsg(''), 5000);
    }
  };

  const handleToggleLock = async (session) => {
    if (togglingLock) return;
    const action = session.is_locked ? 'unlock' : 'lock';
    if (!window.confirm(`${action.charAt(0).toUpperCase() + action.slice(1)} attendance for ${formatDate(session.date)}?`)) return;
    setTogglingLock(session.id);
    try {
      const res = await fetch(`/api/attendance/session/${session.id}/lock`, { method: 'PATCH' });
      if (res.ok) {
        const data = await res.json();
        setSessions(prev => prev.map(s => s.id === session.id ? { ...s, is_locked: data.is_locked } : s));
      }
    } catch (e) { console.error(e); }
    finally { setTogglingLock(null); }
  };

  // ── Create new lecture ──────────────────────────────────────────────────────
  const handleCreateLecture = async () => {
    if (!newLecture.topic.trim()) { setCreateError('Topic is required.'); return; }
    setCreating(true);
    setCreateError('');
    try {
      const res = await fetch('/api/attendance/session', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          faculty_id: faculty.id,
          course_id: course.id,
          exam_id,
          lecture_type,
          batch_id: lecture_type !== 'Theory' ? (batch_id || null) : null,
          dept_id,
          class_sem: sem,
          date: newLecture.date,
          start_time: newLecture.start_time,
          duration: newLecture.duration,
          topic: newLecture.topic
        })
      });
      const data = await res.json();
      if (res.ok) {
        setShowModal(false);
        setNewLecture({ date: new Date().toISOString().split('T')[0], start_time: '09:00', duration: 1, topic: '' });
        await loadRegister();
      } else if (res.status === 409) {
        setCreateError(data.error || 'A session already exists at this date and time.');
      } else {
        setCreateError(data.error || 'Failed to create session.');
      }
    } catch (e) {
      setCreateError('Network error.');
    } finally {
      setCreating(false);
    }
  };

  // ── Helpers ─────────────────────────────────────────────────────────────────
  const formatDate = (d) => {
    if (!d) return '';
    const date = new Date(d + 'T00:00:00');
    return date.toLocaleDateString('en-IN', { day: '2-digit', month: 'short' });
  };

  const formatTime = (t) => {
    if (!t) return '';
    const [h, m] = t.split(':');
    const hr = parseInt(h);
    return `${hr > 12 ? hr - 12 : hr}:${m} ${hr >= 12 ? 'PM' : 'AM'}`;
  };

  const hasDirty = Object.keys(dirty).length > 0;
  const totalSessions = sessions.length;

  // ── Per-session present count ────────────────────────────────────────────────
  const sessionPresentCount = (sessionId) => {
    return students.filter(st => getCellValue(sessionId, st.enrollment_no)).length;
  };

  // ── Type badge color ─────────────────────────────────────────────────────────
  const typeBadge = {
    Theory: 'bg-blue-100 text-blue-700',
    Practical: 'bg-emerald-100 text-emerald-700',
    Tutorial: 'bg-violet-100 text-violet-700'
  }[lecture_type] || 'bg-gray-100 text-gray-700';

  if (loading) {
    return (
      <div className="flex-1 flex flex-col items-center justify-center min-h-[60vh] gap-4">
        <div className="w-10 h-10 border-4 border-blue-600 border-t-transparent rounded-full animate-spin"></div>
        <p className="text-gray-500 font-medium text-sm">Loading attendance register...</p>
      </div>
    );
  }

  const inputCls = "w-full px-3 py-2.5 rounded-xl bg-gray-50 border border-gray-200 focus:ring-2 focus:ring-blue-500 outline-none text-sm font-medium transition-all";

  return (
    <div className="flex flex-col min-h-screen bg-gray-50 font-sans">

      {/* ── Top Bar ── */}
      <div className="bg-white border-b border-gray-200 px-4 py-4 flex items-start justify-between gap-4 shrink-0">
        <div className="flex items-center gap-3 min-w-0">
          <button onClick={onBack}
            className="p-2 rounded-xl bg-gray-100 hover:bg-gray-200 text-gray-700 transition-all shrink-0">
            <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M15 19l-7-7 7-7" />
            </svg>
          </button>
          <div className="min-w-0">
            <div className="flex items-center gap-2 flex-wrap">
              <h2 className="font-black text-gray-900 text-base leading-tight truncate">{course.code} — {course.name}</h2>
              <span className={`text-[10px] font-black px-2 py-0.5 rounded-full uppercase tracking-wide shrink-0 ${typeBadge}`}>{lecture_type}</span>
            </div>
            <p className="text-xs text-gray-500 mt-0.5">{students.length} students · {totalSessions} session{totalSessions !== 1 ? 's' : ''}</p>
          </div>
        </div>
        <div className="flex items-center gap-2 shrink-0">
          <button onClick={() => setShowModal(true)}
            className="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-xl text-xs font-black flex items-center gap-1.5 transition-all active:scale-95">
            <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M12 4v16m8-8H4" />
            </svg>
            New Lecture
          </button>
          {hasDirty && (
            <button onClick={handleSave} disabled={saving}
              className="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-xl text-xs font-black flex items-center gap-1.5 transition-all active:scale-95 disabled:opacity-60">
              {saving ? (
                <svg className="w-3.5 h-3.5 animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
                </svg>
              ) : (
                <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
                </svg>
              )}
              {saving ? 'Saving...' : 'Save Changes'}
            </button>
          )}
        </div>
      </div>

      {/* Save message */}
      {saveMsg && (
        <div className={`px-4 py-2 text-xs font-bold text-center transition-all ${saveMsg.startsWith('✓') ? 'bg-green-50 text-green-700' : 'bg-red-50 text-red-700'}`}>
          {saveMsg}
        </div>
      )}

      {/* ── Register Table ── */}
      {students.length === 0 ? (
        <div className="flex-1 flex flex-col items-center justify-center gap-3 text-center p-10">
          <div className="text-5xl">📋</div>
          <p className="text-gray-500 font-medium">No students found for this class.</p>
        </div>
      ) : (
        <div className="flex-1 overflow-auto">
          <table className="border-collapse text-sm" style={{ tableLayout: 'fixed', minWidth: `${240 + sessions.length * 90}px` }}>

            {/* ── Table Head ── */}
            <thead>
              {/* Row 1: sticky student header + session headers */}
              <tr className="bg-gray-900 text-white">
                {/* Sticky student column header */}
                <th className="sticky left-0 z-20 bg-gray-900 px-3 py-3 text-left font-black text-xs uppercase tracking-widest border-r border-gray-700"
                  style={{ minWidth: '240px', width: '240px' }}>
                  Student
                </th>

                {/* Session columns */}
                {sessions.map((session) => {
                  const isDirtySession = !!dirty[session.id];
                  return (
                    <th key={session.id}
                      className={`px-2 py-2 text-center border-r border-gray-700 relative ${session.is_locked ? 'bg-gray-800' : isDirtySession ? 'bg-gray-900' : 'bg-gray-900'}`}
                      style={{ minWidth: '90px', width: '90px' }}>
                      {/* Lock button */}
                      <button
                        onClick={() => handleToggleLock(session)}
                        disabled={togglingLock === session.id}
                        title={session.is_locked ? 'Unlock this session' : 'Lock this session'}
                        className={`mx-auto mb-1 flex items-center justify-center w-6 h-6 rounded-full transition-all ${session.is_locked ? 'bg-red-500/20 text-red-400 hover:bg-red-500/30' : 'bg-white/10 text-gray-400 hover:bg-white/20'}`}>
                        {session.is_locked ? (
                          <svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
                            <path fillRule="evenodd" d="M10 1a4.5 4.5 0 00-4.5 4.5V9H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-.5V5.5A4.5 4.5 0 0010 1zm3 8V5.5a3 3 0 10-6 0V9h6z" clipRule="evenodd"/>
                          </svg>
                        ) : (
                          <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 11V7a4 4 0 118 0m-4 8v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2z" />
                          </svg>
                        )}
                      </button>
                      {/* Date */}
                      <div className="text-white font-bold text-xs leading-tight">{formatDate(session.date)}</div>
                      {/* Time */}
                      <div className="text-gray-400 text-[9px] font-mono">{formatTime(session.start_time)}</div>
                      {/* Topic (truncated) */}
                      <div className="text-gray-500 text-[9px] truncate mt-0.5 px-1" title={session.topic}>{session.topic}</div>
                      {/* Present count */}
                      <div className={`mt-1 text-[9px] font-black ${session.is_locked ? 'text-red-400' : 'text-green-400'}`}>
                        {sessionPresentCount(session.id)}/{students.length}
                      </div>
                      {/* Dirty indicator */}
                      {isDirtySession && <div className="absolute top-1 right-1 w-1.5 h-1.5 bg-amber-400 rounded-full"></div>}
                    </th>
                  );
                })}

                {/* Empty if no sessions */}
                {sessions.length === 0 && (
                  <th className="px-4 py-3 text-gray-500 text-xs italic font-normal text-center">
                    No sessions yet — click "+ New Lecture"
                  </th>
                )}
              </tr>
            </thead>

            {/* ── Table Body ── */}
            <tbody>
              {students.map((student, idx) => {
                const isEven = idx % 2 === 0;
                return (
                  <tr key={student.id || student.enrollment_no}
                    className={`${isEven ? 'bg-white' : 'bg-gray-50'} hover:bg-blue-50/40 transition-colors`}>

                    {/* Sticky student info */}
                    <td className={`sticky left-0 z-10 px-3 py-2 border-r border-gray-200 ${isEven ? 'bg-white' : 'bg-gray-50'}`}
                      style={{ minWidth: '240px', width: '240px' }}>
                      <div className="flex items-center gap-2">
                        <div className="w-7 h-7 rounded-lg bg-gradient-to-br from-blue-500 to-indigo-600 flex items-center justify-center text-white text-[10px] font-black shrink-0 shadow-sm">
                          {student.roll_no || idx + 1}
                        </div>
                        <div className="min-w-0">
                          <div className="text-gray-900 font-bold text-sm truncate leading-tight">{student.full_name}</div>
                          <div className="text-[10px] text-gray-400 font-mono">{student.enrollment_no}</div>
                        </div>
                      </div>
                    </td>

                    {/* Attendance checkboxes */}
                    {sessions.map((session) => {
                      const isPresent = getCellValue(session.id, student.enrollment_no);
                      const isLocked = session.is_locked;
                      const isDirtyCell = dirty[session.id] && dirty[session.id][student.enrollment_no] !== undefined;

                      return (
                        <td key={session.id}
                          className={`px-2 py-2 text-center border-r border-gray-100 transition-colors
                            ${isPresent ? (isLocked ? 'bg-green-50' : 'bg-green-50') : (isLocked ? 'bg-gray-100/50' : '')}
                            ${isLocked ? 'opacity-80' : 'cursor-pointer hover:bg-blue-50'}`}
                          onClick={() => !isLocked && handleCellToggle(session.id, student.enrollment_no, isPresent)}>

                          <div className={`relative inline-flex items-center justify-center w-7 h-7 rounded-lg border-2 transition-all mx-auto
                            ${isPresent
                              ? 'bg-green-500 border-green-500 shadow-sm shadow-green-200'
                              : 'bg-white border-gray-300 hover:border-blue-400'}
                            ${isLocked ? 'cursor-not-allowed' : 'cursor-pointer active:scale-90'}`}>
                            {isPresent && (
                              <svg className="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
                              </svg>
                            )}
                            {/* Dirty dot */}
                            {isDirtyCell && (
                              <span className="absolute -top-1 -right-1 w-2 h-2 bg-amber-400 rounded-full border border-white"></span>
                            )}
                          </div>
                        </td>
                      );
                    })}

                    {sessions.length === 0 && <td></td>}
                  </tr>
                );
              })}
            </tbody>

            {/* ── Table Footer (summary row) ── */}
            {sessions.length > 0 && (
              <tfoot>
                <tr className="bg-gray-900 text-white">
                  <td className="sticky left-0 z-10 bg-gray-900 px-3 py-2.5 text-xs font-black uppercase tracking-widest border-r border-gray-700">
                    Total Present
                  </td>
                  {sessions.map(session => (
                    <td key={session.id} className="px-2 py-2.5 text-center border-r border-gray-700">
                      <span className="text-green-400 font-black text-sm">{sessionPresentCount(session.id)}</span>
                      <span className="text-gray-600 text-xs">/{students.length}</span>
                    </td>
                  ))}
                </tr>
              </tfoot>
            )}
          </table>
        </div>
      )}

      {/* ── New Lecture Modal ── */}
      {showModal && (
        <div className="fixed inset-0 z-50 bg-black/60 backdrop-blur-sm flex items-end sm:items-center justify-center p-4">
          <div className="bg-white rounded-2xl shadow-2xl w-full max-w-sm overflow-hidden animate-fade-in-up">
            {/* Modal header */}
            <div className="bg-gradient-to-r from-gray-900 to-gray-800 px-6 py-4 flex justify-between items-center">
              <div>
                <h3 className="text-white font-black text-base">New Lecture</h3>
                <p className="text-gray-400 text-xs mt-0.5">{course.code} · {lecture_type}</p>
              </div>
              <button onClick={() => { setShowModal(false); setCreateError(''); }}
                className="text-gray-500 hover:text-white transition-colors p-1">
                <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M6 18L18 6M6 6l12 12" />
                </svg>
              </button>
            </div>

            <div className="p-6 space-y-4">
              <div className="grid grid-cols-2 gap-3">
                <div>
                  <label className="block text-[10px] font-black text-gray-400 uppercase tracking-widest mb-1.5">Date</label>
                  <input type="date" value={newLecture.date}
                    onChange={e => setNewLecture(p => ({ ...p, date: e.target.value }))}
                    className={inputCls} />
                </div>
                <div>
                  <label className="block text-[10px] font-black text-gray-400 uppercase tracking-widest mb-1.5">Start Time</label>
                  <input type="time" value={newLecture.start_time}
                    onChange={e => setNewLecture(p => ({ ...p, start_time: e.target.value }))}
                    className={inputCls} />
                </div>
              </div>
              
              <div>
                <label className="block text-[10px] font-black text-gray-400 uppercase tracking-widest mb-1.5">Duration (Hrs)</label>
                <select value={newLecture.duration}
                  onChange={e => setNewLecture(p => ({ ...p, duration: parseInt(e.target.value) }))}
                  className={inputCls}>
                  {[1, 2, 3, 4].map(h => <option key={h} value={h}>{h} Hr{h > 1 ? 's' : ''}</option>)}
                </select>
              </div>

              <div>
                <label className="block text-[10px] font-black text-gray-400 uppercase tracking-widest mb-1.5">Topic</label>
                <input type="text" value={newLecture.topic}
                  onChange={e => setNewLecture(p => ({ ...p, topic: e.target.value }))}
                  placeholder="e.g. Unit 3 – Trees"
                  className={inputCls} />
              </div>

              {createError && (
                <div className="bg-red-50 border border-red-200 text-red-700 text-xs font-semibold px-4 py-3 rounded-xl">
                  {createError}
                </div>
              )}

              <div className="flex gap-3 pt-1">
                <button onClick={() => { setShowModal(false); setCreateError(''); }}
                  className="flex-1 bg-gray-100 hover:bg-gray-200 text-gray-700 py-3 rounded-xl font-bold text-sm transition-all">
                  Cancel
                </button>
                <button onClick={handleCreateLecture} disabled={creating}
                  className="flex-1 bg-blue-600 hover:bg-blue-700 text-white py-3 rounded-xl font-black text-sm transition-all disabled:opacity-60">
                  {creating ? 'Creating...' : 'Create Lecture'}
                </button>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

window.AttendanceRegister = AttendanceRegister;
