import { useState, useEffect, useRef, useCallback } from 'react';
import './game-library.css';

/* ══════════════════════════════════════════════════════════════════
   TYPES
   ══════════════════════════════════════════════════════════════════ */

interface UserSummary {
  steamId: string;
  personaName: string;
  avatarUrl: string;
  gameCount: number;
  lastUpdated: string;
}

interface SteamGame {
  appid: number;
  name: string;
  playtime_forever: number;
  img_icon_url: string;
}

interface CommonGame {
  appid: number;
  name: string;
  img_icon_url: string;
  owners: Array<{ steamId: string; personaName: string; playtime_forever: number }>;
}

interface SearchResult {
  appid: number;
  name: string;
  img_icon_url: string;
  owners: Array<{ steamId: string; personaName: string }>;
}

/* ══════════════════════════════════════════════════════════════════
   HELPERS
   ══════════════════════════════════════════════════════════════════ */

function gameIconUrl(appid: number, hash: string): string {
  return `https://media.steampowered.com/steamcommunity/public/images/apps/${appid}/${hash}.jpg`;
}

function formatPlaytime(minutes: number): string {
  if (minutes < 60) return `${minutes} Min`;
  const h = Math.floor(minutes / 60);
  const m = minutes % 60;
  return m > 0 ? `${h}h ${m}m` : `${h}h`;
}

function formatDate(iso: string): string {
  try {
    return new Date(iso).toLocaleDateString('de-DE', {
      day: '2-digit',
      month: '2-digit',
      year: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
    });
  } catch {
    return iso;
  }
}

/* ══════════════════════════════════════════════════════════════════
   COMPONENT
   ══════════════════════════════════════════════════════════════════ */

export default function GameLibraryTab({ data }: { data: any }) {
  // ── State ──
  const [users, setUsers] = useState<UserSummary[]>([]);
  const [mode, setMode] = useState<'overview' | 'user' | 'common'>('overview');
  const [selectedUser, setSelectedUser] = useState<string | null>(null);
  const [selectedUsers, setSelectedUsers] = useState<Set<string>>(new Set());
  const [userGames, setUserGames] = useState<SteamGame[] | null>(null);
  const [commonGames, setCommonGames] = useState<CommonGame[] | null>(null);
  const [searchQuery, setSearchQuery] = useState('');
  const [searchResults, setSearchResults] = useState<SearchResult[] | null>(null);
  const [loading, setLoading] = useState(false);

  const searchTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const filterInputRef = useRef<HTMLInputElement>(null);
  const [filterQuery, setFilterQuery] = useState('');

  // ── SSE data sync ──
  useEffect(() => {
    if (data?.users) setUsers(data.users);
  }, [data]);

  // ── Refetch users ──
  const fetchUsers = useCallback(async () => {
    try {
      const resp = await fetch('/api/game-library/users');
      if (resp.ok) {
        const d = await resp.json();
        setUsers(d.users || []);
      }
    } catch {
      /* silent */
    }
  }, []);

  // ── Steam login ──
  const connectSteam = useCallback(() => {
    const w = window.open('/api/game-library/steam/login', '_blank', 'width=800,height=600');
    const interval = setInterval(() => {
      if (w && w.closed) {
        clearInterval(interval);
        setTimeout(fetchUsers, 1000);
      }
    }, 500);
  }, [fetchUsers]);

  // ── Refetch on window focus (after login redirect) ──
  useEffect(() => {
    const onFocus = () => fetchUsers();
    window.addEventListener('focus', onFocus);
    return () => window.removeEventListener('focus', onFocus);
  }, [fetchUsers]);

  // ── View user library ──
  const viewUser = useCallback(async (steamId: string) => {
    setMode('user');
    setSelectedUser(steamId);
    setUserGames(null);
    setFilterQuery('');
    setLoading(true);
    try {
      const resp = await fetch(`/api/game-library/user/${steamId}`);
      if (resp.ok) {
        const d = await resp.json();
        setUserGames(d.games || d);
      }
    } catch {
      /* silent */
    } finally {
      setLoading(false);
    }
  }, []);

  // ── Refresh single user ──
  const refreshUser = useCallback(async (steamId: string, e?: React.MouseEvent) => {
    if (e) e.stopPropagation();
    try {
      await fetch(`/api/game-library/user/${steamId}?refresh=true`);
      await fetchUsers();
      if (mode === 'user' && selectedUser === steamId) {
        viewUser(steamId);
      }
    } catch {
      /* silent */
    }
  }, [fetchUsers, mode, selectedUser, viewUser]);

  // ── Toggle user selection for common games ──
  const toggleCommonUser = useCallback((steamId: string) => {
    setSelectedUsers(prev => {
      const next = new Set(prev);
      if (next.has(steamId)) next.delete(steamId);
      else next.add(steamId);
      return next;
    });
  }, []);

  // ── Find common games ──
  const findCommonGames = useCallback(async () => {
    if (selectedUsers.size < 2) return;
    setMode('common');
    setCommonGames(null);
    setLoading(true);
    try {
      const ids = Array.from(selectedUsers).join(',');
      const resp = await fetch(`/api/game-library/common-games?users=${ids}`);
      if (resp.ok) {
        const d = await resp.json();
        setCommonGames(d.games || d);
      }
    } catch {
      /* silent */
    } finally {
      setLoading(false);
    }
  }, [selectedUsers]);

  // ── Search (debounced) ──
  const handleSearch = useCallback((value: string) => {
    setSearchQuery(value);
    if (searchTimerRef.current) clearTimeout(searchTimerRef.current);
    if (value.length < 2) {
      setSearchResults(null);
      return;
    }
    searchTimerRef.current = setTimeout(async () => {
      try {
        const resp = await fetch(`/api/game-library/search?q=${encodeURIComponent(value)}`);
        if (resp.ok) {
          const d = await resp.json();
          setSearchResults(d.results || d);
        }
      } catch {
        /* silent */
      }
    }, 300);
  }, []);

  // ── Back to overview ──
  const goBack = useCallback(() => {
    setMode('overview');
    setSelectedUser(null);
    setUserGames(null);
    setCommonGames(null);
    setFilterQuery('');
  }, []);

  // ── Resolve user by steamId ──
  const getUser = useCallback(
    (steamId: string) => users.find(u => u.steamId === steamId),
    [users],
  );

  // ── Filtered user games ──
  const filteredGames = userGames
    ? userGames
        .filter(g => !filterQuery || g.name.toLowerCase().includes(filterQuery.toLowerCase()))
        .sort((a, b) => b.playtime_forever - a.playtime_forever)
    : null;

  /* ════════════════════════════════════════════════════════════════
     RENDER
     ════════════════════════════════════════════════════════════════ */

  return (
    <div className="gl-container">
      {/* ── Top bar ── */}
      <div className="gl-topbar">
        <button className="gl-connect-btn" onClick={connectSteam}>
          Mit Steam verbinden
        </button>
        <div className="gl-user-chips">
          {users.map(u => (
            <div
              key={u.steamId}
              className={`gl-user-chip${selectedUser === u.steamId ? ' selected' : ''}`}
              onClick={() => viewUser(u.steamId)}
            >
              <img className="gl-user-chip-avatar" src={u.avatarUrl} alt={u.personaName} />
              <span className="gl-user-chip-name">{u.personaName}</span>
              <span className="gl-user-chip-count">({u.gameCount})</span>
              <button
                className="gl-user-chip-refresh"
                onClick={e => refreshUser(u.steamId, e)}
                title="Aktualisieren"
              >
                &#x21bb;
              </button>
            </div>
          ))}
        </div>
      </div>

      {/* ── Overview mode ── */}
      {mode === 'overview' && (
        <>
          {users.length === 0 ? (
            <div className="gl-empty">
              <div className="gl-empty-icon">&#x1F3AE;</div>
              <h3>Keine Steam-Konten verbunden</h3>
              <p>
                Klicke oben auf &ldquo;Mit Steam verbinden&rdquo;, um deine Spielebibliothek
                hinzuzufuegen.
              </p>
            </div>
          ) : (
            <>
              {/* User cards */}
              <p className="gl-section-title">Verbundene Spieler</p>
              <div className="gl-users-grid">
                {users.map(u => (
                  <div key={u.steamId} className="gl-user-card" onClick={() => viewUser(u.steamId)}>
                    <img className="gl-user-card-avatar" src={u.avatarUrl} alt={u.personaName} />
                    <span className="gl-user-card-name">{u.personaName}</span>
                    <span className="gl-user-card-games">{u.gameCount} Spiele</span>
                    <span className="gl-user-card-updated">
                      Aktualisiert: {formatDate(u.lastUpdated)}
                    </span>
                  </div>
                ))}
              </div>

              {/* Common games finder */}
              {users.length >= 2 && (
                <div className="gl-common-finder">
                  <h3>Gemeinsame Spiele finden</h3>
                  <div className="gl-common-users">
                    {users.map(u => (
                      <label
                        key={u.steamId}
                        className={`gl-common-check${selectedUsers.has(u.steamId) ? ' checked' : ''}`}
                      >
                        <input
                          type="checkbox"
                          checked={selectedUsers.has(u.steamId)}
                          onChange={() => toggleCommonUser(u.steamId)}
                        />
                        <img
                          className="gl-common-check-avatar"
                          src={u.avatarUrl}
                          alt={u.personaName}
                        />
                        {u.personaName}
                      </label>
                    ))}
                  </div>
                  <button
                    className="gl-common-find-btn"
                    disabled={selectedUsers.size < 2}
                    onClick={findCommonGames}
                  >
                    Finden
                  </button>
                </div>
              )}

              {/* Search */}
              <div className="gl-search">
                <input
                  className="gl-search-input"
                  type="text"
                  placeholder="Spiel suchen..."
                  value={searchQuery}
                  onChange={e => handleSearch(e.target.value)}
                />
              </div>

              {/* Search results */}
              {searchResults && searchResults.length > 0 && (
                <>
                  <p className="gl-search-results-title">
                    {searchResults.length} Ergebnis{searchResults.length !== 1 ? 'se' : ''}
                  </p>
                  <div className="gl-game-list">
                    {searchResults.map(g => (
                      <div key={g.appid} className="gl-game-item">
                        {g.img_icon_url ? (
                          <img
                            className="gl-game-icon"
                            src={gameIconUrl(g.appid, g.img_icon_url)}
                            alt=""
                          />
                        ) : (
                          <div className="gl-game-icon" />
                        )}
                        <span className="gl-game-name">{g.name}</span>
                        <div className="gl-game-owners">
                          {g.owners.map(o => {
                            const u = getUser(o.steamId);
                            return u ? (
                              <img
                                key={o.steamId}
                                className="gl-game-owner-avatar"
                                src={u.avatarUrl}
                                alt={o.personaName}
                                title={o.personaName}
                              />
                            ) : null;
                          })}
                        </div>
                      </div>
                    ))}
                  </div>
                </>
              )}

              {searchResults && searchResults.length === 0 && (
                <p className="gl-search-results-title">Keine Ergebnisse gefunden.</p>
              )}
            </>
          )}
        </>
      )}

      {/* ── User mode ── */}
      {mode === 'user' && (() => {
        const user = selectedUser ? getUser(selectedUser) : null;
        return (
          <>
            <div className="gl-detail-header">
              <button className="gl-back-btn" onClick={goBack}>
                &#x2190; Zurueck
              </button>
              {user && (
                <>
                  <img className="gl-detail-avatar" src={user.avatarUrl} alt={user.personaName} />
                  <div className="gl-detail-info">
                    <div className="gl-detail-name">
                      {user.personaName}
                      <span className="gl-game-count">{user.gameCount} Spiele</span>
                    </div>
                    <div className="gl-detail-sub">
                      Aktualisiert: {formatDate(user.lastUpdated)}
                    </div>
                  </div>
                  <button
                    className="gl-refresh-btn"
                    onClick={() => refreshUser(user.steamId)}
                    title="Aktualisieren"
                  >
                    &#x21bb;
                  </button>
                </>
              )}
            </div>

            {loading ? (
              <div className="gl-loading">Bibliothek wird geladen...</div>
            ) : filteredGames ? (
              <>
                <div className="gl-search">
                  <input
                    ref={filterInputRef}
                    className="gl-search-input"
                    type="text"
                    placeholder="Bibliothek durchsuchen..."
                    value={filterQuery}
                    onChange={e => setFilterQuery(e.target.value)}
                  />
                </div>
                {filteredGames.length === 0 ? (
                  <p className="gl-search-results-title">Keine Spiele gefunden.</p>
                ) : (
                  <div className="gl-game-list">
                    {filteredGames.map(g => (
                      <div key={g.appid} className="gl-game-item">
                        {g.img_icon_url ? (
                          <img
                            className="gl-game-icon"
                            src={gameIconUrl(g.appid, g.img_icon_url)}
                            alt=""
                          />
                        ) : (
                          <div className="gl-game-icon" />
                        )}
                        <span className="gl-game-name">{g.name}</span>
                        <span className="gl-game-playtime">
                          {formatPlaytime(g.playtime_forever)}
                        </span>
                      </div>
                    ))}
                  </div>
                )}
              </>
            ) : null}
          </>
        );
      })()}

      {/* ── Common mode ── */}
      {mode === 'common' && (() => {
        const selected = Array.from(selectedUsers)
          .map(id => getUser(id))
          .filter(Boolean) as UserSummary[];
        const names = selected.map(u => u.personaName).join(', ');
        return (
          <>
            <div className="gl-detail-header">
              <button className="gl-back-btn" onClick={goBack}>
                &#x2190; Zurueck
              </button>
              <div className="gl-detail-avatars">
                {selected.map(u => (
                  <img key={u.steamId} src={u.avatarUrl} alt={u.personaName} />
                ))}
              </div>
              <div className="gl-detail-info">
                <div className="gl-detail-name">Gemeinsame Spiele</div>
                <div className="gl-detail-sub">von {names}</div>
              </div>
            </div>

            {loading ? (
              <div className="gl-loading">Gemeinsame Spiele werden gesucht...</div>
            ) : commonGames ? (
              commonGames.length === 0 ? (
                <div className="gl-empty">
                  <div className="gl-empty-icon">&#x1F614;</div>
                  <h3>Keine gemeinsamen Spiele</h3>
                  <p>Die ausgewaehlten Spieler besitzen leider keine gemeinsamen Spiele.</p>
                </div>
              ) : (
                <>
                  <p className="gl-section-title">
                    {commonGames.length} gemeinsame{commonGames.length !== 1 ? ' Spiele' : 's Spiel'}
                  </p>
                  <div className="gl-game-list">
                    {commonGames.map(g => (
                      <div key={g.appid} className="gl-game-item">
                        {g.img_icon_url ? (
                          <img
                            className="gl-game-icon"
                            src={gameIconUrl(g.appid, g.img_icon_url)}
                            alt=""
                          />
                        ) : (
                          <div className="gl-game-icon" />
                        )}
                        <span className="gl-game-name">{g.name}</span>
                        <div className="gl-common-playtimes">
                          {g.owners.map(o => (
                            <span key={o.steamId} className="gl-common-pt">
                              {o.personaName}: {formatPlaytime(o.playtime_forever)}
                            </span>
                          ))}
                        </div>
                      </div>
                    ))}
                  </div>
                </>
              )
            ) : null}
          </>
        );
      })()}
    </div>
  );
}
