import React, { useState, useEffect, useRef, useCallback } from "react";
import api from "../services/api";
import { useNavigate, useSearchParams } from "react-router-dom";
import { useSelector } from "react-redux";
import {
  Container,
  Typography,
  LinearProgress,
  Box,
  Paper,
  Button,
  IconButton,
  Select,
  MenuItem,
  Popover,
} from "@material-ui/core";
// LinearProgress kept for the initializing state only
import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import CheckIcon from "@material-ui/icons/Check";
import pulpGif from "../static/images/pulp.gif";

const CURRENT_YEAR = new Date().getFullYear();
const YEARS = Array.from({ length: CURRENT_YEAR - 2000 + 1}, (_, i) => 2000 + i).reverse();

const DAY_LABELS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

const MONTH_NAMES = [
  "January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December",
];

const PosterSelector = () => {
  const [currentMonth, setCurrentMonth] = useState(null);
  const [moviesByDate, setMoviesByDate] = useState({});
  const [loading, setLoading] = useState(true);
  const [initializing, setInitializing] = useState(true);
  const [popoverAnchor, setPopoverAnchor] = useState(null);
  const [popoverMovies, setPopoverMovies] = useState([]);
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();
  const posterSelections = useSelector((state) => state.posterSelections);
  const dataSource = useSelector((state) => state.dataSource);

  useEffect(() => {
    const init = async () => {
      try {
        const csvCheck = await api.get("/api/check-csv");
        if (!csvCheck.data.fileExists) {
          navigate("/");
          return;
        }

        const urlMonth = searchParams.get("month");
        if (urlMonth) {
          const [year, month] = urlMonth.split("-").map(Number);
          setCurrentMonth({ year, month: month - 1 });
          setInitializing(false);
          return;
        }

        const res = await api.get("/api/movies?page=1&limit=1");
        if (res.data.movies?.length > 0) {
          const latestDate = res.data.movies[0]["Watched Date"];
          const [year, month] = latestDate.split("-").map(Number);
          setCurrentMonth({ year, month: month - 1 });
        } else {
          const now = new Date();
          setCurrentMonth({ year: now.getFullYear(), month: now.getMonth() });
        }
      } catch {
        navigate("/");
      } finally {
        setInitializing(false);
      }
    };
    init();
  }, [navigate, searchParams]);

  useEffect(() => {
    if (!currentMonth) return;
    fetchMoviesForMonth(currentMonth.year, currentMonth.month);
  }, [currentMonth]);

  const fetchMoviesForMonth = useCallback(async (year, month) => {
    setLoading(true);
    try {
      const monthStr = `${year}-${String(month + 1).padStart(2, "0")}`;
      const res = await api.get(`/api/movies?month=${monthStr}`);
      const map = {};
      res.data.movies?.forEach((movie) => {
        const date = movie["Watched Date"];
        if (!map[date]) map[date] = [];
        map[date].push(movie);
      });
      setMoviesByDate(map);
    } catch (err) {
      console.error("Error fetching movies:", err);
    } finally {
      setLoading(false);
    }
  }, []);

  const currentMonthRef = useRef(currentMonth);
  useEffect(() => { currentMonthRef.current = currentMonth; }, [currentMonth]);

  useEffect(() => {
    const handleSync = () => {
      const m = currentMonthRef.current;
      if (m) fetchMoviesForMonth(m.year, m.month);
    };
    window.addEventListener('diary-synced', handleSync);
    return () => window.removeEventListener('diary-synced', handleSync);
  }, [fetchMoviesForMonth]);

  const updateMonth = (year, month) => {
    setCurrentMonth({ year, month });
    setSearchParams({ month: `${year}-${String(month + 1).padStart(2, "0")}` });
  };

  const goToPrevMonth = () => {
    const { year, month } = currentMonth;
    if (month === 0) updateMonth(year - 1, 11);
    else updateMonth(year, month - 1);
  };

  const goToNextMonth = () => {
    const { year, month } = currentMonth;
    if (month === 11) updateMonth(year + 1, 0);
    else updateMonth(year, month + 1);
  };

  const goToToday = () => {
    const now = new Date();
    updateMonth(now.getFullYear(), now.getMonth());
  };

  const handleGoToUpload = async () => {
    try {
      await api.delete("/api/delete-csv");
    } catch {
      // server may have restarted, proceed anyway
    }
    navigate("/");
  };

  const handleMovieClick = (movie) => {
    navigate(
      `/posters/${encodeURIComponent(movie.Name)}/${encodeURIComponent(movie.Year)}`,
      { state: { watchedDate: movie["Watched Date"] } }
    );
  };

  const handleCellClick = (e, movies) => {
    if (!movies.length) return;
    if (movies.length === 1) {
      handleMovieClick(movies[0]);
    } else {
      setPopoverMovies(movies);
      setPopoverAnchor(e.currentTarget);
    }
  };

  const buildCalendarCells = () => {
    if (!currentMonth) return [];
    const { year, month } = currentMonth;
    const firstDayOfWeek = new Date(year, month, 1).getDay();
    const startOffset = (firstDayOfWeek + 6) % 7; // Mon=0
    const daysInMonth = new Date(year, month + 1, 0).getDate();

    const cells = [];
    for (let i = 0; i < startOffset; i++) cells.push(null);
    for (let d = 1; d <= daysInMonth; d++) cells.push(d);
    return cells;
  };

  if (initializing) {
    return (
      <>
        <Container className="poster-selector">
          <Paper elevation={3} className="content-paper">
            <Box className="progress-container">
              <LinearProgress />
            </Box>
          </Paper>
        </Container>
      </>
    );
  }

  const cells = buildCalendarCells();
  const hasAnyMovie = Object.keys(moviesByDate).length > 0;
  const today = new Date();
  const isCurrentMonth =
    currentMonth.year === today.getFullYear() &&
    currentMonth.month === today.getMonth();
  const isFutureMonth =
    currentMonth.year > today.getFullYear() ||
    (currentMonth.year === today.getFullYear() && currentMonth.month > today.getMonth());

  return (
    <>
      <Container className="poster-selector">
        <Paper elevation={3} className="content-paper">
          <Box className="calendar-nav">
            <Button className="calendar-today-btn" onClick={goToToday} size="small">
              Today
            </Button>
            <Box className="calendar-nav-center">
              <IconButton onClick={goToPrevMonth} className="calendar-nav-btn">
                <ChevronLeftIcon />
              </IconButton>
              <Typography variant="h6" className="calendar-month-label">
                {currentMonth
                  ? `${MONTH_NAMES[currentMonth.month]} ${currentMonth.year}`
                  : ""}
              </Typography>
              <IconButton onClick={goToNextMonth} className="calendar-nav-btn" disabled={isCurrentMonth}>
                <ChevronRightIcon />
              </IconButton>
            </Box>
            <Box className="calendar-month-selects">
              <Select
                value={currentMonth?.month ?? ""}
                onChange={(e) => updateMonth(currentMonth.year, e.target.value)}
                className="calendar-select"
                disableUnderline
                MenuProps={{ PaperProps: { className: "calendar-select-menu" } }}
              >
                {MONTH_NAMES.map((name, i) => {
                  const disabled =
                    currentMonth.year === today.getFullYear() && i > today.getMonth();
                  return <MenuItem key={i} value={i} disabled={disabled}>{name}</MenuItem>;
                })}
              </Select>
              <Select
                value={currentMonth?.year ?? ""}
                onChange={(e) => updateMonth(e.target.value, currentMonth.month)}
                className="calendar-select"
                disableUnderline
                MenuProps={{ PaperProps: { className: "calendar-select-menu" } }}
              >
                {YEARS.map((y) => (
                  <MenuItem key={y} value={y}>{y}</MenuItem>
                ))}
              </Select>
            </Box>
          </Box>

          {dataSource === 'rss' && (
            <Box className="rss-notice">
              <span className="rss-notice-icon">⚠</span>
              RSS sync — showing your last ~50 films only.{' '}
              <span className="rss-notice-link" onClick={handleGoToUpload}>
                Upload a CSV
              </span>{' '}
              for your full history.
            </Box>
          )}

          <div className="calendar-grid-wrapper">
            <div className="calendar-grid">
              {DAY_LABELS.map((label) => (
                <div key={label} className="calendar-day-header">{label}</div>
              ))}
              {cells.map((day, i) => {
                if (!day) {
                  return <div key={`empty-${i}`} className="calendar-cell calendar-cell--empty" />;
                }

                const { year, month } = currentMonth;
                const dateStr = `${year}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
                const isFuture = isFutureMonth || (isCurrentMonth && day > today.getDate());
                const isToday = isCurrentMonth && day === today.getDate();
                const movies = isFuture ? [] : (moviesByDate[dateStr] || []);
                const movie = movies[0];

                const movieId = movie ? `${movie.Name}-${movie.Year}` : null;
                const selection = movieId ? posterSelections[movieId]?.[0] : null;
                const posterSrc = selection
                  ? `https://image.tmdb.org/t/p/w200${selection.posterId}`
                  : movie?.Poster
                  ? `https://image.tmdb.org/t/p/w200${movie.Poster}`
                  : null;

                return (
                  <div
                    key={dateStr}
                    className={[
                      "calendar-cell",
                      isFuture ? "calendar-cell--future" : "",
                      isToday ? "calendar-cell--today" : "",
                      !loading && movie ? "calendar-cell--has-movie" : "",
                      selection ? "calendar-cell--selected" : "",
                    ].filter(Boolean).join(" ")}
                    onClick={(e) => !loading && movies.length > 0 && handleCellClick(e, movies)}
                  >
                    <span className="calendar-day-number">{day}</span>
                    {loading && !isFuture && (
                      <div className="calendar-poster-wrapper">
                        <div className="calendar-cell-skeleton" />
                      </div>
                    )}
                    {!loading && movie && posterSrc && (
                      <div className="calendar-poster-wrapper">
                        <img
                          src={posterSrc}
                          alt={movie.Name}
                          className="calendar-poster"
                        />
                        <div className="calendar-poster-overlay">
                          <span className="calendar-movie-title">{movie.Name}</span>
                          <span className="calendar-movie-year">{movie.Year}</span>
                        </div>
                        {selection && (
                          <span className="calendar-selected-badge">
                            <CheckIcon style={{ fontSize: 12 }} />
                          </span>
                        )}
                        {movies.length > 1 && (
                          <span className="calendar-more-badge">+{movies.length - 1}</span>
                        )}
                      </div>
                    )}
                  </div>
                );
              })}
            </div>

            {!loading && !hasAnyMovie && !isFutureMonth && (
              <Box className="no-movies-container">
                <div className="gif-container">
                  <div className="circle-background"></div>
                  <img src={pulpGif} alt="No movies" className="reaction-gif" />
                </div>
                <Typography variant="body1" gutterBottom>
                  No movies watched this month.
                </Typography>
                <Button variant="contained" className="back-button" onClick={() => navigate("/")}>
                  Go Back
                </Button>
              </Box>
            )}
          </div>
        </Paper>
      </Container>

      <Popover
        open={Boolean(popoverAnchor)}
        anchorEl={popoverAnchor}
        onClose={() => setPopoverAnchor(null)}
        anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
        transformOrigin={{ vertical: "top", horizontal: "center" }}
        PaperProps={{ className: "multi-movie-popover" }}
      >
        {popoverMovies.map((movie) => {
          const movieId = `${movie.Name}-${movie.Year}`;
          const selection = posterSelections[movieId]?.[0];
          const posterSrc = selection
            ? `https://image.tmdb.org/t/p/w200${selection.posterId}`
            : movie.Poster
            ? `https://image.tmdb.org/t/p/w200${movie.Poster}`
            : null;
          return (
            <div
              key={movieId}
              className="multi-movie-item"
              onClick={() => { handleMovieClick(movie); setPopoverAnchor(null); }}
            >
              {posterSrc ? (
                <img src={posterSrc} alt={movie.Name} className="multi-movie-poster" />
              ) : (
                <div className="multi-movie-poster multi-movie-poster--empty" />
              )}
              <div className="multi-movie-info">
                <span className="multi-movie-title">{movie.Name}</span>
                <span className="multi-movie-year">{movie.Year}</span>
              </div>
              {selection && <CheckIcon className="multi-movie-check" style={{ fontSize: 16 }} />}
            </div>
          );
        })}
      </Popover>
    </>
  );
};

export default PosterSelector;
