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

function Records() {
  const [filter, setFilter] = useState('all');
  const [sessions, setSessions] = useState([]);
  const [loading, setLoading] = useState(false);
  const [detailState, setDetailState] = useState({
    open: false,
    loading: false,
    error: '',
    session: null
  });
  const chartRef = useRef(null);

  const fileInputRef = useRef(null);

  // Format a session duration.
  const formatDuration = (seconds) => {
    const safeSeconds = Math.max(0, Number(seconds) || 0);
    const mins = Math.floor(safeSeconds / 60);
    const secs = safeSeconds % 60;
    return `${mins}m ${secs}s`;
  };

  // Format a session timestamp for table display.
  const formatDate = (dateString) => {
    const date = new Date(dateString);
    return date.toLocaleDateString('en-US', {
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    });
  };

  const formatDateTime = (dateString) => {
    if (!dateString) return 'Not available';
    const date = new Date(dateString);
    return date.toLocaleString('en-US', {
      month: 'short',
      day: 'numeric',
      year: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    });
  };

  const parseMetadata = (detectionData) => {
    if (!detectionData) return {};
    if (typeof detectionData === 'object') return detectionData;
    try {
      return JSON.parse(detectionData);
    } catch {
      return {};
    }
  };

  const averageOf = (values) => {
    const valid = values.filter((value) => Number.isFinite(value));
    if (valid.length === 0) return null;
    return valid.reduce((sum, value) => sum + value, 0) / valid.length;
  };

  const buildTimelineSegments = (events, maxSegments = 48) => {
    if (!events.length) return [];

    const segmentSize = Math.ceil(events.length / maxSegments);
    const segments = [];

    for (let i = 0; i < events.length; i += segmentSize) {
      const slice = events.slice(i, i + segmentSize);
      const focusedCount = slice.filter((event) => event.isFocused).length;
      const focusRatio = focusedCount / slice.length;
      const confidence = averageOf(slice.map((event) => event.confidence));

      let tone = 'distracted';
      if (focusRatio >= 0.75) tone = 'focused';
      else if (focusRatio >= 0.35) tone = 'mixed';

      segments.push({
        tone,
        focusRatio,
        confidence,
        count: slice.length
      });
    }

    return segments;
  };

  const buildDetailView = (session) => {
    if (!session) return null;

    const parsedEvents = (session.events || []).map((event) => {
      const metadata = parseMetadata(event.detection_data);
      return {
        ...event,
        metadata,
        isFocused: Boolean(event.is_focused),
        confidence: Number(event.confidence) || 0
      };
    });

    const focusRatio = session.total_frames
      ? session.focused_frames / session.total_frames
      : parsedEvents.length
      ? parsedEvents.filter((event) => event.isFocused).length / parsedEvents.length
      : 0;

    const modelCounts = parsedEvents.reduce((counts, event) => {
      const model = event.metadata?.model;
      if (model) counts[model] = (counts[model] || 0) + 1;
      return counts;
    }, {});

    const dominantModel = Object.entries(modelCounts).sort((a, b) => b[1] - a[1])[0]?.[0] || 'Unavailable';
    const avgConfidence = averageOf(parsedEvents.map((event) => event.confidence));
    const avgFaceScore = averageOf(parsedEvents.map((event) => Number(event.metadata?.s_face)));
    const avgEyeScore = averageOf(parsedEvents.map((event) => Number(event.metadata?.s_eye)));
    const avgMar = averageOf(parsedEvents.map((event) => Number(event.metadata?.mar)));

    const startTime = session.start_time ? new Date(session.start_time) : null;
    const timeline = buildTimelineSegments(parsedEvents);
    const recentEvents = parsedEvents.slice(-10).reverse();

    return {
      parsedEvents,
      focusRatio,
      dominantModel,
      avgConfidence,
      avgFaceScore,
      avgEyeScore,
      avgMar,
      timeline,
      recentEvents,
      formatOffset(timestamp) {
        if (!startTime || !timestamp) return '--';
        const offsetSeconds = Math.max(0, Math.round((new Date(timestamp) - startTime) / 1000));
        const mins = Math.floor(offsetSeconds / 60);
        const secs = offsetSeconds % 60;
        return mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
      }
    };
  };

  const getScoreTone = (score) => {
    if (score >= 0.8) return 'excellent';
    if (score >= 0.6) return 'good';
    if (score >= 0.4) return 'fair';
    return 'low';
  };

  const closeDetails = () => {
    setDetailState({
      open: false,
      loading: false,
      error: '',
      session: null
    });
  };

  // Load session rows for the selected filter.
  const loadSessions = async (filterType) => {
    setLoading(true);
    try {
      const response = await fetch(`/api/sessions?filter=${filterType}&limit=50`);
      const data = await response.json();
      setSessions(data);
      drawChart(data);
    } catch (error) {
      console.error('Failed to load sessions:', error);
    } finally {
      setLoading(false);
    }
  };

  // Draw the session score chart.
  const drawChart = (data) => {
    const canvas = chartRef.current;
    if (!canvas) return;

    const ctx = canvas.getContext('2d');
    const width = canvas.width = canvas.offsetWidth;
    const height = canvas.height = 300;

    // Clear the canvas before each redraw.
    ctx.clearRect(0, 0, width, height);

    if (data.length === 0) {
      ctx.fillStyle = '#999';
      ctx.font = '16px Nunito';
      ctx.textAlign = 'center';
      ctx.fillText('No data available', width / 2, height / 2);
      return;
    }

    // Use at most the latest 20 sessions in the chart.
    const displayData = data.slice(0, 20).reverse();
    const padding = 50;
    const chartWidth = width - padding * 2;
    const chartHeight = height - padding * 2;
    const barWidth = chartWidth / displayData.length;

    // Use a normalized max score for chart scaling.
    const maxScore = 1.0;

    // Draw the chart axes.
    ctx.strokeStyle = '#E0E0E0';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(padding, padding);
    ctx.lineTo(padding, height - padding);
    ctx.lineTo(width - padding, height - padding);
    ctx.stroke();

    // Draw Y-axis labels.
    ctx.fillStyle = '#666';
    ctx.font = '12px Nunito';
    ctx.textAlign = 'right';
    for (let i = 0; i <= 4; i++) {
      const y = height - padding - (chartHeight * i / 4);
      const value = (maxScore * i / 4 * 100).toFixed(0);
      ctx.fillText(value + '%', padding - 10, y + 4);

      // Draw horizontal grid lines.
      ctx.strokeStyle = '#F0F0F0';
      ctx.lineWidth = 1;
      ctx.beginPath();
      ctx.moveTo(padding, y);
      ctx.lineTo(width - padding, y);
      ctx.stroke();
    }

    // Draw the bar chart.
    displayData.forEach((session, index) => {
      const barHeight = (session.focus_score / maxScore) * chartHeight;
      const x = padding + index * barWidth + barWidth * 0.1;
      const y = height - padding - barHeight;
      const barActualWidth = barWidth * 0.8;

      // Map each score to a blue-toned color band.
      const score = session.focus_score;
      let color;
      if (score >= 0.8) color = '#4A90E2';
      else if (score >= 0.6) color = '#5DADE2';
      else if (score >= 0.4) color = '#85C1E9';
      else color = '#AED6F1';

      ctx.fillStyle = color;
      ctx.fillRect(x, y, barActualWidth, barHeight);

      // Draw a matching outline around each bar.
      ctx.strokeStyle = color;
      ctx.lineWidth = 1;
      ctx.strokeRect(x, y, barActualWidth, barHeight);
    });

    // Draw the chart title.
    ctx.textAlign = 'left';
    ctx.font = 'bold 14px Nunito';
    ctx.fillStyle = '#4A90E2';
    ctx.fillText('Focus Score by Session', padding, 30);
  };

  // Initial load.
  useEffect(() => {
    loadSessions(filter);
  }, [filter]);

  useEffect(() => {
    if (!detailState.open) return undefined;

    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';

    const handleKeyDown = (event) => {
      if (event.key === 'Escape') {
        closeDetails();
      }
    };

    window.addEventListener('keydown', handleKeyDown);

    return () => {
      document.body.style.overflow = previousOverflow;
      window.removeEventListener('keydown', handleKeyDown);
    };
  }, [detailState.open]);

  // Filter button handler.
  const handleFilterClick = (filterType) => {
    setFilter(filterType);
  };

  // Open the detail modal for one session.
  const handleViewDetails = async (sessionId) => {
    setDetailState({
      open: true,
      loading: true,
      error: '',
      session: null
    });

    try {
      const response = await fetch(`/api/sessions/${sessionId}`);
      if (!response.ok) {
        throw new Error('Failed to load session details.');
      }

      const data = await response.json();
      setDetailState({
        open: true,
        loading: false,
        error: '',
        session: data
      });
    } catch (error) {
      setDetailState({
        open: true,
        loading: false,
        error: error.message || 'Failed to load session details.',
        session: null
      });
    }
  };

  const handleExport = async () => {
    try {
      const response = await fetch('/api/sessions?filter=all');
      if (!response.ok) throw new Error("Failed to fetch data");
      const data = await response.json();
      const jsonString = JSON.stringify(data, null, 2);
      localStorage.setItem('focus_magic_backup', jsonString);

      const blob = new Blob([jsonString], { type: 'application/json' });
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = `focus-guard-backup-${new Date().toISOString().slice(0, 10)}.json`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(url);
    } catch (error) {
      console.error(error);
      alert("Export failed: " + error.message);
    }
  };

  const triggerImport = () => {
    if (fileInputRef.current) fileInputRef.current.click();
  };

  const handleFileChange = async (event) => {
    const file = event.target.files[0];
    if (!file) return;

    const reader = new FileReader();
    reader.onload = async (e) => {
      try {
        const content = e.target.result;
        const sessions = JSON.parse(content);
        if (!Array.isArray(sessions)) {
          throw new Error("Invalid file format: Expected a list of sessions.");
        }
        const response = await fetch('/api/import', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(sessions)
        });
        if (response.ok) {
            const result = await response.json();
            alert(`Success! Imported ${result.count} sessions.`);
            loadSessions(filter);
        } else {
            alert("Import failed on server side.");
        }
      } catch (err) {
        alert("Error parsing file: " + err.message);
      }
      event.target.value = '';
    };
    reader.readAsText(file);
  };

  const handleClearHistory = async () => {
    if (!window.confirm("Are you sure? This will delete ALL your session history permanently.")) {
        return;
    }
    try {
        const response = await fetch('/api/history', { method: 'DELETE' });
        if (response.ok) {
            alert("All history has been cleared.");
            loadSessions(filter);
        } else {
            alert("Failed to clear history.");
        }
    } catch (err) {
        alert("Error: " + err.message);
    }
  };

  const detailView = buildDetailView(detailState.session);

  return (
    <main id="page-d" className="page">
      <h1 className="page-title" style={{ marginBottom: '10px' }}>My Records</h1>

      <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '15px', marginBottom: '25px' }}>
        <input
          type="file"
          ref={fileInputRef}
          style={{ display: 'none' }}
          accept=".json"
          onChange={handleFileChange}
        />
        <button
          onClick={handleExport}
          style={{ background: '#eef3f8', border: '1px solid #d9eaff', color: '#4b5a6b', padding: '6px 16px', borderRadius: '20px', fontSize: '12px', fontWeight: '700', cursor: 'pointer', transition: 'all 0.2s' }}
          onMouseOver={(e) => { e.target.style.background = '#e2eaf3'; }}
          onMouseOut={(e) => { e.target.style.background = '#eef3f8'; }}
        >
          ⬇️ Export
        </button>
        <button
          onClick={triggerImport}
          style={{ background: '#eef3f8', border: '1px solid #d9eaff', color: '#4b5a6b', padding: '6px 16px', borderRadius: '20px', fontSize: '12px', fontWeight: '700', cursor: 'pointer', transition: 'all 0.2s' }}
          onMouseOver={(e) => { e.target.style.background = '#e2eaf3'; }}
          onMouseOut={(e) => { e.target.style.background = '#eef3f8'; }}
        >
          ⬆️ Import
        </button>
        <button
          onClick={handleClearHistory}
          style={{ background: '#fff1ee', border: '1px solid #f3c7c7', color: '#b54028', padding: '6px 16px', borderRadius: '20px', fontSize: '12px', fontWeight: '700', cursor: 'pointer', transition: 'all 0.2s' }}
          onMouseOver={(e) => { e.target.style.background = '#fbe5e1'; }}
          onMouseOut={(e) => { e.target.style.background = '#fff1ee'; }}
        >
          🗑️ Clear
        </button>
      </div>

      <div className="records-controls" style={{ display: 'flex', justifyContent: 'center', gap: '10px', marginBottom: '30px' }}>
        <button
          id="filter-today"
          onClick={() => handleFilterClick('today')}
          style={{
            padding: '10px 30px',
            borderRadius: '8px',
            border: filter === 'today' ? 'none' : '2px solid #4A90E2',
            background: filter === 'today' ? '#4A90E2' : 'transparent',
            color: filter === 'today' ? 'white' : '#4A90E2',
            fontSize: '14px',
            fontWeight: '500',
            cursor: 'pointer',
            transition: 'all 0.3s'
          }}
        >
          Today
        </button>
        <button
          id="filter-week"
          onClick={() => handleFilterClick('week')}
          style={{
            padding: '10px 30px',
            borderRadius: '8px',
            border: filter === 'week' ? 'none' : '2px solid #4A90E2',
            background: filter === 'week' ? '#4A90E2' : 'transparent',
            color: filter === 'week' ? 'white' : '#4A90E2',
            fontSize: '14px',
            fontWeight: '500',
            cursor: 'pointer',
            transition: 'all 0.3s'
          }}
        >
          This Week
        </button>
        <button
          id="filter-month"
          onClick={() => handleFilterClick('month')}
          style={{
            padding: '10px 30px',
            borderRadius: '8px',
            border: filter === 'month' ? 'none' : '2px solid #4A90E2',
            background: filter === 'month' ? '#4A90E2' : 'transparent',
            color: filter === 'month' ? 'white' : '#4A90E2',
            fontSize: '14px',
            fontWeight: '500',
            cursor: 'pointer',
            transition: 'all 0.3s'
          }}
        >
          This Month
        </button>
        <button
          id="filter-all"
          onClick={() => handleFilterClick('all')}
          style={{
            padding: '10px 30px',
            borderRadius: '8px',
            border: filter === 'all' ? 'none' : '2px solid #4A90E2',
            background: filter === 'all' ? '#4A90E2' : 'transparent',
            color: filter === 'all' ? 'white' : '#4A90E2',
            fontSize: '14px',
            fontWeight: '500',
            cursor: 'pointer',
            transition: 'all 0.3s'
          }}
        >
          All Time
        </button>
      </div>

      <div className="chart-container" style={{
        background: 'white',
        padding: '20px',
        borderRadius: '10px',
        marginBottom: '30px',
        boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
      }}>
        <canvas ref={chartRef} id="focus-chart" style={{ width: '100%', height: '300px' }}></canvas>
      </div>

      <div className="sessions-list" style={{
        background: 'white',
        padding: '20px',
        borderRadius: '10px',
        boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
      }}>
        <h2 style={{ color: '#333', marginBottom: '20px', fontSize: '18px', fontWeight: '600' }}>Recent Sessions</h2>
        {loading ? (
          <div style={{ textAlign: 'center', padding: '40px', color: '#999' }}>
            Loading sessions...
          </div>
        ) : sessions.length === 0 ? (
          <div style={{ textAlign: 'center', padding: '40px', color: '#999' }}>
            No sessions found for this period.
          </div>
        ) : (
          <table id="sessions-table" style={{ width: '100%', borderCollapse: 'collapse', borderRadius: '10px', overflow: 'hidden' }}>
            <thead>
              <tr style={{ background: '#4A90E2' }}>
                <th style={{ padding: '15px', textAlign: 'left', color: 'white', fontWeight: '600', fontSize: '14px' }}>Date</th>
                <th style={{ padding: '15px', textAlign: 'center', color: 'white', fontWeight: '600', fontSize: '14px' }}>Duration</th>
                <th style={{ padding: '15px', textAlign: 'center', color: 'white', fontWeight: '600', fontSize: '14px' }}>Focus Score</th>
                <th style={{ padding: '15px', textAlign: 'center', color: 'white', fontWeight: '600', fontSize: '14px' }}>Action</th>
              </tr>
            </thead>
            <tbody id="sessions-tbody">
              {sessions.map((session, index) => (
                <tr key={session.id} style={{
                  background: index % 2 === 0 ? '#f8f9fa' : 'white',
                  borderBottom: '1px solid #e9ecef'
                }}>
                  <td style={{ padding: '15px', color: '#333', fontSize: '13px' }}>{formatDate(session.start_time)}</td>
                  <td style={{ padding: '15px', textAlign: 'center', color: '#333', fontSize: '13px' }}>{formatDuration(session.duration_seconds)}</td>
                  <td style={{ padding: '15px', textAlign: 'center' }}>
                    <span
                      style={{
                        color:
                          session.focus_score >= 0.8
                            ? '#28a745'
                            : session.focus_score >= 0.6
                            ? '#ffc107'
                            : session.focus_score >= 0.4
                            ? '#fd7e14'
                            : '#dc3545',
                        fontWeight: '600',
                        fontSize: '13px'
                      }}
                    >
                      {(session.focus_score * 100).toFixed(1)}%
                    </span>
                  </td>
                  <td style={{ padding: '15px', textAlign: 'center' }}>
                    <button
                      onClick={() => handleViewDetails(session.id)}
                      className="btn-view"
                    >
                      View
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>

      {detailState.open ? (
        <div className="modal-overlay" onClick={closeDetails}>
          <div className="modal-content records-detail-modal" onClick={(event) => event.stopPropagation()}>
            <div className="records-detail-header">
              <div>
                <div className="records-detail-kicker">Session Detail</div>
                <h2>
                  {detailState.session ? formatDateTime(detailState.session.start_time) : 'Loading session'}
                </h2>
                <p className="records-detail-subtitle">
                  Review score, capture quality, and a condensed event timeline for this session.
                </p>
              </div>
              <button type="button" className="records-detail-close" onClick={closeDetails}>
                Close
              </button>
            </div>

            {detailState.loading ? (
              <div className="records-detail-feedback">Loading session details...</div>
            ) : detailState.error ? (
              <div className="records-detail-feedback records-detail-feedback-error">{detailState.error}</div>
            ) : detailState.session && detailView ? (
              <>
                <section className="records-detail-summary">
                  <article className={`records-detail-stat ${getScoreTone(detailState.session.focus_score)}`}>
                    <span className="records-detail-stat-label">Focus Score</span>
                    <strong className="records-detail-stat-value">
                      {(detailState.session.focus_score * 100).toFixed(1)}%
                    </strong>
                  </article>
                  <article className="records-detail-stat">
                    <span className="records-detail-stat-label">Duration</span>
                    <strong className="records-detail-stat-value">
                      {formatDuration(detailState.session.duration_seconds)}
                    </strong>
                  </article>
                  <article className="records-detail-stat">
                    <span className="records-detail-stat-label">Frames Analysed</span>
                    <strong className="records-detail-stat-value">{detailState.session.total_frames}</strong>
                  </article>
                  <article className="records-detail-stat">
                    <span className="records-detail-stat-label">Focused Frames</span>
                    <strong className="records-detail-stat-value">
                      {(detailView.focusRatio * 100).toFixed(1)}%
                    </strong>
                  </article>
                </section>

                <section className="records-detail-grid">
                  <article className="records-detail-card">
                    <h3>Session Info</h3>
                    <div className="records-detail-list">
                      <div className="records-detail-item">
                        <span className="records-detail-item-label">Started</span>
                        <span className="records-detail-item-value">{formatDateTime(detailState.session.start_time)}</span>
                      </div>
                      <div className="records-detail-item">
                        <span className="records-detail-item-label">Ended</span>
                        <span className="records-detail-item-value">{formatDateTime(detailState.session.end_time)}</span>
                      </div>
                      <div className="records-detail-item">
                        <span className="records-detail-item-label">Dominant Model</span>
                        <span className="records-detail-item-value">{detailView.dominantModel}</span>
                      </div>
                      <div className="records-detail-item">
                        <span className="records-detail-item-label">Event Samples</span>
                        <span className="records-detail-item-value">{detailView.parsedEvents.length}</span>
                      </div>
                    </div>
                  </article>

                  <article className="records-detail-card">
                    <h3>Signal Quality</h3>
                    <div className="records-detail-list">
                      <div className="records-detail-item">
                        <span className="records-detail-item-label">Avg Confidence</span>
                        <span className="records-detail-item-value">
                          {detailView.avgConfidence !== null ? `${(detailView.avgConfidence * 100).toFixed(1)}%` : '--'}
                        </span>
                      </div>
                      <div className="records-detail-item">
                        <span className="records-detail-item-label">Avg Face Score</span>
                        <span className="records-detail-item-value">
                          {detailView.avgFaceScore !== null ? detailView.avgFaceScore.toFixed(3) : '--'}
                        </span>
                      </div>
                      <div className="records-detail-item">
                        <span className="records-detail-item-label">Avg Eye Score</span>
                        <span className="records-detail-item-value">
                          {detailView.avgEyeScore !== null ? detailView.avgEyeScore.toFixed(3) : '--'}
                        </span>
                      </div>
                      <div className="records-detail-item">
                        <span className="records-detail-item-label">Avg MAR</span>
                        <span className="records-detail-item-value">
                          {detailView.avgMar !== null ? detailView.avgMar.toFixed(3) : '--'}
                        </span>
                      </div>
                    </div>
                  </article>
                </section>

                <section className="records-detail-card">
                  <div className="records-detail-section-head">
                    <h3>Focus Timeline</h3>
                    <span>{detailView.parsedEvents.length} events condensed</span>
                  </div>
                  {detailView.timeline.length > 0 ? (
                    <>
                      <div className="records-detail-timeline">
                        {detailView.timeline.map((segment, index) => (
                          <div
                            key={`${segment.tone}-${index}`}
                            className={`records-detail-segment ${segment.tone}`}
                            title={`${(segment.focusRatio * 100).toFixed(0)}% focused, ${segment.count} events`}
                          />
                        ))}
                      </div>
                      <div className="records-detail-legend">
                        <span><i className="records-detail-dot focused" />Focused</span>
                        <span><i className="records-detail-dot mixed" />Mixed</span>
                        <span><i className="records-detail-dot distracted" />Distracted</span>
                      </div>
                    </>
                  ) : (
                    <div className="records-detail-empty">No event timeline was recorded for this session.</div>
                  )}
                </section>

                <section className="records-detail-card">
                  <div className="records-detail-section-head">
                    <h3>Recent Events</h3>
                    <span>Last {detailView.recentEvents.length} samples</span>
                  </div>
                  {detailView.recentEvents.length > 0 ? (
                    <div className="records-detail-events">
                      {detailView.recentEvents.map((event) => (
                        <article key={event.id} className="records-detail-event">
                          <div className="records-detail-event-time">{detailView.formatOffset(event.timestamp)}</div>
                          <div className="records-detail-event-copy">
                            <div className="records-detail-event-status">
                              {event.isFocused ? 'Focused' : 'Distracted'}
                            </div>
                            <div className="records-detail-event-meta">
                              {event.metadata?.model || 'model n/a'} · confidence {(event.confidence * 100).toFixed(1)}%
                            </div>
                          </div>
                          <div className={`records-detail-event-badge ${event.isFocused ? 'focused' : 'distracted'}`}>
                            {event.isFocused ? 'OK' : 'Alert'}
                          </div>
                        </article>
                      ))}
                    </div>
                  ) : (
                    <div className="records-detail-empty">No individual event samples are available.</div>
                  )}
                </section>
              </>
            ) : null}
          </div>
        </div>
      ) : null}
    </main>
  );
}

export default Records;