import React, { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { useNavigate, useMatch } from "react-router-dom";
import { createSelector } from "reselect";
import { AppBar, Toolbar, Typography, Button, IconButton, LinearProgress, Box, Tooltip, Link, Menu, MenuItem } from "@material-ui/core";
import { Snackbar, Alert } from "@mui/material";
import GetAppIcon from "@material-ui/icons/GetApp";
import ExitToAppIcon from "@material-ui/icons/ExitToApp";
import ViewModuleIcon from "@material-ui/icons/ViewModule";
import SyncIcon from "@material-ui/icons/Sync";
import MoreVertIcon from "@material-ui/icons/MoreVert";
import JSZip from "jszip";
import api from "../services/api";
import { removeAllPosters } from "../services/action";

const selectSelectedPosters = createSelector(
  (state) => state.posterSelections,
  (posterSelections) =>
    Object.entries(posterSelections).flatMap(([movieId, posters]) =>
      (posters || []).map((p) => ({ movieId, posterId: p.posterId, watchedDate: p.watchedDate }))
    )
);

const Header = () => {
  const navigate = useNavigate();
  const dispatch = useDispatch();
  const galleryMatch = useMatch("/posters/:movieName/:movieYear");
  const movieName = galleryMatch ? decodeURIComponent(galleryMatch.params.movieName) : null;

  const [downloadState, setDownloadState] = useState(null); // null | { current, total }
  const [syncState, setSyncState] = useState(null); // null | 'syncing' | { added: number }
  const [menuAnchor, setMenuAnchor] = useState(null);
  const [snackbar, setSnackbar] = useState(null); // null | { message, severity }

  const selectedPosters = useSelector(selectSelectedPosters);
  const username = useSelector((state) => state.username);

  const count = selectedPosters.length;

  const handleDownload = async () => {
    if (downloadState) return;
    const total = selectedPosters.length;
    setDownloadState({ current: 0, total });

    try {
      const zip = new JSZip();

      for (let i = 0; i < selectedPosters.length; i++) {
        const { movieId, posterId, watchedDate } = selectedPosters[i];
        const url = `https://image.tmdb.org/t/p/original${posterId}`;
        const res = await fetch(url);
        const blob = await res.blob();
        zip.file(`${watchedDate}_${movieId}.jpg`, blob);
        setDownloadState({ current: i + 1, total });
      }

      const content = await zip.generateAsync({ type: "blob" });
      const objectUrl = URL.createObjectURL(content);
      const link = document.createElement("a");
      link.href = objectUrl;
      link.download = "posters.zip";
      document.body.appendChild(link);
      link.click();
      link.remove();
      URL.revokeObjectURL(objectUrl);
    } catch (err) {
      console.error("Download error:", err);
    } finally {
      setDownloadState(null);
    }
  };

  const handleRssSync = async () => {
    if (!username || syncState === 'syncing') return;
    setSyncState('syncing');
    try {
      const res = await api.post("/api/sync-rss", { username });
      setSyncState({ added: res.data.added });
      setTimeout(() => setSyncState(null), 3000);
      if (res.data.added > 0) {
        setSnackbar({ message: `${res.data.added} new film${res.data.added > 1 ? 's' : ''} added to your diary`, severity: 'success' });
        window.dispatchEvent(new Event('diary-synced'));
      } else {
        setSnackbar({ message: 'Already up to date', severity: 'info' });
      }
    } catch {
      setSyncState(null);
      setSnackbar({ message: 'Sync failed. Please try again.', severity: 'error' });
    }
  };

  const handleReset = async () => {
    try {
      await api.delete("/api/delete-csv");
      dispatch(removeAllPosters());
      navigate("/");
    } catch (err) {
      console.error("Reset error:", err);
    }
  };

  const isDownloading = !!downloadState;
  const progress = isDownloading
    ? Math.round((downloadState.current / downloadState.total) * 100)
    : 0;

  return (
    <>
    <Snackbar
      open={!!snackbar}
      autoHideDuration={4000}
      onClose={() => setSnackbar(null)}
      anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
    >
      <Alert onClose={() => setSnackbar(null)} severity={snackbar?.severity} sx={{ width: '100%' }}>
        {snackbar?.message}
      </Alert>
    </Snackbar>
    <AppBar position="fixed" className="app-header">
      <Toolbar className="header-toolbar">
        <div className="header-left" onClick={() => navigate("/PosterSelector")}>
          <img src="/icon.svg" alt="logo" className="header-logo" />
          <Typography variant="h6" className="header-title">
            Poster Picker
          </Typography>
        </div>

        <div className="header-center">
          {movieName ? (
            <Typography variant="h6" className="header-movie-name">
              {movieName}
            </Typography>
          ) : username ? (
            <Link
                href={`https://letterboxd.com/${username}`}
                target="_blank"
                rel="noopener noreferrer"
                className="header-username"
                onMouseEnter={(e) => (e.currentTarget.style.opacity = 1)}
                onMouseLeave={(e) => (e.currentTarget.style.opacity = 0.7)}
              >
                {username}
            </Link>
          ) : null}
        </div>
        {/* Desktop actions */}
        <div className="header-actions">
          {username && (
            <Tooltip title={
              syncState === 'syncing' ? 'Syncing…'
              : syncState?.added === 0 ? 'Already up to date'
              : syncState?.added > 0 ? `+${syncState.added} new film${syncState.added > 1 ? 's' : ''}`
              : `Sync from ${username}'s RSS`
            }>
              <span>
                <IconButton
                  className={`header-sync-btn${syncState ? ' header-sync-btn--active' : ''}`}
                  onClick={handleRssSync}
                  disabled={isDownloading || syncState === 'syncing'}
                >
                  <SyncIcon className={syncState === 'syncing' ? 'spin' : ''} />
                </IconButton>
              </span>
            </Tooltip>
          )}
          <Tooltip title="Reset diary">
            <span>
              <IconButton className="header-reset-btn" onClick={handleReset} disabled={isDownloading}>
                <ExitToAppIcon />
              </IconButton>
            </span>
          </Tooltip>
          {count > 0 && (
            <IconButton className="header-recap-btn" onClick={() => navigate("/recap")} disabled={isDownloading}>
              <ViewModuleIcon />
            </IconButton>
          )}
          {count > 0 && (
            <Button
              className={`header-download-btn${isDownloading ? " header-download-btn--loading" : ""}`}
              startIcon={!isDownloading && <GetAppIcon />}
              onClick={handleDownload}
              disabled={isDownloading}
            >
              {isDownloading ? (
                <Box className="header-download-progress">
                  <span>{downloadState.current} / {downloadState.total}</span>
                  <LinearProgress variant="determinate" value={progress} className="header-progress-bar" />
                </Box>
              ) : (
                `Download (${count})`
              )}
            </Button>
          )}
        </div>

        {/* Mobile actions — collapsed into a menu */}
        <IconButton className="header-menu-btn" onClick={(e) => setMenuAnchor(e.currentTarget)}>
          <MoreVertIcon />
        </IconButton>
        <Menu
          anchorEl={menuAnchor}
          open={Boolean(menuAnchor)}
          onClose={() => setMenuAnchor(null)}
          PaperProps={{ className: "header-menu-paper" }}
          getContentAnchorEl={null}
          anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
          transformOrigin={{ vertical: 'top', horizontal: 'right' }}
        >
          {username && (
            <MenuItem
              onClick={() => { handleRssSync(); setMenuAnchor(null); }}
              disabled={isDownloading || syncState === 'syncing'}
              className="header-menu-item"
            >
              <SyncIcon fontSize="small" className={`header-menu-icon${syncState === 'syncing' ? ' spin' : ''}`} />
              {syncState === 'syncing' ? 'Syncing…'
                : syncState?.added === 0 ? 'Up to date'
                : syncState?.added > 0 ? `+${syncState.added} new film${syncState.added > 1 ? 's' : ''}`
                : 'Sync RSS'}
            </MenuItem>
          )}
          {count > 0 && (
            <MenuItem onClick={() => { navigate('/recap'); setMenuAnchor(null); }} className="header-menu-item">
              <ViewModuleIcon fontSize="small" className="header-menu-icon" />
              My selections ({count})
            </MenuItem>
          )}
          {count > 0 && (
            <MenuItem
              onClick={() => { handleDownload(); setMenuAnchor(null); }}
              disabled={isDownloading}
              className="header-menu-item"
            >
              <GetAppIcon fontSize="small" className="header-menu-icon" />
              {isDownloading
                ? `Downloading… ${downloadState.current}/${downloadState.total}`
                : `Download (${count})`}
            </MenuItem>
          )}
          <MenuItem onClick={() => { handleReset(); setMenuAnchor(null); }} className="header-menu-item header-menu-item--danger">
            <ExitToAppIcon fontSize="small" className="header-menu-icon" />
            Reset diary
          </MenuItem>
        </Menu>
      </Toolbar>
    </AppBar>
    </>
  );
};

export default Header;
