import React, { useEffect, useRef } from "react";
import { useQuery } from "@apollo/react-hooks";
import { gql } from "apollo-boost";
import { GQLMessage } from "./gql-types";

function perDay(messages: GQLMessage[]) {
  const days = messages.reduce((acc, msg) => {
    const [day] = msg.time.split("T");
    if (!(day in acc)) {
      acc[day] = [];
    }
    acc[day].push(msg);
    return acc;
  }, {});
  return Object.entries(days).sort(([a], [b]) => {
    if (a > b) {
      return 1;
    }
    return -1;
  });
}

function formatTime(time: string): string {
  const t = new Date(time);
  return [t.getHours(), t.getMinutes(), t.getSeconds()]
    .map(x => `0${x}`.slice(-2))
    .join(":");
}

function colorname(name: string): string {
  const n = name
    .split("")
    .map(x => x.charCodeAt(0))
    .reduce((a, b) => a + b, 0);
  return `hsl(${n % 360}, 60%, 50%)`;
}

export default function Chatroom() {
  const {
    loading: localLoading,
    error: localError,
    data: localData
  } = useQuery(gql`
    {
      currentChat {
        workspace
        channel
      }
    }
  `);
  const variables = {
    workspace: localData.currentChat?.workspace || "",
    channel: localData.currentChat?.channel || ""
  };
  const {
    loading: remoteLoading,
    error: remoteError,
    data: remoteData
  } = useQuery(
    gql`
      query Messages($workspace: String!, $channel: String!) {
        messages(
          workspace: $workspace
          order: DATE_ASC
          filter: { channel: $channel }
        ) {
          messages {
            content
            username
            userRealname
            time
            messageId
          }
        }
      }
    `,
    {
      variables
    }
  );

  const lastMessage = useRef(null);
  useEffect(() => {
    lastMessage.current?.scrollIntoView();
  });

  if (localLoading || remoteLoading) {
    return <div>Loading</div>;
  }
  if (localData.currentChat == null) {
    return <div>Select a channel from the left menu</div>;
  }

  if (localError) {
    return <div>{localError.message}</div>;
  }
  if (remoteError) {
    return <div>{remoteError.message}</div>;
  }

  return (
    <div>
      <ul className="chatlog">
        {perDay(remoteData.messages.messages).map(([day, messages]) => (
          <li>
            <div className="day">{day}</div>
            <ul>
              {messages.map((msg: GQLMessage) => (
                <li key={msg.messageId}>
                  <article className="message">
                    <header>
                      <div className="time" title={msg.time}>
                        {formatTime(msg.time)}
                      </div>
                      <div
                        className="realname"
                        style={{ color: colorname(msg.username) }}
                      >
                        {msg.userRealname}
                      </div>
                      <div className="username">{msg.username}</div>
                    </header>
                    <p>{msg.content}</p>
                  </article>
                </li>
              ))}
            </ul>
          </li>
        ))}
      </ul>
      <div ref={lastMessage}></div>
    </div>
  );
}
