import React, { useState, useEffect, useRef } from 'react';

function FocusPageLocal({ videoManager, sessionResult, setSessionResult, isActive }) {
  const [currentFrame, setCurrentFrame] = useState(15);
  const [timelineEvents, setTimelineEvents] = useState([]);
  const [stats, setStats] = useState(null);
  const [systemStats, setSystemStats] = useState(null);
  const [availableModels, setAvailableModels] = useState([]);
  const [currentModel, setCurrentModel] = useState('mlp');

  const localVideoRef = useRef(null);
  const displayCanvasRef = useRef(null);
  const pipVideoRef = useRef(null);
  const pipStreamRef = useRef(null);

  const formatDuration = (seconds) => {
    if (seconds === 0) return "0s";
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    return `${mins}m ${secs}s`;
  };

  useEffect(() => {
    if (!videoManager) return;

    const originalOnStatusUpdate = videoManager.callbacks.onStatusUpdate;
    videoManager.callbacks.onStatusUpdate = (isFocused) => {
      setTimelineEvents(prev => {
        const newEvents = [...prev, { isFocused, timestamp: Date.now() }];
        if (newEvents.length > 60) newEvents.shift();
        return newEvents;
      });
      if (originalOnStatusUpdate) originalOnStatusUpdate(isFocused);
    };

    const statsInterval = setInterval(() => {
      if (videoManager && videoManager.getStats) {
        setStats(videoManager.getStats());
      }
    }, 1000);

    return () => {
      if (videoManager) {
        videoManager.callbacks.onStatusUpdate = originalOnStatusUpdate;
      }
      clearInterval(statsInterval);
    };
  }, [videoManager]);

  // Fetch available models on mount
  useEffect(() => {
    fetch('/api/models')
      .then(res => res.json())
      .then(data => {
        if (data.available) setAvailableModels(data.available);
        if (data.current) setCurrentModel(data.current);
      })
      .catch(err => console.error('Failed to fetch models:', err));
  }, []);

  // Poll server CPU/memory for UI
  useEffect(() => {
    const fetchSystem = () => {
      fetch('/api/stats/system')
        .then(res => res.json())
        .then(data => setSystemStats(data))
        .catch(() => setSystemStats(null));
    };
    fetchSystem();
    const interval = setInterval(fetchSystem, 3000);
    return () => clearInterval(interval);
  }, []);

  const handleModelChange = async (modelName) => {
    try {
      const res = await fetch('/api/settings', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ model_name: modelName })
      });
      const result = await res.json();
      if (result.updated) {
        setCurrentModel(modelName);
      }
    } catch (err) {
      console.error('Failed to switch model:', err);
    }
  };

  const handleStart = async () => {
    try {
      if (videoManager) {
        setSessionResult(null);
        setTimelineEvents([]);

        console.log('Initializing local camera...');
        await videoManager.initCamera(localVideoRef.current, displayCanvasRef.current);
        console.log('Camera initialized');

        console.log('Starting local streaming...');
        await videoManager.startStreaming();
        console.log('Streaming started successfully');
      }
    } catch (err) {
      console.error('Start error:', err);
      let errorMessage = "Failed to start: ";

      if (err.name === 'NotAllowedError') {
        errorMessage += "Camera permission denied. Please allow camera access.";
      } else if (err.name === 'NotFoundError') {
        errorMessage += "No camera found. Please connect a camera.";
      } else if (err.name === 'NotReadableError') {
        errorMessage += "Camera is already in use by another application.";
      } else {
        errorMessage += err.message || "Unknown error occurred.";
      }

      alert(errorMessage + "\n\nCheck browser console for details.");
    }
  };

  const handleStop = async () => {
    if (videoManager) {
      videoManager.stopStreaming();
    }
    try {
      if (document.pictureInPictureElement === pipVideoRef.current) {
        await document.exitPictureInPicture();
      }
    } catch (_) {}
    if (pipVideoRef.current) {
      pipVideoRef.current.pause();
      pipVideoRef.current.srcObject = null;
    }
    if (pipStreamRef.current) {
      pipStreamRef.current.getTracks().forEach(t => t.stop());
      pipStreamRef.current = null;
    }
  };

  const handlePiP = async () => {
    try {
      //
      if (!videoManager || !videoManager.isStreaming) {
        alert('Please start the video first.');
        return;
      }

      if (!displayCanvasRef.current) {
        alert('Video not ready.');
        return;
      }

      //
      if (document.pictureInPictureElement === pipVideoRef.current) {
        await document.exitPictureInPicture();
        console.log('PiP exited');
        return;
      }

      //
      if (!document.pictureInPictureEnabled) {
        alert('Picture-in-Picture is not supported in this browser.');
        return;
      }

      //
      const pipVideo = pipVideoRef.current;
      if (!pipVideo) {
        alert('PiP video element not ready.');
        return;
      }

      const isSafariPiP = typeof pipVideo.webkitSetPresentationMode === 'function';

      //
      let stream = pipStreamRef.current;
      if (!stream) {
        const capture = displayCanvasRef.current.captureStream;
        if (typeof capture === 'function') {
          stream = capture.call(displayCanvasRef.current, 30);
        }
        if (!stream || stream.getTracks().length === 0) {
          const cameraStream = localVideoRef.current?.srcObject;
          if (!cameraStream) {
            alert('Camera stream not ready.');
            return;
          }
          stream = cameraStream;
        }
        pipStreamRef.current = stream;
      }

      //
      if (!stream || stream.getTracks().length === 0) {
        alert('Failed to capture video stream from canvas.');
        return;
      }

      pipVideo.srcObject = stream;

      //
      if (pipVideo.readyState < 2) {
        await new Promise((resolve) => {
          const onReady = () => {
            pipVideo.removeEventListener('loadeddata', onReady);
            pipVideo.removeEventListener('canplay', onReady);
            resolve();
          };
          pipVideo.addEventListener('loadeddata', onReady);
          pipVideo.addEventListener('canplay', onReady);
          //
          setTimeout(resolve, 600);
        });
      }

      try {
        await pipVideo.play();
      } catch (_) {
        //
      }

      //
      if (isSafariPiP) {
        try {
          pipVideo.webkitSetPresentationMode('picture-in-picture');
          console.log('PiP activated (Safari)');
          return;
        } catch (e) {
          //
          const cameraStream = localVideoRef.current?.srcObject;
          if (cameraStream && cameraStream !== pipVideo.srcObject) {
            pipVideo.srcObject = cameraStream;
            try {
              await pipVideo.play();
            } catch (_) {}
            pipVideo.webkitSetPresentationMode('picture-in-picture');
            console.log('PiP activated (Safari fallback)');
            return;
          }
          throw e;
        }
      }

      //
      if (typeof pipVideo.requestPictureInPicture === 'function') {
        await pipVideo.requestPictureInPicture();
        console.log('PiP activated');
      } else {
        alert('Picture-in-Picture is not supported in this browser.');
      }

    } catch (err) {
      console.error('PiP error:', err);
      alert('Failed to enter Picture-in-Picture: ' + err.message);
    }
  };

  const handleFloatingWindow = () => {
    handlePiP();
  };

  const handleFrameChange = (val) => {
    const rate = parseInt(val);
    setCurrentFrame(rate);
    if (videoManager) {
      videoManager.setFrameRate(rate);
    }
  };

  const handlePreview = () => {
    if (!videoManager || !videoManager.isStreaming) {
      alert('Please start a session first.');
      return;
    }

    //
    const currentStats = videoManager.getStats();

    if (!currentStats.sessionId) {
      alert('No active session.');
      return;
    }

    //
    const sessionDuration = Math.floor((Date.now() - (videoManager.sessionStartTime || Date.now())) / 1000);

    //
    const focusScore = currentStats.framesProcessed > 0
      ? (currentStats.framesProcessed * (currentStats.currentStatus ? 1 : 0)) / currentStats.framesProcessed
      : 0;

    //
    setSessionResult({
      duration_seconds: sessionDuration,
      focus_score: focusScore,
      total_frames: currentStats.framesProcessed,
      focused_frames: Math.floor(currentStats.framesProcessed * focusScore)
    });
  };

  const handleCloseOverlay = () => {
    setSessionResult(null);
  };

  const pageStyle = isActive
    ? undefined
    : {
        position: 'absolute',
        width: '1px',
        height: '1px',
        overflow: 'hidden',
        opacity: 0,
        pointerEvents: 'none'
      };

  useEffect(() => {
    return () => {
      if (pipVideoRef.current) {
        pipVideoRef.current.pause();
        pipVideoRef.current.srcObject = null;
      }
      if (pipStreamRef.current) {
        pipStreamRef.current.getTracks().forEach(t => t.stop());
        pipStreamRef.current = null;
      }
    };
  }, []);

  return (
    <main id="page-b" className="page" style={pageStyle}>
      {/* 1. Camera / Display Area */}
      <section id="display-area" style={{ position: 'relative', overflow: 'hidden' }}>
        {/* hidden PiP video element */}
        <video
          ref={pipVideoRef}
          muted
          playsInline
          autoPlay
          style={{
            position: 'absolute',
            width: '1px',
            height: '1px',
            opacity: 0,
            pointerEvents: 'none'
          }}
        />
        {/* local video (hidden, for capture) */}
        <video
          ref={localVideoRef}
          muted
          playsInline
          autoPlay
          style={{ display: 'none' }}
        />

        {/* processed video (canvas) */}
        <canvas
          ref={displayCanvasRef}
          width={640}
          height={480}
          style={{
            width: '100%',
            height: '100%',
            objectFit: 'contain',
            backgroundColor: '#000'
          }}
        />

        {/* result overlay */}
        {sessionResult && (
          <div className="session-result-overlay">
            <h3>Session Complete!</h3>
            <div className="result-item">
              <span className="label">Duration:</span>
              <span className="value">{formatDuration(sessionResult.duration_seconds)}</span>
            </div>
            <div className="result-item">
              <span className="label">Focus Score:</span>
              <span className="value">{(sessionResult.focus_score * 100).toFixed(1)}%</span>
            </div>

            <button
              onClick={handleCloseOverlay}
              style={{
                marginTop: '20px',
                padding: '8px 20px',
                background: 'transparent',
                border: '1px solid white',
                color: 'white',
                borderRadius: '20px',
                cursor: 'pointer'
              }}
            >
              Close
            </button>
          </div>
        )}

        {/* stats overlay */}
        {stats && stats.isStreaming && (
          <div style={{
            position: 'absolute',
            top: '10px',
            right: '10px',
            background: 'rgba(0,0,0,0.7)',
            color: 'white',
            padding: '10px',
            borderRadius: '5px',
            fontSize: '12px',
            fontFamily: 'monospace'
          }}>
            <div>Session: {stats.sessionId}</div>
            <div>Sent: {stats.framesSent}</div>
            <div>Processed: {stats.framesProcessed}</div>
            <div>Latency: {stats.avgLatency.toFixed(0)}ms</div>
            <div>Status: {stats.currentStatus ? 'Focused' : 'Not Focused'}</div>
            <div>Confidence: {(stats.lastConfidence * 100).toFixed(1)}%</div>
            {systemStats && systemStats.cpu_percent != null && (
              <div style={{ marginTop: '6px', borderTop: '1px solid #444', paddingTop: '4px' }}>
                <div>CPU: {systemStats.cpu_percent}%</div>
                <div>RAM: {systemStats.memory_percent}% ({systemStats.memory_used_mb}/{systemStats.memory_total_mb} MB)</div>
              </div>
            )}
          </div>
        )}
      </section>

      {/* Server CPU / Memory (always visible) */}
      {systemStats && (systemStats.cpu_percent != null || systemStats.memory_percent != null) && (
        <section style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          gap: '16px',
          padding: '6px 12px',
          background: 'rgba(0,0,0,0.3)',
          borderRadius: '8px',
          margin: '6px auto',
          maxWidth: '400px',
          fontSize: '13px',
          color: '#aaa'
        }}>
          <span title="Server CPU">CPU: <strong style={{ color: '#8f8' }}>{systemStats.cpu_percent}%</strong></span>
          <span title="Server memory">RAM: <strong style={{ color: '#8af' }}>{systemStats.memory_percent}%</strong> ({systemStats.memory_used_mb}/{systemStats.memory_total_mb} MB)</span>
        </section>
      )}

      {/* 2. Model Selector */}
      {availableModels.length > 0 && (
        <section style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          gap: '8px',
          padding: '8px 16px',
          background: '#1a1a2e',
          borderRadius: '8px',
          margin: '8px auto',
          maxWidth: '600px'
        }}>
          <span style={{ color: '#aaa', fontSize: '13px', marginRight: '4px' }}>Model:</span>
          {availableModels.map(name => (
            <button
              key={name}
              onClick={() => handleModelChange(name)}
              style={{
                padding: '5px 14px',
                borderRadius: '16px',
                border: currentModel === name ? '2px solid #007BFF' : '1px solid #555',
                background: currentModel === name ? '#007BFF' : 'transparent',
                color: currentModel === name ? '#fff' : '#ccc',
                fontSize: '12px',
                fontWeight: currentModel === name ? 'bold' : 'normal',
                cursor: 'pointer',
                textTransform: 'uppercase',
                transition: 'all 0.2s'
              }}
            >
              {name}
            </button>
          ))}
        </section>
      )}

      {/* 3. Timeline Area */}
      <section id="timeline-area">
        <div className="timeline-label">Timeline</div>
        <div id="timeline-visuals">
          {timelineEvents.map((event, index) => (
            <div
              key={index}
              className="timeline-block"
              style={{
                backgroundColor: event.isFocused ? '#00FF00' : '#FF0000',
                width: '10px',
                height: '20px',
                display: 'inline-block',
                marginRight: '2px',
                borderRadius: '2px'
              }}
              title={event.isFocused ? 'Focused' : 'Distracted'}
            />
          ))}
        </div>
        <div id="timeline-line"></div>
      </section>

      {/* 4. Control Buttons */}
      <section id="control-panel">
        <button id="btn-cam-start" className="action-btn green" onClick={handleStart}>
          Start
        </button>

        <button id="btn-floating" className="action-btn yellow" onClick={handleFloatingWindow}>
          Floating Window
        </button>

        <button
          id="btn-preview"
          className="action-btn"
          style={{ backgroundColor: '#6c5ce7' }}
          onClick={handlePreview}
        >
          Preview Result
        </button>

        <button id="btn-cam-stop" className="action-btn red" onClick={handleStop}>
          Stop
        </button>
      </section>

      {/* 5. Frame Control */}
      <section id="frame-control">
        <label htmlFor="frame-slider">Frame Rate (FPS)</label>
        <input
          type="range"
          id="frame-slider"
          min="10"
          max="30"
          value={currentFrame}
          onChange={(e) => handleFrameChange(e.target.value)}
        />
        <input
          type="number"
          id="frame-input"
          min="10"
          max="30"
          value={currentFrame}
          onChange={(e) => handleFrameChange(e.target.value)}
        />
      </section>
    </main>
  );
}

export default FocusPageLocal;
