import React, { useState, useEffect, useContext, useCallback } from "react";
import axios from "axios";
import { toast } from "react-toastify";

import { AuthContext } from "../context/AuthContext";
import LeaderboardCard from "./LeaderboardCard";

/**
 * Leaderboard component displays top users by points with different timeframes
 */
const Leaderboard = () => {
  const { auth } = useContext(AuthContext);
  const [activeTab, setActiveTab] = useState("global");
  const [leaderboard, setLeaderboard] = useState([]);
  const [stats, setStats] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);
  const limit = 50;

  // Load leaderboard data based on active tab
  const loadLeaderboard = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);

      const offset = (page - 1) * limit;
      let endpoint = "";

      switch (activeTab) {
        case "global":
          endpoint = `/api/leaderboard/global?limit=${limit}&offset=${offset}`;
          break;
        case "weekly":
          endpoint = `/api/leaderboard/weekly?limit=${limit}&offset=${offset}`;
          break;
        case "monthly":
          endpoint = `/api/leaderboard/monthly?limit=${limit}&offset=${offset}`;
          break;
        case "friends":
          endpoint = `/api/leaderboard/friends?limit=${limit}&offset=${offset}`;
          break;
        default:
          endpoint = `/api/leaderboard/global?limit=${limit}&offset=${offset}`;
      }

      const config = {};
      // Friends endpoint requires authentication
      if (activeTab === "friends") {
        const token = localStorage.getItem("token");
        config.headers = { "x-auth-token": token };
      }

      const res = await axios.get(endpoint, config);
      setLeaderboard(res.data);
      setHasMore(res.data.length === limit);
    } catch (err) {
      console.error("Error loading leaderboard:", err);
      const errorMessage =
        err.response?.data?.msg ||
        err.response?.data?.message ||
        "Failed to load leaderboard. Please try again later.";
      setError(errorMessage);
      toast.error(errorMessage);
    } finally {
      setLoading(false);
    }
  }, [activeTab, page]);

  // Load leaderboard stats
  const loadStats = useCallback(async () => {
    try {
      const res = await axios.get("/api/leaderboard/stats");
      setStats(res.data);
    } catch (err) {
      console.error("Error loading leaderboard stats:", err);
    }
  }, []);

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

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

  // Handle tab change
  const handleTabChange = (tab) => {
    if (tab === "friends" && !auth.isAuthenticated) {
      toast.warning("Please login to view friends leaderboard");
      return;
    }
    setActiveTab(tab);
    setPage(1);
    setLeaderboard([]);
  };

  // Handle pagination
  const handlePreviousPage = () => {
    if (page > 1) {
      setPage(page - 1);
    }
  };

  const handleNextPage = () => {
    if (hasMore) {
      setPage(page + 1);
    }
  };

  if (loading && leaderboard.length === 0) {
    return (
      <div className="text-center mt-5">
        <div className="spinner-border" role="status">
          <span className="sr-only">Loading...</span>
        </div>
        <p>Loading leaderboard...</p>
      </div>
    );
  }

  if (error) {
    return (
      <div className="alert alert-danger m-3" role="alert">
        <h4 className="alert-heading">Error Loading Leaderboard</h4>
        <p>{error}</p>
        <hr />
        <button className="btn btn-primary" onClick={loadLeaderboard}>
          Retry
        </button>
      </div>
    );
  }

  return (
    <div>
      <h1>Leaderboard</h1>

      {/* Leaderboard Stats */}
      {stats && (
        <div className="alert alert-info mb-4">
          <div className="row">
            <div className="col-md-3 col-6 mb-2">
              <strong>Total Users:</strong> {stats.totalUsers}
            </div>
            <div className="col-md-3 col-6 mb-2">
              <strong>Total Points:</strong> {stats.totalPoints.toLocaleString()}
            </div>
            <div className="col-md-3 col-6 mb-2">
              <strong>Avg Points:</strong> {Math.round(stats.averagePoints)}
            </div>
            <div className="col-md-3 col-6 mb-2">
              <strong>Top Score:</strong> {stats.maxPoints.toLocaleString()}
            </div>
          </div>
        </div>
      )}

      {/* Tab Navigation */}
      <ul className="nav nav-tabs mb-4">
        <li className="nav-item">
          <button
            className={`nav-link ${activeTab === "global" ? "active" : ""}`}
            onClick={() => handleTabChange("global")}
          >
            All Time
          </button>
        </li>
        <li className="nav-item">
          <button
            className={`nav-link ${activeTab === "weekly" ? "active" : ""}`}
            onClick={() => handleTabChange("weekly")}
          >
            This Week
          </button>
        </li>
        <li className="nav-item">
          <button
            className={`nav-link ${activeTab === "monthly" ? "active" : ""}`}
            onClick={() => handleTabChange("monthly")}
          >
            This Month
          </button>
        </li>
        <li className="nav-item">
          <button
            className={`nav-link ${activeTab === "friends" ? "active" : ""}`}
            onClick={() => handleTabChange("friends")}
            disabled={!auth.isAuthenticated}
          >
            Friends {!auth.isAuthenticated && "(Login Required)"}
          </button>
        </li>
      </ul>

      {/* Current User Info */}
      {auth.user && activeTab !== "friends" && (
        <div className="alert alert-success mb-4">
          <strong>Your Points:</strong>{" "}
          <span className="badge badge-primary">{auth.user.points || 0}</span>
        </div>
      )}

      {/* Leaderboard List */}
      {leaderboard.length === 0 ? (
        <div className="alert alert-info">
          {activeTab === "friends"
            ? "No friends to display. Add friends to see them on the leaderboard!"
            : "No users to display yet. Be the first to earn points!"}
        </div>
      ) : (
        <>
          <div className="row">
            {leaderboard.map((entry, index) => (
              <LeaderboardCard
                key={entry.userId}
                entry={entry}
                rank={(page - 1) * limit + index + 1}
                isCurrentUser={auth.user && entry.userId === auth.user._id}
              />
            ))}
          </div>

          {/* Pagination */}
          <div className="d-flex justify-content-between align-items-center mt-4">
            <button
              className="btn btn-secondary"
              onClick={handlePreviousPage}
              disabled={page === 1 || loading}
            >
              Previous
            </button>
            <span>
              Page {page} {hasMore && "- More available"}
            </span>
            <button
              className="btn btn-secondary"
              onClick={handleNextPage}
              disabled={!hasMore || loading}
            >
              {loading ? (
                <>
                  <span
                    className="spinner-border spinner-border-sm mr-2"
                    role="status"
                    aria-hidden="true"
                  ></span>
                  Loading...
                </>
              ) : (
                "Next"
              )}
            </button>
          </div>
        </>
      )}
    </div>
  );
};

export default Leaderboard;
