import React, { useCallback, useMemo, useState } from "react";
import classNames from "classnames";

import Post from "./Post";

const PostList = ({
  className,
  items,
  showAddPostCta,
  currentUser,
  supportThreshold,
  canThumb,
  dimArchived,
  onLike,
  onDislike,
  onHide,
  onBanUser,
  onUnbanUser,
  onInviteUser,
  onAnnounceProcedureProposal,
  onAcceptProcedureProposal,
  onRejectProcedureProposal,
  onRejectProcedureProposalByChairman,
  onEdit,
  onArchive,
  onSeen,
}) => {
  const buildHandler = (responderFn) => (post) => (evt) => {
    evt.preventDefault();
    responderFn(post);
  };

  const windowSize = 20;
  const [window, setWindow] = useState(windowSize);

  const onPostLike = buildHandler(onLike);
  const onPostDislike = buildHandler(onDislike);
  const onPostEdit = buildHandler(onEdit);
  const onPostHide = buildHandler(onHide);
  const onPostBanUser = buildHandler(onBanUser);
  const onPostUnbanUser = buildHandler(onUnbanUser);
  const onPostInviteUser = buildHandler(onInviteUser);
  const onPostArchive = buildHandler(onArchive);
  const onPostAnnounceProcedureProposal = buildHandler(
    onAnnounceProcedureProposal
  );
  const onPostAcceptProcedureProposal = buildHandler(onAcceptProcedureProposal);
  const onPostRejectProcedureProposal = buildHandler(onRejectProcedureProposal);
  const onPostRejectProcedureProposalByChairman = buildHandler(
    onRejectProcedureProposalByChairman
  );

  const onPostSeen = useCallback(
    (post) => () => {
      if (!post.seen) {
        onSeen(post);
      }

      // Once last post in window is reached, attempt show more.
      if (items.indexOf(post) === window - 1) {
        setWindow(window + windowSize);
      }
    },
    [items, onSeen, window]
  );

  const windowItems = useMemo(() => {
    return items.slice(0, window).filter((item) => !item.hidden);
  }, [items, window]);

  return (
    <div className={classNames("space-y-px", className)}>
      {windowItems.map((item, idx) => (
        <Post
          key={item.id}
          datetime={item.datetime}
          author={item.author}
          type={item.type}
          state={item.state}
          content={item.contentHtml}
          ranking={item.ranking}
          modified={item.modified}
          seen={item.seen}
          reportSeen={!item.seen || idx === window - 1}
          archived={item.archived}
          dimIfArchived={dimArchived}
          currentUser={currentUser}
          supportThreshold={supportThreshold}
          canThumb={canThumb}
          onLike={onPostLike(item)}
          onDislike={onPostDislike(item)}
          onHide={onPostHide(item)}
          onBanUser={onPostBanUser(item)}
          onUnbanUser={onPostUnbanUser(item)}
          onInviteUser={onPostInviteUser(item)}
          onAnnounceProcedureProposal={onPostAnnounceProcedureProposal(item)}
          onAcceptProcedureProposal={onPostAcceptProcedureProposal(item)}
          onRejectProcedureProposal={onPostRejectProcedureProposal(item)}
          onRejectProcedureProposalByChairman={onPostRejectProcedureProposalByChairman(
            item
          )}
          onEdit={onPostEdit(item)}
          onArchive={onPostArchive(item)}
          onSeen={onPostSeen(item)}
        />
      ))}
      {showAddPostCta && !items.length && (
        <p className="p-4 lg:p-0 lg:py-3 leading-snug text-sm md:text-base">
          Nikdo zatím žádný odpovídající příspěvek do rozpravy nepřidal. Budeš
          první?
        </p>
      )}
    </div>
  );
};

export default PostList;