import React, { useState, useEffect, useCallback, useRef, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
import { useToast } from '../components/Toast';
import api from '../api/axios';
import { formatDayHeader, formatTimeOnly, getLocalDateKey, isSunday } from '../utils/dateUtils';
import { prefixKey } from '../utils/adminPrefs';

function History() {
  const { isAuthenticated, adminName } = useAuth();
  const { error, success } = useToast();
  const navigate = useNavigate();

  const [sessions, setSessions] = useState([]);
  const [loading, setLoading] = useState(true);
  const [totalCount, setTotalCount] = useState(0);
  const [absoluteTotal, setAbsoluteTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [prevLastDate, setPrevLastDate] = useState(null);
  const [closingSession, setClosingSession] = useState(null);

  const [filter, setFilter] = useState(() => localStorage.getItem(prefixKey(adminName, 'history-filter')) || 'default');
  const [limit, setLimit] = useState(() => localStorage.getItem(prefixKey(adminName, 'history-show-limit')) || '5');

  const [selectMode, setSelectMode] = useState(false);
  const [selectedIds, setSelectedIds] = useState(new Set());
  const [showBulkDeleteConfirm, setShowBulkDeleteConfirm] = useState(false);

  const longPressTimer = useRef(null);
  const longPressFired = useRef(false);

  const loadSessions = useCallback(async () => {
    try {
      const limitNum = limit === 'all' ? null : parseInt(limit, 10);
      const offset = limitNum ? (page - 1) * limitNum : 0;

      const response = await api.get('/sessions', {
        params: { filter, limit, offset: offset || undefined }
      });
      setSessions(response.data);
      setTotalCount(parseInt(response.headers['x-total-count'] || '0', 10));
      setAbsoluteTotal(parseInt(response.headers['x-absolute-total'] || '0', 10));
      setPrevLastDate(response.headers['x-prev-last-date'] || null);

      if (response.data.length === 0 && offset > 0) {
        setPage(1);
      }
    } catch (err) {
      console.error('Failed to load sessions', err);
    } finally {
      setLoading(false);
    }
  }, [filter, limit, page]);

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

  useEffect(() => {
    const interval = setInterval(() => {
      loadSessions();
    }, 3000);
    return () => clearInterval(interval);
  }, [loadSessions]);

  useEffect(() => {
    if (adminName) {
      const savedFilter = localStorage.getItem(prefixKey(adminName, 'history-filter'));
      const savedLimit = localStorage.getItem(prefixKey(adminName, 'history-show-limit'));
      if (savedFilter) setFilter(savedFilter);
      if (savedLimit) setLimit(savedLimit);
    }
  }, [adminName]);

  const handleFilterChange = (newFilter) => {
    setFilter(newFilter);
    localStorage.setItem(prefixKey(adminName, 'history-filter'), newFilter);
    setSelectedIds(new Set());
    setPage(1);
  };

  const handleLimitChange = (newLimit) => {
    setLimit(newLimit);
    localStorage.setItem(prefixKey(adminName, 'history-show-limit'), newLimit);
    setSelectedIds(new Set());
    setPage(1);
  };

  const handleCloseSession = async (sessionId, notes) => {
    try {
      await api.post(`/sessions/${sessionId}/close`, { notes });
      await loadSessions();
      setClosingSession(null);
      success('Session ended successfully');
    } catch (err) {
      error('Failed to close session');
    }
  };

  // Multi-select handlers
  const toggleSelection = (sessionId) => {
    setSelectedIds(prev => {
      const next = new Set(prev);
      if (next.has(sessionId)) {
        next.delete(sessionId);
      } else {
        next.add(sessionId);
      }
      return next;
    });
  };

  const exitSelectMode = () => {
    setSelectMode(false);
    setSelectedIds(new Set());
    setShowBulkDeleteConfirm(false);
    setPage(1);
  };

  const handlePointerDown = (sessionId) => {
    if (!isAuthenticated || selectMode) return;
    longPressFired.current = false;
    longPressTimer.current = setTimeout(() => {
      longPressFired.current = true;
      setSelectMode(true);
      setSelectedIds(new Set([sessionId]));
      setPage(1);
    }, 500);
  };

  const handlePointerUp = () => {
    if (longPressTimer.current) {
      clearTimeout(longPressTimer.current);
      longPressTimer.current = null;
    }
  };

  const handleBulkAction = async (action) => {
    try {
      await api.post('/sessions/bulk', {
        action,
        ids: Array.from(selectedIds)
      });
      success(`${selectedIds.size} session${selectedIds.size !== 1 ? 's' : ''} ${action}d`);
      setSelectedIds(new Set());
      setShowBulkDeleteConfirm(false);
      await loadSessions();
    } catch (err) {
      error(err.response?.data?.error || `Failed to ${action} sessions`);
    }
  };

  const groupedSessions = useMemo(() => {
    const groups = [];
    let currentKey = null;

    sessions.forEach(session => {
      const dateKey = getLocalDateKey(session.created_at);
      if (dateKey !== currentKey) {
        currentKey = dateKey;
        groups.push({ dateKey, sessions: [session] });
      } else {
        groups[groups.length - 1].sessions.push(session);
      }
    });

    return groups;
  }, [sessions]);

  if (loading) {
    return (
      <div className="flex justify-center items-center h-64">
        <div className="text-xl text-gray-600 dark:text-gray-400">Loading...</div>
      </div>
    );
  }

  return (
    <div className="max-w-2xl mx-auto">
      <h1 className="text-4xl font-bold mb-8 text-gray-800 dark:text-gray-100">Session History</h1>

      <div className="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6">
        {/* Controls Bar */}
        <div className="flex flex-wrap justify-between items-center gap-3 mb-4">
          <div className="flex items-center gap-3">
            <div className="flex items-center gap-1.5">
              <span className="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider">Filter:</span>
              <select
                value={filter}
                onChange={(e) => handleFilterChange(e.target.value)}
                className="px-2 py-1.5 border border-gray-300 dark:border-gray-600 rounded-md text-sm text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 cursor-pointer"
              >
                <option value="default">Sessions</option>
                <option value="archived">Archived</option>
                <option value="all">All</option>
              </select>
            </div>
            <div className="flex items-center gap-1.5">
              <span className="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider">Show:</span>
              <select
                value={limit}
                onChange={(e) => handleLimitChange(e.target.value)}
                className="px-2 py-1.5 border border-gray-300 dark:border-gray-600 rounded-md text-sm text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 cursor-pointer"
              >
                <option value="5">5</option>
                <option value="10">10</option>
                <option value="25">25</option>
                <option value="50">50</option>
                <option value="all">All</option>
              </select>
            </div>
          </div>
          <div className="flex items-center gap-3">
            <span className="text-xs text-gray-400 dark:text-gray-500">
              {sessions.length === absoluteTotal
                ? `${absoluteTotal} session${absoluteTotal !== 1 ? 's' : ''} total`
                : `${sessions.length} visible (${absoluteTotal} total)`
              }
            </span>
            {isAuthenticated && (
              <button
                onClick={selectMode ? exitSelectMode : () => { setSelectMode(true); setPage(1); }}
                className={`px-3 py-1.5 rounded text-sm font-medium transition ${
                  selectMode
                    ? 'bg-indigo-600 dark:bg-indigo-700 text-white hover:bg-indigo-700 dark:hover:bg-indigo-800'
                    : 'bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-300 dark:hover:bg-gray-600'
                }`}
              >
                {selectMode ? '✓ Done' : 'Select'}
              </button>
            )}
          </div>
        </div>

        {/* Session List */}
        {sessions.length === 0 ? (
          <p className="text-gray-500 dark:text-gray-400">No sessions found</p>
        ) : (
          <div className="space-y-2">
            {groupedSessions.map((group, groupIdx) => {
              const isSundayGroup = isSunday(group.sessions[0].created_at);
              const isContinued = groupIdx === 0 && page > 1 && prevLastDate &&
                getLocalDateKey(prevLastDate) === group.dateKey;

              return (
                <div key={group.dateKey}>
                  {/* Day header bar */}
                  <div className="bg-gray-100 dark:bg-[#1e2a3a] rounded-md px-3.5 py-2 mb-2 flex justify-between items-center border-l-[3px] border-indigo-500">
                    <div className="flex items-center gap-2">
                      <span className="text-sm font-semibold text-indigo-700 dark:text-indigo-300">
                        {formatDayHeader(group.sessions[0].created_at)}
                      </span>
                      {isContinued && (
                        <span className="text-xs text-gray-400 dark:text-gray-500 italic">(continued)</span>
                      )}
                    </div>
                    {!isContinued && (
                      <div className="flex items-center gap-2">
                        <span className="text-xs text-gray-500 dark:text-gray-400">
                          {group.sessions.length} session{group.sessions.length !== 1 ? 's' : ''}
                        </span>
                        {isSundayGroup && (
                          <span className="text-xs font-semibold text-amber-700 dark:text-amber-300">🎲 Game Night</span>
                        )}
                      </div>
                    )}
                  </div>

                  {/* Session cards under this day */}
                  <div className="ml-3 space-y-1.5 mb-4">
                    {group.sessions.map(session => {
                      const isActive = session.is_active === 1;
                      const isSelected = selectedIds.has(session.id);
                      const isArchived = session.archived === 1;

                      return (
                        <div
                          key={session.id}
                          className={`border rounded-lg transition ${
                            selectMode && isActive
                              ? 'opacity-50 cursor-not-allowed border-gray-300 dark:border-gray-600'
                              : isSelected
                                ? 'border-indigo-500 bg-indigo-50 dark:bg-indigo-900/20 cursor-pointer'
                                : 'border-gray-300 dark:border-gray-600 hover:border-indigo-400 dark:hover:border-indigo-500 cursor-pointer'
                          }`}
                          onClick={() => {
                            if (longPressFired.current) {
                              longPressFired.current = false;
                              return;
                            }
                            if (selectMode) {
                              if (!isActive) toggleSelection(session.id);
                            } else {
                              navigate(`/history/${session.id}`);
                            }
                          }}
                          onPointerDown={() => {
                            if (!isActive) handlePointerDown(session.id);
                          }}
                          onPointerUp={handlePointerUp}
                          onPointerLeave={handlePointerUp}
                        >
                          <div className="p-4">
                            <div className="flex items-start gap-3">
                              {selectMode && (
                                <div className={`mt-0.5 w-5 h-5 flex-shrink-0 rounded border-2 flex items-center justify-center ${
                                  isActive
                                    ? 'border-gray-300 dark:border-gray-600 bg-gray-100 dark:bg-gray-700'
                                    : isSelected
                                      ? 'border-indigo-600 bg-indigo-600'
                                      : 'border-gray-300 dark:border-gray-600'
                                }`}>
                                  {isSelected && (
                                    <span className="text-white text-xs font-bold">✓</span>
                                  )}
                                </div>
                              )}
                              <div className="flex-1 min-w-0">
                                <div className="flex justify-between items-center mb-1">
                                  <div className="flex items-center gap-2 flex-wrap">
                                    <span className="font-semibold text-gray-800 dark:text-gray-100">
                                      Session #{session.id}
                                    </span>
                                    {isActive && (
                                      <span className="bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200 text-xs px-2 py-0.5 rounded">
                                        Active
                                      </span>
                                    )}
                                    {isArchived && (filter === 'all' || filter === 'archived') && (
                                      <span className="bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 text-xs px-2 py-0.5 rounded">
                                        Archived
                                      </span>
                                    )}
                                  </div>
                                  <span className="text-sm text-gray-500 dark:text-gray-400">
                                    {session.games_played} game{session.games_played !== 1 ? 's' : ''}
                                  </span>
                                </div>
                                <div className="text-sm text-gray-500 dark:text-gray-400">
                                  {formatTimeOnly(session.created_at)}
                                </div>
                                {session.has_notes && session.notes_preview && (
                                  <div className="mt-2 text-sm text-indigo-400 dark:text-indigo-300 bg-indigo-50 dark:bg-indigo-900/20 px-3 py-2 rounded border-l-2 border-indigo-500">
                                    {session.notes_preview}
                                  </div>
                                )}
                              </div>
                            </div>
                          </div>

                          {!selectMode && isAuthenticated && isActive && (
                            <div className="px-4 pb-4 pt-0">
                              <button
                                onClick={(e) => {
                                  e.stopPropagation();
                                  setClosingSession(session.id);
                                }}
                                className="w-full bg-orange-600 dark:bg-orange-700 text-white px-4 py-2 rounded text-sm hover:bg-orange-700 dark:hover:bg-orange-800 transition"
                              >
                                End Session
                              </button>
                            </div>
                          )}
                        </div>
                      );
                    })}
                  </div>
                </div>
              );
            })}
          </div>
        )}

        {/* Pagination bar */}
        {limit !== 'all' && (() => {
          const limitNum = parseInt(limit, 10);
          const totalPages = Math.ceil(totalCount / limitNum);
          if (totalPages <= 1) return null;
          return (
            <div className="flex justify-center items-center gap-4 py-3 mt-3 border-t border-gray-200 dark:border-gray-700">
              <button
                onClick={() => { setPage(p => p - 1); setSelectedIds(new Set()); }}
                disabled={page <= 1}
                className={`px-4 py-1.5 rounded-md text-sm font-medium transition ${
                  page <= 1
                    ? 'bg-gray-600 dark:bg-gray-700 text-gray-400 dark:text-gray-500 cursor-not-allowed'
                    : 'bg-indigo-600 text-white hover:bg-indigo-700'
                }`}
              >
                ← Prev
              </button>
              <span className="text-sm text-gray-500 dark:text-gray-400">
                Page {page} of {totalPages}
              </span>
              <button
                onClick={() => { setPage(p => p + 1); setSelectedIds(new Set()); }}
                disabled={page >= totalPages}
                className={`px-4 py-1.5 rounded-md text-sm font-medium transition ${
                  page >= totalPages
                    ? 'bg-gray-600 dark:bg-gray-700 text-gray-400 dark:text-gray-500 cursor-not-allowed'
                    : 'bg-indigo-600 text-white hover:bg-indigo-700'
                }`}
              >
                Next →
              </button>
            </div>
          );
        })()}

        {/* Multi-select Action Bar */}
        {selectMode && selectedIds.size > 0 && (
          <div className="sticky bottom-4 mt-4 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 p-4 flex justify-between items-center">
            <span className="text-sm font-semibold text-gray-700 dark:text-gray-300">
              {selectedIds.size} selected
            </span>
            <div className="flex gap-2">
              {filter !== 'archived' && (
                <button
                  onClick={() => handleBulkAction('archive')}
                  className="px-4 py-2 bg-indigo-600 text-white rounded-lg text-sm hover:bg-indigo-700 transition"
                >
                  Archive
                </button>
              )}
              {filter !== 'default' && (
                <button
                  onClick={() => handleBulkAction('unarchive')}
                  className="px-4 py-2 bg-green-600 text-white rounded-lg text-sm hover:bg-green-700 transition"
                >
                  Unarchive
                </button>
              )}
              <button
                onClick={() => setShowBulkDeleteConfirm(true)}
                className="px-4 py-2 bg-red-600 text-white rounded-lg text-sm hover:bg-red-700 transition"
              >
                Delete
              </button>
            </div>
          </div>
        )}
      </div>

      {/* End Session Modal */}
      {closingSession && (
        <EndSessionModal
          sessionId={closingSession}
          onClose={() => setClosingSession(null)}
          onConfirm={handleCloseSession}
        />
      )}

      {/* Bulk Delete Confirmation Modal */}
      {showBulkDeleteConfirm && (
        <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
          <div className="bg-white dark:bg-gray-800 rounded-lg p-8 max-w-md w-full">
            <h2 className="text-2xl font-bold mb-4 text-red-600 dark:text-red-400">
              Delete {selectedIds.size} Session{selectedIds.size !== 1 ? 's' : ''}?
            </h2>
            <p className="text-gray-700 dark:text-gray-300 mb-6">
              This will permanently delete {selectedIds.size} session{selectedIds.size !== 1 ? 's' : ''} and all associated games and chat logs. This action cannot be undone.
            </p>
            <div className="flex gap-4">
              <button
                onClick={() => handleBulkAction('delete')}
                className="flex-1 bg-red-600 dark:bg-red-700 text-white py-3 rounded-lg hover:bg-red-700 dark:hover:bg-red-800 transition font-semibold"
              >
                Delete Permanently
              </button>
              <button
                onClick={() => setShowBulkDeleteConfirm(false)}
                className="flex-1 bg-gray-600 dark:bg-gray-700 text-white py-3 rounded-lg hover:bg-gray-700 dark:hover:bg-gray-800 transition"
              >
                Cancel
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function EndSessionModal({ sessionId, onClose, onConfirm }) {
  const [notes, setNotes] = useState('');

  return (
    <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
      <div className="bg-white dark:bg-gray-800 rounded-lg p-8 max-w-md w-full">
        <h2 className="text-2xl font-bold mb-4 dark:text-gray-100">End Session #{sessionId}</h2>
        <div className="mb-4">
          <label className="block text-gray-700 dark:text-gray-300 font-semibold mb-2">
            Session Notes (optional)
          </label>
          <textarea
            value={notes}
            onChange={(e) => setNotes(e.target.value)}
            className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg h-32 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100"
            placeholder="Add any notes about this session..."
          />
        </div>
        <div className="flex gap-4">
          <button
            onClick={() => onConfirm(sessionId, notes)}
            className="flex-1 bg-orange-600 dark:bg-orange-700 text-white py-3 rounded-lg hover:bg-orange-700 dark:hover:bg-orange-800 transition"
          >
            End Session
          </button>
          <button
            onClick={onClose}
            className="flex-1 bg-gray-600 dark:bg-gray-700 text-white py-3 rounded-lg hover:bg-gray-700 dark:hover:bg-gray-800 transition"
          >
            Cancel
          </button>
        </div>
      </div>
    </div>
  );
}

export default History;
