import React, { useState, useRef, useEffect } from "react";
import {
  Container,
  Typography,
  Button,
  Card,
  CardContent,
  Grid,
  Box,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  CircularProgress
} from "@mui/material";
import AddIcon from "@mui/icons-material/Add";
import ThumbUpIcon from "@mui/icons-material/ThumbUp";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { OnlineCount } from "../components/VisitorCount";
import { Render } from "../components/render";
import NewStructure from '../components/NewStructure';


const isLiked = (id) => !!localStorage.getItem(`liked-${id}`);
const markLiked = (id) => localStorage.setItem(`liked-${id}`, "1");

const fetchStructures = async () => {
  const res = await fetch("/api/structures");
  if (!res.ok) throw new Error(await res.text());
  return res.json();
};

export default function Home() {
  const queryClient = useQueryClient();
  const [open, setOpen] = useState(false);
  const [selected, setSelected] = useState(null);
  const nextId = useRef(1);

  const renderRef = useRef(null);

  
  const {
    data: structures = [],
    isLoading,
    isError,
    error
  } = useQuery({ queryKey: ["structures"], queryFn: fetchStructures });

  // Use SSE to listen for likes updates /api/subscribe-likes
  const HEARTBEAT_TIMEOUT = 5000;
  useEffect(() => {
    let eventSource;

    let lastHeartbeat = Date.now();
    const onHeartbeat = () => {
      lastHeartbeat = Date.now();
    };

    const connect = () => {
      eventSource = new EventSource("/api/subscribe-likes");

      eventSource.onmessage = (event) => {
        const data = JSON.parse(event.data);
        if (data.structureId && data.likes !== undefined) {
          queryClient.setQueryData(["structures"], (old = []) =>
            old.map((s) =>
              s.id === data.structureId ? { ...s, likes: data.likes } : s
            )
          );
        }
      }

      eventSource.onerror = (error) => {
        console.error("SSE error:", error);
        eventSource.close();
      };

      eventSource.onopen = () => {
        console.log("SSE connection opened");
      };

      eventSource.onclose = () => {
        console.log("SSE connection closed");
      }
      
      eventSource.addEventListener("heartbeat", onHeartbeat);
    }

    connect();

    const heartbeatTimeout = setInterval(() => {
      if (Date.now() - lastHeartbeat > HEARTBEAT_TIMEOUT) {
        console.warn('SSE heartbeat timeout, reconnecting...');
        eventSource.close();
        connect();
      }
    }, HEARTBEAT_TIMEOUT);

    return () => {
      if (heartbeatTimeout) {
        clearInterval(heartbeatTimeout);
      }
      
      if (eventSource) {
        eventSource.removeEventListener("heartbeat", onHeartbeat);
        eventSource.close();
      }
    }
  }, []);

  const likeStructureMutation = useMutation({
    mutationFn: async (id) => {
      const res = await fetch(`/api/structures/${id}/like`, { method: "POST" });
      if (!res.ok) throw new Error(await res.text());
      return res.json();
    },
    onSuccess: (updated) => {
      markLiked(updated.id);
      queryClient.setQueryData(["structures"], (old = []) =>
        old.map((s) => (s.id === updated.id ? { ...updated, liked: true } : s))
      );
      setSelected((prev) => (prev && prev.id === updated.id ? { ...updated, liked: true } : prev));
    }
  });

  const handleCardClick = structure => {
    setSelected(structure);
    setOpen(true);
  };
  const handleClose = () => {
    setOpen(false);
    setSelected(null);
    const engine = renderRef.current?.getEngine();
    if (engine) {
      engine.stopRenderLoop();
    }
  };

  if (isLoading) {
    return (
      <Container sx={{ mt: 4, textAlign: "center" }}>
        <CircularProgress />
      </Container>
    );
  }

  if (isError) {
    return (
      <Container sx={{ mt: 4 }}>
        <Typography color="error">{error.message}</Typography>
      </Container>
    );
  }

  return (
    <Container maxWidth="md" sx={{ mt: 4 }}>
      {/* Intro */}
      <Card>
        <CardContent>
          <Typography variant="h5" gutterBottom>
            Welcome to MINEDRIVE
          </Typography>
          <Typography variant="body1" gutterBottom>
            Upload your WorldEdit shenanigans and give zero stars to your friends
          </Typography>
        </CardContent>
      </Card>

      {/* Online counter */}
      <Card sx={{ mt: 4, p: 2 }}>
        <Typography>
          Count of online users:&nbsp;<OnlineCount />
        </Typography>
      </Card>

      <NewStructure structures={structures}/>

      {/* Cards grid */}
      <Grid container spacing={2} sx={{ mt: 1 }}>
        {structures.map(s => (
          <Grid size={{xs: 12, sm: 6, md: 4,}} key={s.id}>
            <Card onClick={() => handleCardClick(s)} sx={{ cursor: 'pointer' }}>
              <CardContent>
                <Typography variant="h6">{s.name}</Typography>
                <Typography variant="body2" color="textSecondary">
                  ID: {s.id}
                </Typography>
                <Typography variant="body1" sx={{ mt: 1 }}>
                  Likes:&nbsp;<strong>{s.likes}</strong>
                </Typography>
              </CardContent>
            </Card>
          </Grid>
        ))}
      </Grid>

      <Dialog open={open} onClose={handleClose} fullWidth maxWidth="sm" slotProps={{
          paper: {
            sx: {
              m: 2,
              height: 'calc(100dvh - 32px)',
            }
          }
        }}>
        <DialogTitle sx={{display: "flex", justifyContent: "space-between"}}>
          <Box>{selected?.name}</Box>
          <Box><strong>Likes:</strong> {selected?.likes}</Box>
        </DialogTitle>
        <DialogContent dividers sx={{display: "flex", flexDirection: "column", height: "100%"}}>
          {selected && (
            <>
              <Typography variant="body1" sx={{height: "fit-content"}}>
                {selected.description}
              </Typography>
              <Box sx={{height: "90%"}} >
                <Render ref={renderRef} schemUrl={`/api/structures/${selected.id}/file`} />
              </Box>
              <Typography sx={{height: "fit-content"}}>
                <strong>ID:</strong> {selected.id}
              </Typography>
            </>
          )}
        </DialogContent>
        <DialogActions>
          <Button onClick={handleClose}>Close</Button>
          <Button
            startIcon={<ThumbUpIcon />}
            disabled={!selected || selected.liked || likeStructureMutation.isLoading || isLiked(selected.id)}
            onClick={() => selected && likeStructureMutation.mutate(selected.id)}
          >
            Like
          </Button>
        </DialogActions>
      </Dialog>
    </Container>
  );
}