import { useCallback, useEffect, useMemo, useState } from "react";
import Footer from "../components/Footer";
import Header from "../components/Header";
import { useAuth } from "../context/auth";
import Login from "../Login";
import { formatDate, getFirstWorkDayOfWeek, getHumanDate, getLastWorkDayOfWeek } from "../Utils";
import { WeeklyStats, LunchChoice, VotingStats, FeatureRequest, getStats, getVotingStats } from "../../../types";
import Loader from "../components/Loader";
import { faChevronLeft, faChevronRight, faGear } from "@fortawesome/free-solid-svg-icons";
import { Legend, Line, LineChart, Tooltip, XAxis, YAxis } from "recharts";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { getLunchChoiceName } from "../enums";
import './StatsPage.scss';

const CHART_WIDTH = 1400;
const CHART_HEIGHT = 700;
const STROKE_WIDTH = 2.5;

const COLORS = [
  '#ff1493',
  '#1e90ff',
  '#c5a700',
  '#006400',
  '#b300ff',
  '#ff4500',
  '#bc8f8f',
  '#00ff00',
  '#7c7c7c',
]

export default function StatsPage() {
  const auth = useAuth();
  const [dateRange, setDateRange] = useState<Date[]>();
  const [data, setData] = useState<WeeklyStats>();
  const [votingStats, setVotingStats] = useState<VotingStats>();

  // Prvotní nastavení aktuálního týdne
  useEffect(() => {
    const today = new Date();
    setDateRange([getFirstWorkDayOfWeek(today), getLastWorkDayOfWeek(today)]);
  }, []);

  // Přenačtení pro zvolený týden
  useEffect(() => {
    if (dateRange) {
      getStats({ query: { startDate: formatDate(dateRange[0]), endDate: formatDate(dateRange[1]) } }).then(response => {
        setData(response.data);
      });
    }
  }, [dateRange]);

  // Načtení statistik hlasování
  useEffect(() => {
    getVotingStats().then(response => {
      setVotingStats(response.data);
    });
  }, []);

  const sortedVotingStats = useMemo(() => {
    if (!votingStats) return [];
    return Object.entries(votingStats)
      .sort((a, b) => (b[1] as number) - (a[1] as number));
  }, [votingStats]);

  const renderLine = (location: LunchChoice) => {
    const index = Object.values(LunchChoice).indexOf(location);
    return <Line key={location} name={getLunchChoiceName(location)} type="monotone" dataKey={data => data.locations[location] ?? 0} stroke={COLORS[index]} strokeWidth={STROKE_WIDTH} />
  }

  const handlePreviousWeek = () => {
    if (dateRange) {
      const previousStartDate = new Date(dateRange[0]);
      previousStartDate.setDate(previousStartDate.getDate() - 7);
      const previousEndDate = new Date(previousStartDate);
      previousEndDate.setDate(previousEndDate.getDate() + 4);
      setDateRange([previousStartDate, previousEndDate]);
    }
  }

  const handleNextWeek = () => {
    if (dateRange) {
      const nextStartDate = new Date(dateRange[0]);
      nextStartDate.setDate(nextStartDate.getDate() + 7);
      const nextEndDate = new Date(nextStartDate);
      nextEndDate.setDate(nextEndDate.getDate() + 4);
      setDateRange([nextStartDate, nextEndDate]);
    }
  }

  const isCurrentOrFutureWeek = useMemo(() => {
    if (!dateRange) return true;
    const currentWeekEnd = getLastWorkDayOfWeek(new Date());
    currentWeekEnd.setHours(23, 59, 59, 999);
    return dateRange[1] >= currentWeekEnd;
  }, [dateRange]);

  const handleKeyDown = useCallback((e: any) => {
    if (e.keyCode === 37) {
      handlePreviousWeek();
    } else if (e.keyCode === 39 && !isCurrentOrFutureWeek) {
      handleNextWeek()
    }
  }, [dateRange, isCurrentOrFutureWeek]);

  useEffect(() => {
    document.addEventListener('keydown', handleKeyDown);
    return () => {
      document.removeEventListener('keydown', handleKeyDown);
    }
  }, [handleKeyDown]);

  if (!auth?.login) {
    return <Login />;
  }

  if (!dateRange) {
    return <Loader
      icon={faGear}
      description={'Načítám data...'}
      animation={'fa-bounce'}
    />
  }

  return (
    <>
      <Header />
      <div className="stats-page">
        <h1>Statistiky</h1>
        <div className="week-navigator">
          <span title="Předchozí týden">
            <FontAwesomeIcon icon={faChevronLeft} style={{ cursor: "pointer" }} onClick={handlePreviousWeek} />
          </span>
          <h2 className="date-range">{getHumanDate(dateRange[0])} - {getHumanDate(dateRange[1])}</h2>
          <span title="Následující týden">
            <FontAwesomeIcon icon={faChevronRight} style={{ cursor: "pointer", visibility: isCurrentOrFutureWeek ? "hidden" : "visible" }} onClick={handleNextWeek} />
          </span>
        </div>
        <LineChart width={CHART_WIDTH} height={CHART_HEIGHT} data={data}>
          {Object.values(LunchChoice).map(location => renderLine(location))}
          <XAxis dataKey="date" />
          <YAxis />
          <Tooltip />
          <Legend />
        </LineChart>
        {sortedVotingStats.length > 0 && (
          <div className="voting-stats-section">
            <h2>Hlasování o funkcích</h2>
            <table className="voting-stats-table">
              <thead>
                <tr>
                  <th>Funkce</th>
                  <th>Počet hlasů</th>
                </tr>
              </thead>
              <tbody>
                {sortedVotingStats.map(([feature, count]) => (
                  <tr key={feature}>
                    <td>{FeatureRequest[feature as keyof typeof FeatureRequest] ?? feature}</td>
                    <td>{count as number}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
      <Footer />
    </>
  );
}
