import styled from "@emotion/styled";
import { remote } from "electron";
import { inject, observer } from "mobx-react";
import React, { useEffect, useRef } from "react";
import { LIGHT_PRIMARY_TWO } from "../../shared/colors";
import { HAS_MOUSE } from "../../shared/types";
import { CurrentUser_me } from "../graphql/generated/types";
import { SocketActions, StoreProps } from "../platform/SlideshowStore";
import withPlatform, { PlatformProps } from "../platform/withPlatform";
import { useCommandLineContext } from "../providers/CommandLineProvider";
import { generateRandomColor } from "../utils";
import Canvas from "./canvas/Canvas";
import ChangelogModal from "./canvas/ChangelogModal";
import { deleteConnections } from "./canvas/windowListeners";
import SlideInfo from "./info/SlideInfo";
import ProfileTab from "./ProfileTab";
import SettingsModal from "./SettingsModal";
import SlideBoardModal from "./SlideBoardModal";
import SlideItemToggler from "./SlideItemToggler";

type Props = {
  user: CurrentUser_me;
} & PlatformProps &
  StoreProps;

function Slideshow(props: Props) {
  const { toggle, isVisible } = useCommandLineContext();

  useEffect(() => {
    props.manager.bind(
      "del",
      () => {
        const selectedElement = props.store.selectedSlideElement.get();
        const selectedSlides = props.store.selectedSlides;
        if (selectedElement) {
          deleteConnections(
            selectedElement,
            props.store.currentSlide.get()!,
            props.store
          );
          props.store.emit(SocketActions.DELETE_SLIDE_OBJECT, {
            slideId: props.store.currentSlide.get()!,
            id: selectedElement,
          });
        } else if (selectedSlides.length) {
          props.store.emit(SocketActions.DELETE_SLIDES, {});
        }
      },
      "Slideshow",
      "Delete currently selected element",
      1
    );
    props.manager.bind(
      "command+k",
      () => {
        toggle();
      },
      "Slideshow",
      "Open command bar",
      1
    );

    return () => {
      props.manager.unbind("del", "Slideshow");
      props.manager.unbind("command+k", "Slideshow");
    };
  });
  const slideshowRef = useRef<HTMLDivElement>(null);
  const subscriberList = Array.from(props.store.subscribers.keys())
    .filter((subscriber) => subscriber !== props.user.id)
    .map((subscriber) => (
      <Participant color={generateRandomColor(subscriber)} key={subscriber} />
    ));

  const setMouseClickEvent = (e: React.MouseEvent<HTMLDivElement>) => {
    if (!slideshowRef.current || !HAS_MOUSE) {
      return;
    }
    const container = slideshowRef.current.getBoundingClientRect();

    props.store.emit(SocketActions.MOUSE_CLICK, {
      x: e.clientX - container.left - 9,
      y: e.clientY - container.top - 12.75,
      userId: props.user.id,
      timestamp: Date.now(),
    });
    // TODO: emit here
    e.persist();
  };

  const presentStuff = () => {
    props.store.setIsPresenting(true);
  };

  return (
    <Container
      onClick={setMouseClickEvent}
      ref={slideshowRef}
      onMouseMove={(e) => {
        if (!slideshowRef.current || !HAS_MOUSE) {
          return;
        }

        const container = slideshowRef.current.getBoundingClientRect();

        props.store.emit(SocketActions.MOUSE_MOVEMENT, {
          x: e.clientX - container.left - 9,
          y: e.clientY - container.top - 12.75,
          userId: props.user.id,
        });
      }}
    >
      <WindowHeader
        onDoubleClick={() => {
          const currentWindow = remote.getCurrentWindow();
          currentWindow.maximize();
        }}
      />
      <Header>
        <Participants>{subscriberList}</Participants>
      </Header>
      <MainContent>
        <SlideContainer>
          <Canvas user={props.user} store={props.store} />
        </SlideContainer>
        <SlideItemToggler user={props.user} store={props.store} />
        <ProfileTab user={props.user} store={props.store} />
        <SlideInfo user={props.user} store={props.store} />
        {props.store.showBoardModal.get() && (
          <SlideBoardModal user={props.user} store={props.store} />
        )}
        {props.store.showSettingsModal.get() && (
          <SettingsModal user={props.user} store={props.store} />
        )}
        {props.store.showChangelogModal.get() && (
          <ChangelogModal user={props.user} store={props.store} />
        )}
      </MainContent>
    </Container>
  );
}

export default withPlatform(inject("store")(observer(Slideshow)));

const WindowHeader = styled.div`
  width: 100%;
  background: none;
  z-index: 99999;
  height: 20px;
  position: absolute;
  top: 0px;
  -webkit-app-region: drag;
`;

const PlayButtonContainer = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  margin-left: auto;
  margin-right: 20px;
`;

const SlideContainer = styled.div`
  display: flex;
  height: 100%;
  width: 100%;
  align-items: center;
  justify-content: center;
  background-color: ${LIGHT_PRIMARY_TWO};
`;

const MainContent = styled.div`
  display: flex;
  height: 100%;
  width: 100%;
`;

const Header = styled.div`
  position: absolute;
  top: 12px;
  right: 64px;
  display: flex;
  z-index: 2;
  justify-content: flex-end;
  background: none;
  align-items: center;
`;

const Container = styled.div`
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
`;

const Participants = styled.div`
  display: flex;
  justify-items: flex-end;
  margin-right: 24px;
`;

const Participant = styled.div<{ color: string }>`
  display: flex;
  height: 24px;
  width: 24px;
  border-radius: 12px;
  background-color: ${(props) => props.color};
  margin-right: 8px;
  :last-of-type {
    margin-right: 0px;
  }
`;
