import React, { useEffect, useState, useRef, useMemo } from 'react';
import { getWsUrl, type ExamRoomStudent } from '../api';
import { openStaffChat } from '../chatEvents';

interface ExamGridProctorProps {
  students: ExamRoomStudent[];
  onlineIds: number[];
  onSelectStudent: (student: ExamRoomStudent) => void;
}

export const ExamGridProctor: React.FC<ExamGridProctorProps> = ({
  students,
  onlineIds,
  onSelectStudent,
}) => {
  const [screenFrames, setScreenFrames] = useState<Record<number, string>>({});
  const [webcamFrames, setWebcamFrames] = useState<Record<number, string>>({});
  const [gridCols, setGridCols] = useState<number>(3);
  const [showWebcamOverlay, setShowWebcamOverlay] = useState<boolean>(true);
  const [searchQuery, setSearchQuery] = useState<string>('');
  const [onlyOnline, setOnlyOnline] = useState<boolean>(false);
  const [isFullscreen, setIsFullscreen] = useState<boolean>(false);

  const wsRef = useRef<WebSocket | null>(null);
  const gridContainerRef = useRef<HTMLDivElement>(null);

  const studentIdsString = useMemo(
    () => students.map((s) => s.studentRkId).join(','),
    [students]
  );

  useEffect(() => {
    if (students.length === 0) return;

    const wsUrl = getWsUrl('/ws?role=teacher');
    const ws = new WebSocket(wsUrl);
    wsRef.current = ws;

    ws.onopen = () => {
      students.forEach((s) => {
        ws.send(
          JSON.stringify({
            event: 'teacher:subscribe',
            data: { studentId: s.studentRkId },
          })
        );
      });
    };

    ws.onmessage = (event) => {
      try {
        const msg = JSON.parse(event.data);
        if (msg.event === 'teacher:screenshot-stream-frame') {
          const { studentId, imageBuffer } = msg.data;
          setScreenFrames((prev) => ({ ...prev, [studentId]: imageBuffer }));
        } else if (msg.event === 'teacher:webcam-stream-frame') {
          const { studentId, imageBuffer } = msg.data;
          setWebcamFrames((prev) => ({ ...prev, [studentId]: imageBuffer }));
        } else if (msg.event === 'teacher:stream-stopped') {
          const { studentId } = msg.data;
          setScreenFrames((prev) => {
            const next = { ...prev };
            delete next[studentId];
            return next;
          });
          setWebcamFrames((prev) => {
            const next = { ...prev };
            delete next[studentId];
            return next;
          });
        }
      } catch (err) {
        console.error('Error parsing WS message in grid view:', err);
      }
    };

    return () => {
      if (ws.readyState === WebSocket.OPEN) {
        students.forEach((s) => {
          ws.send(
            JSON.stringify({
              event: 'teacher:unsubscribe',
              data: { studentId: s.studentRkId },
            })
          );
        });
      }
      ws.close();
    };
  }, [studentIdsString]);

  // Clean up frames when students are removed or go offline
  useEffect(() => {
    setScreenFrames((prev) => {
      const next = { ...prev };
      let changed = false;
      Object.keys(next).forEach((idStr) => {
        const id = Number(idStr);
        if (!onlineIds.includes(id)) {
          delete next[id];
          changed = true;
        }
      });
      return changed ? next : prev;
    });
    setWebcamFrames((prev) => {
      const next = { ...prev };
      let changed = false;
      Object.keys(next).forEach((idStr) => {
        const id = Number(idStr);
        if (!onlineIds.includes(id)) {
          delete next[id];
          changed = true;
        }
      });
      return changed ? next : prev;
    });
  }, [onlineIds]);

  const filteredStudents = useMemo(() => {
    return students.filter((s) => {
      const matchesSearch =
        s.fullName.toLowerCase().includes(searchQuery.toLowerCase()) ||
        s.studentCode.toLowerCase().includes(searchQuery.toLowerCase());
      const isOnline = onlineIds.includes(s.studentRkId);
      const matchesOnlineFilter = !onlyOnline || isOnline;
      return matchesSearch && matchesOnlineFilter;
    });
  }, [students, onlineIds, searchQuery, onlyOnline]);

  const handleOpenChat = (s: ExamRoomStudent, e: React.MouseEvent) => {
    e.stopPropagation();
    openStaffChat({
      studentRkId: s.studentRkId,
      fullName: s.fullName,
      studentCode: s.studentCode,
      email: s.email,
    });
  };

  useEffect(() => {
    const handleFsChange = () => {
      setIsFullscreen(document.fullscreenElement === gridContainerRef.current);
    };
    document.addEventListener('fullscreenchange', handleFsChange);
    return () => document.removeEventListener('fullscreenchange', handleFsChange);
  }, []);

  const toggleFullscreen = () => {
    const el = gridContainerRef.current;
    if (!el) return;
    if (document.fullscreenElement === el) {
      document.exitFullscreen().catch(console.error);
    } else {
      el.requestFullscreen().catch(console.error);
    }
  };

  return (
    <div className="grid-proctor-container" ref={gridContainerRef}>
      <div className="grid-proctor-toolbar">
        <div className="grid-proctor-toolbar-left">
          <div className="search-input-wrapper">
            <input
              type="text"
              className="search-input"
              placeholder="Lọc sinh viên..."
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
            />
            <span className="search-icon">🔍</span>
          </div>

          <label className="checkbox-label" style={{ display: 'flex', alignItems: 'center', gap: '0.35rem', cursor: 'pointer', fontSize: '0.85rem' }}>
            <input
              type="checkbox"
              checked={onlyOnline}
              onChange={(e) => setOnlyOnline(e.target.checked)}
            />
            <span>Chỉ hiện Online</span>
          </label>

          <label className="checkbox-label" style={{ display: 'flex', alignItems: 'center', gap: '0.35rem', cursor: 'pointer', fontSize: '0.85rem' }}>
            <input
              type="checkbox"
              checked={showWebcamOverlay}
              onChange={(e) => setShowWebcamOverlay(e.target.checked)}
            />
            <span>Đè webcam góc màn hình</span>
          </label>
        </div>

        <div className="grid-proctor-toolbar-right">
          <div className="grid-cols-selector">
            <span style={{ fontSize: '0.8rem', color: 'var(--text-muted)' }}>Cột:</span>
            <button
              type="button"
              className={`btn btn-secondary btn-xs ${gridCols === 2 ? 'active' : ''}`}
              onClick={() => setGridCols(2)}
            >
              2
            </button>
            <button
              type="button"
              className={`btn btn-secondary btn-xs ${gridCols === 3 ? 'active' : ''}`}
              onClick={() => setGridCols(3)}
            >
              3
            </button>
            <button
              type="button"
              className={`btn btn-secondary btn-xs ${gridCols === 4 ? 'active' : ''}`}
              onClick={() => setGridCols(4)}
            >
              4
            </button>
            <button
              type="button"
              className={`btn btn-secondary btn-xs ${gridCols === 6 ? 'active' : ''}`}
              onClick={() => setGridCols(6)}
            >
              6
            </button>
          </div>

          <button
            type="button"
            className="btn btn-secondary btn-sm"
            onClick={toggleFullscreen}
          >
            {isFullscreen ? '🖥️ Thu nhỏ' : '🖥️ Toàn màn hình'}
          </button>
        </div>
      </div>

      <div
        className={`grid-proctor-layout`}
        style={{
          display: 'grid',
          gridTemplateColumns: `repeat(${gridCols}, minmax(0, 1fr))`,
          gap: '1rem',
          padding: '1rem 0',
        }}
      >
        {filteredStudents.map((s) => {
          const isOnline = onlineIds.includes(s.studentRkId);
          const screenFrame = screenFrames[s.studentRkId];
          const webcamFrame = webcamFrames[s.studentRkId];

          return (
            <div
              key={s.id}
              className={`grid-proctor-card ${isOnline ? 'online' : 'offline'} ${s.submitted ? 'submitted' : ''}`}
              onClick={() => onSelectStudent(s)}
            >
              <div className="grid-proctor-card-header">
                <div className="student-info-left">
                  <span className={`status-dot ${isOnline ? 'online' : 'offline'}`} />
                  <span className="student-name" title={s.fullName}>
                    {s.fullName}
                  </span>
                </div>
                <span className="student-code">{s.studentCode}</span>
              </div>

              <div className="grid-proctor-card-body">
                {isOnline ? (
                  <div className="proctor-frame-container">
                    {screenFrame ? (
                      <img
                        src={screenFrame}
                        alt={`Màn hình ${s.fullName}`}
                        className="proctor-screen-image"
                        draggable={false}
                      />
                    ) : (
                      <div className="proctor-placeholder streaming">
                        <div className="sync-spinner" style={{ width: '20px', height: '20px', borderWidth: '2px', marginBottom: '0.5rem' }} />
                        <span>Đang kết nối màn hình...</span>
                      </div>
                    )}

                    {showWebcamOverlay && webcamFrame && (
                      <div className="proctor-webcam-overlay">
                        <img
                          src={webcamFrame}
                          alt={`Webcam ${s.fullName}`}
                          className="proctor-webcam-image"
                          draggable={false}
                        />
                      </div>
                    )}
                  </div>
                ) : (
                  <div className="proctor-placeholder offline">
                    <span className="icon">📴</span>
                    <span>Ngoại tuyến (Offline)</span>
                  </div>
                )}
              </div>

              <div className="grid-proctor-card-footer" onClick={(e) => e.stopPropagation()}>
                <span className="assigned-paper" title={s.paperTitle || 'Chưa gán đề'}>
                  {s.paperTitle ? `Đề: ${s.paperTitle}` : 'Chưa gán đề'}
                </span>
                <div className="footer-actions">
                  <button
                    type="button"
                    className="btn btn-ghost btn-xs text-primary"
                    onClick={(e) => handleOpenChat(s, e)}
                    title="Nhắn tin cho sinh viên"
                  >
                    💬 Nhắn tin
                  </button>
                  <button
                    type="button"
                    className="btn btn-ghost btn-xs"
                    onClick={() => onSelectStudent(s)}
                    title="Xem chi tiết giám sát"
                  >
                    🔍 Giám sát
                  </button>
                </div>
              </div>
            </div>
          );
        })}

        {filteredStudents.length === 0 && (
          <div className="grid-proctor-empty" style={{ gridColumn: '1 / -1' }}>
            <span>🔍</span>
            <p>Không tìm thấy sinh viên nào.</p>
          </div>
        )}
      </div>
    </div>
  );
};
