import React, { useEffect } from "react";
import { useInView } from "react-intersection-observer";
import classNames from "classnames";
import { format, isToday } from "date-fns";

import Chip from "components/Chip";
import { DropdownMenu, DropdownMenuItem } from "components/dropdown-menu";
import PostScore from "components/posts/PostScore";
import Thumbs from "components/Thumbs";

const Post = ({
  className,
  datetime,
  author,
  type,
  ranking,
  content,
  modified,
  seen,
  archived,
  state,
  dimIfArchived = true,
  currentUser,
  supportThreshold,
  canThumb,
  reportSeen = true,
  onLike,
  onDislike,
  onHide,
  onBanUser,
  onUnbanUser,
  onInviteUser,
  onAnnounceProcedureProposal,
  onAcceptProcedureProposal,
  onRejectProcedureProposal,
  onRejectProcedureProposalByChairman,
  onEdit,
  onArchive,
  onSeen,
  ...props
}) => {
  const { ref, inView } = useInView({
    threshold: 0.8,
    trackVisibility: true,
    delay: 1000,
    skip: !reportSeen,
    triggerOnce: true,
  });

  useEffect(() => {
    if (inView && onSeen) {
      onSeen();
    }
  }, [inView, onSeen]);

  const wrapperClassName = classNames(
    "flex items-start p-4 lg:p-2 lg:py-3 lg:-mx-2 transition duration-500",
    {
      "bg-yellow-100 bg-opacity-50": !seen,
      "opacity-25 hover:opacity-100": dimIfArchived && !!archived,
    },
    className
  );

  const labels = [];

  if (type === "post") {
    labels.push(
      <Chip
        key="type__post"
        condensed
        color="grey-125"
        className="text-grey-300"
      >
        Příspěvek
      </Chip>
    );
  }

  if (type === "procedure-proposal") {
    labels.push(
      <Chip key="type__procedure-proposal" condensed color="cyan-200">
        Návrh postupu
      </Chip>
    );

    labels.push(
      {
        pending: (
          <Chip
            key="state__pending"
            condensed
            color="grey-500"
            aria-label="Návrh čekající na zpracování"
          >
            Čeká na zpracování
          </Chip>
        ),
        announced: (
          <Chip
            key="state__announced"
            condensed
            color="blue-300"
            aria-label="Návrh k hlasování"
          >
            K hlasování
          </Chip>
        ),
        accepted: (
          <Chip
            key="state__accepted"
            condensed
            color="green-400"
            aria-label="Schválený návrh"
          >
            Schválený
          </Chip>
        ),
        rejected: (
          <Chip
            key="state__rejected"
            condensed
            color="red-600"
            aria-label="Zamítnutý návrh"
          >
            Zamítnutý
          </Chip>
        ),
        "rejected-by-chairman": (
          <Chip
            key="state__rejected-by-chairmen"
            condensed
            color="red-600"
            aria-label="Návrh zamítnutý předsedajícím"
          >
            Zamítnutý předs.
          </Chip>
        ),
      }[state]
    );
  }

  if (archived) {
    labels.push(
      <Chip
        key="isArchived"
        condensed
        color="grey-125"
        className="text-grey-300"
      >
        Archivovaný
      </Chip>
    );
  }

  const isChairman = currentUser && currentUser.role === "chairman";

  const showAnnounceAction =
    isChairman && type === "procedure-proposal" && state === "pending";
  const showAcceptAction =
    isChairman && type === "procedure-proposal" && state === "announced";
  const showRejectAction =
    isChairman && type === "procedure-proposal" && state === "announced";
  const showRejectByChairmanAction =
    isChairman &&
    type === "procedure-proposal" &&
    ["announced", "pending"].includes(state);
  const showEditAction =
    isChairman ||
    (currentUser && currentUser.id === author.id && !currentUser.isBanned);
  const showBanAction = isChairman && !author.isBanned;
  const showUnbanAction = isChairman && author.isBanned;
  const showInviteAction = isChairman;
  const showHideAction = isChairman && !archived;
  const showArchiveAction = isChairman && !archived;

  // Show actions dropdown if any of actions is available.
  const showActions = [
    showAnnounceAction,
    showAcceptAction,
    showRejectAction,
    showRejectByChairmanAction,
    showEditAction,
    showBanAction,
    showUnbanAction,
    showInviteAction,
    showHideAction,
    showArchiveAction,
  ].some((item) => !!item);

  const htmlContent = {
    __html: content,
  };

  const thumbsVisible = !archived && (type === "post" || state === "announced");

  return (
    <div className={wrapperClassName} ref={ref} {...props}>
      <img
        src={`https://a.pirati.cz/piratar/200/${author.username}.jpg`}
        className="w-8 h-8 lg:w-14 lg:h-14 mr-3 rounded object-cover"
        alt={author.name}
      />
      <div className="flex-1 overflow-hidden">
        <div className="mb-1">
          <div className="flex justify-between items-start xl:items-center">
            <div className="flex flex-col xl:flex-row xl:items-center">
              <div className="flex flex-col xl:flex-row xl:items-center">
                <span className="font-bold">{author.name}</span>
                <div className="mt-1 xl:mt-0 xl:ml-2 leading-tight">
                  <span className="text-grey-200 text-xs sm:text-sm">
                    {author.group}
                  </span>
                  <span className="text-grey-200 ml-1 text-xs sm:text-sm">
                    @{" "}
                    {format(
                      datetime,
                      isToday(datetime) ? "H:mm" : "dd. MM. H:mm"
                    )}
                    {modified && (
                      <span className="text-grey-200 text-xs block md:inline md:ml-2">
                        (upraveno)
                      </span>
                    )}
                  </span>
                </div>
              </div>
              <div className="hidden lg:flex flex-row flex-wrap lg:flex-no-wrap lg:items-center mt-1 xl:mt-0 xl:ml-2 space-x-2">
                {labels}
              </div>
            </div>
            <div className="flex items-center">
              {thumbsVisible && (
                <Thumbs
                  likes={ranking.likes}
                  dislikes={ranking.dislikes}
                  readOnly={!canThumb}
                  onLike={onLike}
                  onDislike={onDislike}
                  myVote={ranking.myVote}
                />
              )}
              <PostScore
                className="ml-2"
                postType={type}
                ranking={ranking}
                rankingReadonly={!thumbsVisible}
                supportThreshold={supportThreshold}
              />
              {showActions && (
                <DropdownMenu right className="pl-4 static">
                  {showAnnounceAction && (
                    <DropdownMenuItem
                      onClick={onAnnounceProcedureProposal}
                      icon="ico--bullhorn"
                      title="Vyhlásit procedurální návrh"
                    />
                  )}
                  {showAcceptAction && (
                    <DropdownMenuItem
                      onClick={onAcceptProcedureProposal}
                      icon="ico--thumbs-up"
                      title="Schválit procedurální návrh"
                    />
                  )}
                  {showRejectAction && (
                    <DropdownMenuItem
                      onClick={onRejectProcedureProposal}
                      icon="ico--thumbs-down"
                      title="Zamítnout procedurální návrh"
                    />
                  )}
                  {showRejectByChairmanAction && (
                    <DropdownMenuItem
                      onClick={onRejectProcedureProposalByChairman}
                      icon="ico--thumbs-down"
                      title="Zamítnout procedurální návrh předsedajícím"
                    />
                  )}
                  {showEditAction && (
                    <DropdownMenuItem
                      onClick={onEdit}
                      icon="ico--pencil"
                      title="Upravit příspěvek"
                    />
                  )}
                  {showBanAction && (
                    <DropdownMenuItem
                      onClick={onBanUser}
                      icon="ico--lock"
                      title="Zablokovat uživatele"
                    />
                  )}
                  {showUnbanAction && (
                    <DropdownMenuItem
                      onClick={onUnbanUser}
                      icon="ico--lock-open"
                      title="Odblokovat uživatele"
                    />
                  )}
                  {showInviteAction && (
                    <DropdownMenuItem
                      onClick={onInviteUser}
                      icon="ico--phone"
                      title="Pozvat uživatele do Jitsi"
                    />
                  )}
                  {showHideAction && (
                    <DropdownMenuItem
                      onClick={onHide}
                      icon="ico--eye-off"
                      title="Skrýt příspěvek"
                    />
                  )}
                  {showArchiveAction && (
                    <DropdownMenuItem
                      onClick={onArchive}
                      icon="ico--drawer"
                      title="Archivovat příspěvek"
                    />
                  )}
                </DropdownMenu>
              )}
            </div>
          </div>
        </div>
        <div className="flex lg:hidden flex-row flex-wrap my-2 space-x-2">
          {labels}
        </div>
        <div
          className="text-sm lg:text-base text-black leading-normal content-block overflow-x-auto overflow-y-hidden mt-1"
          dangerouslySetInnerHTML={htmlContent}
        ></div>
      </div>
    </div>
  );
};

export default React.memo(Post);