import styled from "@emotion/styled";
import { inject, observer } from "mobx-react";
import moment from "moment";
import React, { useCallback, useRef, useState } from "react";
import { v4 } from "uuid";
import {
  LIGHT_PRIMARY_THREE,
  LIGHT_PRIMARY_TWO,
  LIGHT_SECONDARY_FOUR,
  LIGHT_SHADOW,
  LIGHT_TERTIARY_THREE,
} from "../../../shared/colors";
import { CommentThreadItem, SlideComment } from "../../../shared/types";
import { generateRandomColor } from "../../../shared/utils/utils";
import { CurrentUser_me } from "../../graphql/generated/types";
import { SocketActions, StoreProps } from "../../platform/SlideshowStore";
import withPlatform, { PlatformProps } from "../../platform/withPlatform";
import { Button } from "../shared/StyledComponents";
import { canvasStyleDictionary } from "./canvasStyle";

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

const a = canvasStyleDictionary;

function SlideObjectComment(props: Props) {
  const newCommentRef = useRef<HTMLInputElement>(null);
  const [showCommentThread, setShowCommentThread] = useState<boolean>(false);
  const [newComment, setNewComment] = useState<string>("");

  const submitComment = useCallback(() => {
    const id = v4();
    const newThreadAddition: CommentThreadItem = {
      id,
      userId: props.user.id,
      text: newComment,
      createdAt: Date.now(),
    };

    props.store.emit(SocketActions.UPDATE_SLIDE_OBJECT, {
      id: props.slideComment.id,
      slideId: props.store.currentSlide.get()!,
      data: {
        ...props.slideComment,
        thread: [...props.slideComment.thread, newThreadAddition],
      },
    });
  }, [newComment]);

  return (
    <>
      <CommentBubble
        style={{
          position: "absolute",
          top: props.slideComment.y,
          left: props.slideComment.x,
        }}
        onClick={(e) => {
          if (
            props.store.selectedSlideElement.get() === props.slideComment.id
          ) {
            setShowCommentThread(!showCommentThread);
          }
          props.store.setSelectedSlideElement(props.slideComment.id);
          e.stopPropagation();
        }}
      >
        {props.slideComment.thread.length}
      </CommentBubble>
      {showCommentThread && (
        <CommentThread
          style={{
            position: "absolute",
            top: props.slideComment.y + 64,
            left: props.slideComment.x,
          }}
        >
          {props.slideComment.thread
            .reduce((accumulator, threadItem) => {
              return [
                ...accumulator,
                {
                  ...threadItem,
                  differentUser:
                    !accumulator.length ||
                    accumulator[accumulator.length - 1].userId !==
                      threadItem.userId,
                },
              ];
            }, [] as any[])
            .map((threadItem) => (
              <ThreadItem key={threadItem.id}>
                {threadItem.differentUser && (
                  <DetailRow>
                    <ProfilePicture
                      color={generateRandomColor(threadItem.userId)}
                    />
                    <Name>
                      {props.user.team.users.find(
                        (user) => user.id === threadItem.userId
                      )?.name || "Unknown"}
                    </Name>
                    <Time>{moment(threadItem.createdAt).fromNow()}</Time>
                  </DetailRow>
                )}
                <ThreadItemText>{threadItem.text}</ThreadItemText>
              </ThreadItem>
            ))}
          <AddCommentRow>
            <ProfilePicture color={generateRandomColor(props.user.id)} />
            <Input
              ref={newCommentRef}
              placeholder="Add a comment..."
              value={newComment}
              onChange={(e) => setNewComment(e.target.value)}
              autoFocus
              onKeyPress={(e) => {
                console.log("key");
                console.log(e);
                if (e.key === "Enter") {
                  submitComment();
                  setNewComment("");
                  newCommentRef.current?.focus();
                } else if (e.key === "Escape") {
                  console.log(":esc");
                  setShowCommentThread(false);
                }
              }}
            />
            <Button
              style={{ marginLeft: "auto", marginRight: 8 }}
              onClick={(e) => {
                submitComment();
                setNewComment("");
                newCommentRef.current?.focus();
              }}
            >
              Send
            </Button>
          </AddCommentRow>
        </CommentThread>
      )}
    </>
  );
}

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

const CommentBubble = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  height: 48px;
  width: 48px;
  border-radius: 24px;
  background-color: ${LIGHT_TERTIARY_THREE};
  box-shadow: 0px 2px 5px 0px ${LIGHT_SECONDARY_FOUR};
  cursor: default;
`;

const DetailRow = styled.div`
  display: flex;
  margin-bottom: 8px;
  align-items: center;
`;

const Name = styled.div`
  font-size: 12px;
  font-weight: bold;
`;

const Time = styled.div`
  margin-left: 4px;
  font-size: 12px;
  color: ${LIGHT_SECONDARY_FOUR};
`;

const AddCommentRow = styled.div`
  display: flex;
  width: 470px;
  max-width: 470px;
  padding: 8px 10px;
  border-top: 1px solid ${LIGHT_PRIMARY_TWO};
  :first-of-type {
    border-top: none;
    border-top-right-radius: 8px;
    border-top-left-radius: 8px;
  }
  border-bottom-right-radius: 8px;
  border-bottom-left-radius: 8px;
`;

const ThreadItem = styled.div`
  display: flex;
  flex-direction: column;
  width: 470px;
  max-width: 470px;
  padding: 8px 10px;
`;

const ThreadItemText = styled.div`
  margin-left: 32px;
`;

const CommentThread = styled.div`
  display: flex;
  flex-direction: column;
  background-color: ${LIGHT_PRIMARY_THREE};
  box-shadow: 0px 1px 5px 0px ${LIGHT_SHADOW};
  border-radius: 8px;
`;

// TODO: Just a placeholder
const ProfilePicture = styled.div<{ color: string }>`
  display: flex;
  height: 24px;
  width: 24px;
  border-radius: 12px;
  background-color: ${(props) => props.color};
  margin-right: 8px;
`;

const Input = styled.input`
  appearance: none;
  background: none;
  :focus {
    outline: none;
  }
  border: none;
  margin-right: 8px;
`;
