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, getStats } 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>();

  // 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]);

  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>
      </div>
      <Footer />
    </>
  );
}
