import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { Helmet } from 'react-helmet-async';
import { Link, useNavigate} from 'react-router-dom';
import { confirmAlert } from 'react-confirm-alert';
import { Tooltip } from 'react-tooltip';
import { Virtuoso } from 'react-virtuoso';
import { useAccount, useFeed, usePublishCommentEdit, useSubplebbit, useSubplebbits } from '@plebbit/plebbit-react-hooks';
import { debounce } from 'lodash';
import { Container, NavBar, Header, Break, PostMenu, BoardForm } from '../styled/views/Board.styled';
import { Threads, PostPreview, PostMenuCatalog } from '../styled/views/Catalog.styled';
import { TopBar, Footer } from '../styled/views/Thread.styled';
import { AlertModal } from '../styled/modals/AlertModal.styled';
import CatalogLoader from '../CatalogLoader';
import EditModal from '../modals/EditModal';
import ImageBanner from '../ImageBanner';
import VerifiedAuthor from '../VerifiedAuthor';
import CreateBoardModal from '../modals/CreateBoardModal';
import ModerationModal from '../modals/ModerationModal';
import OfflineIndicator from '../OfflineIndicator';
import SettingsModal from '../modals/SettingsModal';
import countLinks from '../../utils/countLinks';
import getCommentMediaInfo from '../../utils/getCommentMediaInfo';
import getFormattedTime from '../../utils/getFormattedTime';
import handleShareClick from '../../utils/handleShareClick';
import handleStyleChange from '../../utils/handleStyleChange';
import useError from '../../hooks/useError';
import useFeedRows from '../../hooks/useFeedRows';
import useFeedStateString from '../../hooks/useFeedStateString';
import useSuccess from '../../hooks/useSuccess';
import useWindowWidth from '../../hooks/useWindowWidth';
import useGeneralStore from '../../hooks/stores/useGeneralStore';
import packageJson from '../../../package.json';
const {version} = packageJson;
let lastVirtuosoStates = {};
const commitRef = process?.env?.REACT_APP_COMMIT_REF ? ` ${process.env.REACT_APP_COMMIT_REF.slice(0, 7)}` : '';


const CatalogPost = ({post}) => {
  const {
    editedComment,
    setDeletePost,
    setIsAuthorDelete,
    captchaResponse, setCaptchaResponse,
    setIsModerationOpen,
    setChallengesArray,
    setIsAuthorEdit,
    setIsCaptchaOpen,
    setIsEditModalOpen,
    setModeratingCommentCid,
    setOriginalCommentContent,
    setPendingComment,
    setResolveCaptchaPromise,
    selectedAddress, setSelectedAddress,
    selectedStyle,
    setSelectedThread,
  } = useGeneralStore(state => state);

  const thread = post;
  const commentMediaInfo = getCommentMediaInfo(thread);
  const linkCount = countLinks(thread);
  const fallbackImgUrl = "assets/filedeleted-res.gif";
  const [isHoveringOnThread, setIsHoveringOnThread] = useState(false);
  const [menuPosition, setMenuPosition] = useState({top: 0, left: 0});
  const [popupPosition, setPopupPosition] = useState({top: 0, left: 0});
  const [openMenuCid, setOpenMenuCid] = useState(null);
  const [triggerPublishCommentEdit, setTriggerPublishCommentEdit] = useState(false);
  const [isImageSearchOpen, setIsImageSearchOpen] = useState(false);
  const [isClientRedirectMenuOpen, setIsClientRedirectMenuOpen] = useState(false);
  const [commentCid, setCommentCid] = useState(null);
  const [isModerator, setIsModerator] = useState(false);

  const [, setNewErrorMessage] = useError();
  const [, setNewSuccessMessage] = useSuccess();

  const account = useAccount();
  const subplebbit = useSubplebbit({subplebbitAddress: thread.subplebbitAddress});
  const threadMenuRefs = useRef({});
  const threadRefs = useRef({});
  const postMenuRef = useRef(null);
  const postMenuCatalogRef = useRef(null);
  const popupRef = useRef(null);
  const textRef = useRef(null);
  const imageRef = useRef(null);
  const [spaceOnRight, setSpaceOnRight] = useState(null);
  const [isCalculationDone,setIsCalculationDone] = useState(false);
  const [hoverTimeoutId, setHoverTimeoutId] = useState(null);
  const [isHoveringForMenu, setIsHoveringForMenu] = useState(false);
  const textRect = textRef.current?.getBoundingClientRect();
  const imageRect = imageRef.current?.getBoundingClientRect();
  const popupRect = popupRef.current?.getBoundingClientRect();
  const isMediaShowed = (thread.link && commentMediaInfo && (
    commentMediaInfo.type === 'image' || 
    commentMediaInfo.type === 'video' || 
    (commentMediaInfo.type === 'webpage' && 
    commentMediaInfo.thumbnail) ||
    (commentMediaInfo.type === 'iframe' &&
    commentMediaInfo.thumbnail))) ? true : false;


    const { left: textLeft, right: textRight, width: textWidth } = textRef.current?.getBoundingClientRect() || {};
    const { left: imageLeft, right: imageRight, width: imageWidth } = imageRef.current?.getBoundingClientRect() || {};
    
    useLayoutEffect(() => {
      const executeLayoutEffectLogic = () => {
        let ref;
    
        if (isMediaShowed) {
          ref = imageRef.current; 
        } else {
          ref = textRef.current;
        }
    
        if (ref && popupRef.current) {
          const rect = ref.getBoundingClientRect();
          const viewportWidth = document.documentElement.clientWidth;
          const spaceRight = viewportWidth - (rect.left + rect.width);
          const spaceLeft = rect.left;
    
          if (spaceRight < 200 && spaceLeft > spaceRight && spaceLeft < 500) {
            popupRef.current.style.maxWidth = `calc(
              100vw - 
              ${isMediaShowed ? imageWidth : textWidth}px
              - ${spaceRight + 40}px
              )`;
          } else if (spaceRight < 200 && spaceLeft < spaceRight) {
            popupRef.current.style.maxWidth = `calc(100vw - ${isMediaShowed ? imageWidth : textWidth}px)`;
          } else {
            popupRef.current.style.maxWidth = `500px`;
          }
    
          setSpaceOnRight(spaceRight);
          setIsCalculationDone(true);
        }
      };
    
      if (isHoveringOnThread) {
        const timeoutId = setTimeout(executeLayoutEffectLogic, 250);
        return () => {
          clearTimeout(timeoutId);
          setIsCalculationDone(false);
        };
      }
    
    }, [isHoveringOnThread, isMediaShowed, textLeft, textRight, imageLeft, imageRight, textWidth, imageWidth]);
    
  
  const handleMouseOnLeaveThread = () => {
    if (hoverTimeoutId) {
        clearTimeout(hoverTimeoutId);
        setHoverTimeoutId(null);
        setIsHoveringOnThread("")
    } else if (isHoveringOnThread !== "") {
        setIsHoveringOnThread("");
        setIsCalculationDone(false);
    }
  };


  useEffect(() => {
    if (subplebbit.roles !== undefined) { 
      const role = subplebbit.roles[account?.author.address]?.role;
  
      if (role === 'moderator' || role === 'admin' || role === 'owner') {
        setIsModerator(true);
      } else {
        setIsModerator(false);
      }
    }
  }, [account?.author.address, subplebbit.roles]);


  const handleOutsideClick = useCallback((e) => {
    if (openMenuCid !== null && !postMenuRef.current.contains(e.target) && !postMenuCatalogRef.current.contains(e.target)) {
      setOpenMenuCid(null);
    }
  }, [openMenuCid]);

  const handleOptionClick = () => {
    setOpenMenuCid(null);
  };

  useEffect(() => {
    if (openMenuCid !== null) {
      document.addEventListener('click', handleOutsideClick);
    } else {
      document.removeEventListener('click', handleOutsideClick);
    }
    
    return () => {
      document.removeEventListener('click', handleOutsideClick);
    };
  }, [openMenuCid, handleOutsideClick]);

  const handleAuthorDeleteClick = (comment) => {
    handleOptionClick(comment.cid);

    confirmAlert({
      customUI: ({ onClose }) => {
        return (
          <AlertModal selectedStyle={selectedStyle}>
            <div className='author-delete-alert'>
              <p>Are you sure you want to delete this post?</p>
              <div className="author-delete-buttons">
                <button onClick={onClose}>No</button>
                <button
                  onClick={() => {
                    setIsAuthorDelete(true);
                    setIsAuthorEdit(false);
                    setPublishCommentEditOptions(prevOptions => ({
                      ...prevOptions,
                      commentCid: comment.cid,
                      subplebbitAddress: comment.subplebbitAddress,
                      deleted: true,
                    }));
                    setTriggerPublishCommentEdit(true);
                    onClose();
                  }}
                >
                  Yes
                </button>
              </div>
            </div>
          </AlertModal>
        );
      }
    });
  };


  const handleAuthorEditClick = (comment) => {
    handleOptionClick(comment.cid);
    setIsAuthorEdit(true);
    setIsAuthorDelete(false);
    setCommentCid(comment.cid);
    setOriginalCommentContent(comment.content);
    setIsEditModalOpen(true);
  }



  const onChallengeVerification = (challengeVerification) => {
    if (challengeVerification.challengeSuccess === true) {
        setNewSuccessMessage('Challenge Success');
    } 
    else if (challengeVerification.challengeSuccess === false) {
      setNewErrorMessage(`Challenge Failed, reason: ${challengeVerification.reason}. Errors: ${challengeVerification.errors}`);
      console.log('challenge failed', challengeVerification);
    }
  };


  const onChallenge = async (challenges, comment) => {
    setPendingComment(comment);
    let challengeAnswers = [];
    try {
      challengeAnswers = await getChallengeAnswersFromUser(challenges)
    }
    catch (error) {
      setNewErrorMessage(error.message); console.log(error);
    }
    if (challengeAnswers) {
      await comment.publishChallengeAnswers(challengeAnswers)
    }
  };


  const getChallengeAnswersFromUser = async (challenges) => {
    setChallengesArray(challenges);
    
    return new Promise((resolve, reject) => {
      const imageString = challenges?.challenges[0].challenge;
      const imageSource = `data:image/png;base64,${imageString}`;
      const challengeImg = new Image();
      challengeImg.src = imageSource;
  
      challengeImg.onload = () => {
        setIsCaptchaOpen(true);
  
        const handleKeyDown = async (event) => {
          if (event.key === 'Enter') {
            const currentCaptchaResponse = captchaResponse;
            resolve(currentCaptchaResponse);
            setIsCaptchaOpen(false);
            document.removeEventListener('keydown', handleKeyDown);
            event.preventDefault();
          }
        };

        setCaptchaResponse('');
        document.addEventListener('keydown', handleKeyDown);

        setResolveCaptchaPromise(resolve);
      };
  
      challengeImg.onerror = () => {
        reject(setNewErrorMessage('Could not load challenges'));
      };
    });
  };

  const [publishCommentEditOptions, setPublishCommentEditOptions] = useState({
    commentCid: commentCid,
    content: editedComment || undefined,
    subplebbitAddress: selectedAddress,
    onChallenge,
    onChallengeVerification,
    onError: (error) => {
      setNewErrorMessage(error.message); console.log(error);
    },
  });
  
  
  const { publishCommentEdit } = usePublishCommentEdit(publishCommentEditOptions);


  useEffect(() => {
    setPublishCommentEditOptions((prevOptions) => ({
      ...prevOptions,
      commentCid: commentCid,
      content: editedComment || undefined,
    }));
  }, [commentCid, editedComment]);


  useEffect(() => {
    if (editedComment !== '') {
      setTriggerPublishCommentEdit(true);
    }
  }, [editedComment, setIsAuthorEdit]);

  
  useEffect(() => {
    let isActive = true;
    if (publishCommentEditOptions && triggerPublishCommentEdit) {
      (async () => {
        await publishCommentEdit();
        if (isActive) {
          setTriggerPublishCommentEdit(false);
        }
      })();
    }

    return () => {
      isActive = false;
    };
  }, [triggerPublishCommentEdit, publishCommentEdit, publishCommentEditOptions]);


  let displayWidth, displayHeight;
  if (thread.linkWidth && thread.linkHeight) {
    let scale = Math.min(1, 150 / Math.max(thread.linkWidth, thread.linkHeight));
    displayWidth = `${thread.linkWidth * scale}px`;
    displayHeight = `${thread.linkHeight * scale}px`;
  } else if (thread.link) {
    displayWidth = '150px';
    displayHeight = '150px';
  } else {
    displayWidth = '0px';
    displayHeight = '0px';
  }


  return (
    <>
      {isHoveringOnThread === thread.cid  ? 
        createPortal(
          <PostPreview selectedStyle={selectedStyle}>
            <div ref={popupRef}
            className="post-preview"
            onMouseOver={() => handleMouseOnLeaveThread()}
            style={{
            visibility: isCalculationDone ? 'visible' : 'hidden',
            left: 
              isCalculationDone && spaceOnRight > 250
              ? isMediaShowed ? imageRect.right + 5 : textRect.right + 5 :
              isCalculationDone && spaceOnRight < 250
              ? isMediaShowed ? imageRect.left - popupRect.width - 5 : textRect.left - popupRect.width - 5
              : 'auto',
            top: popupPosition.top + 5,
            }}>
              <span className="post-subject" >
                {thread.title ? `${thread.title} ` : "Posted "}
              </span>
              by 
              <span className="post-author"> 
              {thread.author.displayName ?` ${thread.author.displayName} ` : " Anonymous "} 
              </span>
              <span className='post-ago'>
                {thread.timestamp ? getFormattedTime(thread.timestamp) : null}
              </span>
              {thread.replyCount > 0 ?
                <div className='post-last'>
                  Last reply by 
                  <span className="post-author"> Anonymous </span>
                  <span className='post-ago'>{getFormattedTime(thread.lastReplyTimestamp)}</span>
                </div>
              : null}
            </div>
          </PostPreview>, document.body
        )
        : null }
      <div key={`thread-`} className="thread"  
        ref={el => { 
          threadRefs.current[thread.cid] = el; 
        }}
      onMouseLeave={() => {handleMouseOnLeaveThread()}}>
        {commentMediaInfo?.url ? (
          <Link style={{all: "unset", cursor: "pointer"}} key={`link-`} to={`/p/${thread.subplebbitAddress}/c/${thread.cid}`} 
          onClick={() => setSelectedThread(thread.cid)} 
          onMouseOver={() => {
            setIsHoveringOnThread(thread.cid);
            setIsHoveringForMenu(thread.cid);
            const rect = threadRefs.current[thread.cid].getBoundingClientRect();
            setPopupPosition({top: rect.top + window.scrollY, left: rect.left});
          }}
          onMouseLeave={() => setIsHoveringForMenu(false)}>
            {commentMediaInfo?.type === "webpage" ? (
              thread.thumbnailUrl ? (
                <span className="file-thumb" style={{width: displayWidth, height: displayHeight}}>
                  <img className="card" ref={imageRef} key={`img-`}
                  src={commentMediaInfo.thumbnail} alt={commentMediaInfo.type}
                  onError={(e) => {
                    e.target.src = fallbackImgUrl
                    e.target.onerror = null;
                  }}  />
                </span>
              ) : null
            ) : null}
            {commentMediaInfo?.type === "iframe" && (thread.thumbnailUrl || commentMediaInfo.thumbnail) ? (
              <span className="file-thumb" style={{width: displayWidth, height: displayHeight}}>
                <img className="card" ref={imageRef} key={`img-`}
                src={commentMediaInfo.thumbnail} alt={commentMediaInfo.type}
                onError={(e) => { e.target.src = fallbackImgUrl }}  />
              </span>
            ) : null}
            {commentMediaInfo?.type === "image" ? (
              <span className="file-thumb" style={{width: displayWidth, height: displayHeight}}>
                <img className="card" ref={imageRef} key={`img-`}
                src={commentMediaInfo.url} alt={commentMediaInfo.type} 
                onError={(e) => {
                  e.target.src = fallbackImgUrl
                  e.target.onerror = null;}}  />
              </span>
            ) : null}
            {commentMediaInfo?.type === "video" ? (
              <span className="file-thumb" style={{width: displayWidth, height: displayHeight}}>
                <video className="card" ref={imageRef} key={`fti-`} 
                src={commentMediaInfo.url} 
                alt={commentMediaInfo.type} 
                onError={(e) => e.target.src = fallbackImgUrl} /> 
              </span>
            ) : null}
            {commentMediaInfo?.type === "audio" ? (
                <audio className="card" ref={imageRef} controls 
                key={`fti-`} 
                src={commentMediaInfo.url} 
                alt={commentMediaInfo.type} 
                onError={(e) => e.target.src = fallbackImgUrl} />
            ) : null}
          </Link>
        ) : null}
        <div key={`ti-`} className="thread-icons" >
        {isMediaShowed ? (                          
            <OfflineIndicator 
            address={thread.subplebbitAddress} 
            className="thread-icon offline-icon"
            tooltipPlace="top" />
          ) : (
            <OfflineIndicator 
            address={thread.subplebbitAddress} 
            className={`thread-icon ${linkCount > 0 ? "offline-icon-no-link-shifted" : "offline-icon-no-link"} ${isHoveringOnThread === thread.cid ? 'offline-icon-no-link-hovered' : ''}`}
            tooltipPlace="top" />
        )}
        </div>
        <BoardForm selectedStyle={selectedStyle} 
          onMouseOver={() => {
            setIsHoveringForMenu(thread.cid);
            handleMouseOnLeaveThread();
          }}
          onMouseLeave={() => setIsHoveringForMenu(false)}
        style={{ all: "unset"}}>
          <div key={`meta-`} className="meta" title="(R)eplies / (L)ink Replies" >
            R:&nbsp;<b key={`b-`}>{thread.replyCount}</b>
            {linkCount > 0 ? (
              <>
                &nbsp;/
                L:&nbsp;<b key={`i-`}>{linkCount}</b>
              </>
            ) : null}
          <PostMenu 
            style={{ display: isHoveringForMenu === thread.cid ? 'inline-block' : 'none',
            position: 'absolute', lineHeight: '1em', marginTop: '-1px', outline: 'none',
            zIndex: '999'}}
            key={`pmb-`} 
            title="Post menu"
            ref={el => { 
              threadMenuRefs.current[thread.cid] = el; 
              postMenuRef.current = el; 
            }}
            className='post-menu-button' 
            id='post-menu-button-catalog'
            rotated={openMenuCid === thread.cid}
            onClick={(event) => {
              event.stopPropagation();
              const rect = threadMenuRefs.current[thread.cid].getBoundingClientRect();
              setMenuPosition({top: rect.top + window.scrollY, left: rect.left});
              setOpenMenuCid(prevCid => (prevCid === thread.cid ? null : thread.cid));
            }}                              
          >
            ▶
          </PostMenu>
          </div>
          {createPortal(
            <PostMenuCatalog selectedStyle={selectedStyle} 
              ref={el => {postMenuCatalogRef.current = el}}
              onClick={(event) => event.stopPropagation()}
              style={{position: "absolute", 
              top: menuPosition.top + 7, 
              left: menuPosition.left}}>
              <div className={`post-menu-thread post-menu-thread-${thread.cid}`}
              style={{ display: openMenuCid === thread.cid ? 'block' : 'none' }}
              >
                <ul className="post-menu-catalog">
                  <li onClick={() => {
                    handleOptionClick(thread.cid);
                    handleShareClick(selectedAddress, thread.cid);
                  }}>Share thread</li>
                  <VerifiedAuthor commentCid={thread.cid}>{({ authorAddress }) => (
                    <>
                      {authorAddress === account?.author.address || 
                      authorAddress === account?.signer.address ? (
                        <>
                          <li onClick={() => handleAuthorEditClick(thread)}>Edit post</li>
                          <li onClick={() => handleAuthorDeleteClick(thread)}>Delete post</li>
                        </>
                      ) : null}
                      {isModerator ? (
                        <>
                          {authorAddress === account?.author.address ||
                          authorAddress === account?.signer.address ? (
                            null
                          ) : (
                            <li onClick={() => {
                              setSelectedAddress(thread.subplebbitAddress);
                              setModeratingCommentCid(thread.cid)
                              setIsModerationOpen(true); 
                              handleOptionClick(thread.cid);
                              setDeletePost(true);
                            }}>
                            Delete post
                            </li>
                          )}
                          <li
                          onClick={() => {
                            setSelectedAddress(thread.subplebbitAddress);
                            setModeratingCommentCid(thread.cid)
                            setIsModerationOpen(true); 
                            handleOptionClick(thread.cid);
                          }}>
                            Mod tools
                          </li>
                        </>
                      ) : null}
                    </>
                  )}</VerifiedAuthor>
                  {(commentMediaInfo && (
                    commentMediaInfo.type === 'image' || 
                    (commentMediaInfo.type === 'webpage' && 
                    commentMediaInfo.thumbnail))) ? ( 
                      <li 
                      onMouseOver={() => {setIsImageSearchOpen(true)}}
                      onMouseLeave={() => {setIsImageSearchOpen(false)}}>
                        Image search »
                        <ul className="dropdown-menu post-menu-catalog"
                          style={{display: isImageSearchOpen ? 'block': 'none'}}>
                          <li onClick={() => handleOptionClick(thread.cid)}>
                            <a 
                            href={`https://lens.google.com/uploadbyurl?url=${commentMediaInfo.url}`}
                            target="_blank" rel="noreferrer"
                            >Google</a>
                          </li>
                          <li onClick={() => handleOptionClick(thread.cid)}>
                            <a
                            href={`https://yandex.com/images/search?url=${commentMediaInfo.url}`}
                            target="_blank" rel="noreferrer"
                            >Yandex</a>
                          </li>
                          <li onClick={() => handleOptionClick(thread.cid)}>
                            <a
                            href={`https://saucenao.com/search.php?url=${commentMediaInfo.url}`}
                            target="_blank" rel="noreferrer"
                            >SauceNAO</a>
                          </li>
                        </ul>
                      </li>
                    ) : null
                  }
                  <li 
                  onMouseOver={() => {setIsClientRedirectMenuOpen(true)}}
                  onMouseLeave={() => {setIsClientRedirectMenuOpen(false)}}>
                    View on »
                    <ul className="dropdown-menu post-menu-catalog"
                      style={{display: isClientRedirectMenuOpen ? 'block': 'none'}}>
                      <li onClick={() => handleOptionClick(thread.cid)}>
                        <a 
                        href={`https://plebbitapp.eth.limo/#/p/${selectedAddress}/c/${thread.cid}`}
                        target="_blank" rel="noreferrer"
                        >Plebbit</a>
                      </li>
                      {/* <li onClick={() => handleOptionClick(thread.cid)}>
                        <a
                        href={`https://seedit.eth.limo/#/p/${selectedAddress}/c/${thread.cid}`}
                        target="_blank" rel="noreferrer"
                        >Seedit</a>
                      </li> */}
                      <li onClick={() => handleOptionClick(thread.cid)}>
                        <a
                        href={`https://plebones.netlify.app/#/p/${selectedAddress}/c/${thread.cid}`}
                        target="_blank" rel="noreferrer"
                        >Plebones</a>
                      </li>
                    </ul>
                  </li>
                </ul>
              </div>
            </PostMenuCatalog>, document.body
          )}
        </BoardForm>
        <Link style={{all: "unset", cursor: "pointer"}} key={`link2-`} to={`/p/${thread.subplebbitAddress}/c/${thread.cid}`} 
        onClick={() => setSelectedThread(thread.cid)}>
          <div key={`t-`} className="teaser" style={{maxHeight: `calc(320px - ${displayHeight})`}}>
            <span key={`teaser-width${thread.cid}`} ref={textRef} 
            onMouseOver={() => {
              setIsHoveringOnThread(thread.cid);
              setIsHoveringForMenu(thread.cid);
              const rect = threadRefs.current[thread.cid].getBoundingClientRect();
              setPopupPosition({top: rect.top + window.scrollY, left: rect.left});
            }}
            onMouseLeave={() => setIsHoveringForMenu(false)}>
              <b key={`b2-`}>{thread.title ? `${thread.title}` : null}</b>
              {thread.content ? `: ${thread.content}` : null}
            </span>
          </div>
        </Link>
      </div>
    </>
  );
};


const CatalogRow = ({row}) => {
  const posts = []
  for (const post of row) {
    posts.push(<CatalogPost key={post?.cid} post={post} />)
  }
  return <div>{posts}</div>
}


const AllCatalog = () => {
  const {
    defaultSubplebbits,
    isModerationOpen, setIsModerationOpen,
    isSettingsOpen, setIsSettingsOpen,
    originalCommentContent,
    selectedAddress, setSelectedAddress,
    selectedStyle,
    setSelectedTitle,
  } = useGeneralStore(state => state);

  const virtuosoRef = useRef();

  const navigate = useNavigate();

  const [prevScrollPos, setPrevScrollPos] = useState(0);
  const [visible, setVisible] = useState(true);

  const [isEditModalOpen, setIsEditModalOpen] = useState(false);
  const [deletePost, setDeletePost] = useState(false);
  const [isCreateBoardOpen, setIsCreateBoardOpen] = useState(false);

  const addresses = defaultSubplebbits.map(subplebbit => subplebbit.address);
  const { feed, hasMore, loadMore } = useFeed({subplebbitAddresses: addresses, sortType: 'active'});
  const {subplebbits} = useSubplebbits({subplebbitAddresses: addresses, sortType: 'active'});
  const [selectedFeed, setSelectedFeed] = useState(feed.sort((a, b) => b.timestamp - a.timestamp));

  const stateString = useFeedStateString(subplebbits);

  const columnWidth = 180;
  const windowWidth = useWindowWidth();
  const columnCount = Math.floor(windowWidth / columnWidth);
  const rows = useFeedRows(selectedFeed, columnCount);

  // mobile navbar scroll effect
  useEffect(() => {
    const debouncedHandleScroll = debounce(() => {
      const currentScrollPos = window.pageYOffset;
      setVisible(prevScrollPos > currentScrollPos || currentScrollPos < 10);
      setPrevScrollPos(currentScrollPos);
    }, 50);
  
    window.addEventListener('scroll', debouncedHandleScroll);
  
    return () => window.removeEventListener('scroll', debouncedHandleScroll);
  }, [prevScrollPos, visible]);

  // mobile navbar board select functionality
  const handleSelectChange = (event) => {
    const selected = event.target.value;

    if (selected === 'subscriptions') {
      navigate(`/p/subscriptions`);
      return;
    } else if (selected === 'all') {
      navigate(`/p/all`);
      return;
    }

    const selectedTitle = defaultSubplebbits.find((subplebbit) => subplebbit.address === selected).title;
    setSelectedTitle(selectedTitle);
    setSelectedAddress(selected);
    navigate(`/p/${selected}`);
  };

  // desktop navbar board select functionality
  const handleClickTitle = (title, address) => {
    setSelectedTitle(title);
    setSelectedAddress(address);
    setSelectedFeed(feed.filter(feed => feed.title === title));
  };


  useEffect(() => {
    const setLastVirtuosoState = () => {
      virtuosoRef.current?.getState((snapshot) => {
        if (snapshot?.scrollTop === 0 || snapshot?.ranges?.length) {
          lastVirtuosoStates["allCatalog"] = snapshot;
        }
      });
    };
    window.addEventListener('scroll', setLastVirtuosoState);

    return () => window.removeEventListener('scroll', setLastVirtuosoState);
  }, [selectedAddress]);
  

  const lastVirtuosoState = lastVirtuosoStates["allCatalog"];


  return (
    <>
      <Helmet>
      <title>p/All - Catalog - plebchan</title>
      </Helmet>
      <Container>
        <CreateBoardModal
        selectedStyle={selectedStyle}
        isOpen={isCreateBoardOpen}
        closeModal={() => setIsCreateBoardOpen(false)} />
        <SettingsModal
        selectedStyle={selectedStyle}
        isOpen={isSettingsOpen}
        closeModal={() => setIsSettingsOpen(false)} />
        <ModerationModal 
        selectedStyle={selectedStyle}
        isOpen={isModerationOpen}
        closeModal={() => {setIsModerationOpen(false); setDeletePost(false)}}
        deletePost={deletePost} />
        <EditModal
        selectedStyle={selectedStyle}
        isOpen={isEditModalOpen}
        closeModal={() => setIsEditModalOpen(false)}
        originalCommentContent={originalCommentContent} />
        <NavBar selectedStyle={selectedStyle}>
          <>
          <span className="boardList">
            [
              <Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>All</Link>
               / 
              <Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>Subscriptions</Link>
            ]&nbsp;[
            {defaultSubplebbits.map((subplebbit, index) => (
              <span className="boardList" key={`span-${subplebbit.address}`}>
                {index === 0 ? null : "\u00a0"}
                <Link to={`/p/${subplebbit.address}`} key={`a-${subplebbit.address}`} onClick={() => {
                setSelectedTitle(subplebbit.title);
                setSelectedAddress(subplebbit.address);
                }}
                >{subplebbit.title ? subplebbit.title : subplebbit.address}</Link>
                {index !== defaultSubplebbits.length - 1 ? " /" : null}
              </span>
            ))}
            ]
          </span>
            <span className="nav">
              [
              <span id="button-span" style={{cursor: 'pointer'}} onClick={
              () => {
                window.electron && window.electron.isElectron ? (
                  setIsCreateBoardOpen(true)
                ) : (
                  alert(
                    'You can create a board with the desktop version of plebchan:\nhttps://github.com/plebbit/plebchan/releases/latest\n\nIf you are comfortable with the command line, use plebbit-cli:\nhttps://github.com/plebbit/plebbit-cli\n\n'
                  )
                )
              }
              }>Create Board</span>
              ]
              [
              <Link to={`/p/all/catalog/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
              ]
              [
              <Link to="/">Home</Link>
              ]
            </span>
            <div id="board-nav-mobile" style={{ top: visible ? 0 : '-23px' }}>
              <div className="nav-container">
                <div className="board-select">
                  <strong>Board</strong>
                  &nbsp;
                  <select id="board-select-mobile" value="all" onChange={handleSelectChange}>
                    <option value="all">All</option>
                    <option value="subscriptions">Subscriptions</option>
                    {defaultSubplebbits.map(subplebbit => (
                        <option key={`option-${subplebbit.address}`} value={subplebbit.address}
                        >{subplebbit.title ? subplebbit.title : subplebbit.address}</option>
                      ))}
                  </select> 
                  <span id="button-span" style={{cursor: 'pointer'}} onClick={
                  () => alert(
                    'You can create a board with the desktop version of plebchan:\nhttps://github.com/plebbit/plebchan/releases/latest\n\nIf you are comfortable with the command line, use plebbit-cli:\nhttps://github.com/plebbit/plebbit-cli\n\n'
                    )
                  }>Create Board</span>
                </div>
                <div className="page-jump">
                  <Link to={`/p/all/catalog/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
                  &nbsp;
                  <Link to="/" onClick={() => {handleStyleChange({target: {value: "Yotsuba"}}); window.scrollTo(0, 0);}}>Home</Link>
                </div>
              </div>
            </div>
            <div id="separator-mobile">&nbsp;</div>
            <div id="separator-mobile">&nbsp;</div>
          </>
        </NavBar>
        <Header selectedStyle={selectedStyle}>
          <>
            <div className="banner">
              <ImageBanner />
            </div>
            <div className="board-title">p/All</div>
            <div className="board-address">Default boards, currently curated by devs.</div>
          </>
        </Header>
        <Break selectedStyle={selectedStyle} />
        <TopBar selectedStyle={selectedStyle}>
          <hr />
          <span className="style-changer">
            Style:
             
            <select id="style-selector" onChange={handleStyleChange} value={selectedStyle}>
              <option value="Yotsuba">Yotsuba</option>
              <option value="Yotsuba-B">Yotsuba B</option>
              <option value="Futaba">Futaba</option>
              <option value="Burichan">Burichan</option>
              <option value="Tomùorrow">Tomorrow</option>
              <option value="Photon">Photon</option>
            </select>
          </span>
          <div className="return-button" id="return-button-desktop">
            [
            <Link to={`/p/all`}>Return</Link>
            ]
          </div>
          <div id="return-button-mobile">
            <span className="btn-wrap-catalog btn-wrap">
              <Link to={`/p/all`}>Return</Link>
            </span>
          </div>
          {subplebbits.state === "succeeded" ? (
            null
          ) : (
            <div className="stats-all-catalog-container">
            <span id="stats-all">
              {stateString}
            </span>
            <span className={stateString ? "ellipsis-all" : ""} />
          </div>
          )}
          <hr />
        </TopBar>
        <Tooltip id="tooltip" className="tooltip" />
        <Threads selectedStyle={selectedStyle}>
          {feed.length > 1 ? (
            <Virtuoso
              increaseViewportBy={{bottom: 600, top: 600}}
              totalCount={rows?.length || 0}
              data={rows}
              style={{maxWidth: '100%'}}
              itemContent={(index, row) => <CatalogRow index={index} row={row} />}
              useWindowScroll={true}
              components={{ Footer: () => hasMore ? <CatalogLoader /> : null}}
              endReached={loadMore}
              ref={virtuosoRef}
              restoreStateFrom={lastVirtuosoState}
              initialScrollTop={lastVirtuosoState?.scrollTop}
            />
          ) : (<CatalogLoader />)}
        </Threads>
        <Footer selectedStyle={selectedStyle}>
          <Break id="break" selectedStyle={selectedStyle} style={{
            marginTop: "-36px",
            width: "100%",
          }} />
          <Break selectedStyle={selectedStyle} style={{
            width: "100%",
          }} />
          <span className="style-changer" style={{
            float: "right",
            marginTop: "2px",
          }}>
            Style:
             
            <select id="style-selector" onChange={handleStyleChange} value={selectedStyle}>
              <option value="Yotsuba">Yotsuba</option>
              <option value="Yotsuba-B">Yotsuba B</option>
              <option value="Futaba">Futaba</option>
              <option value="Burichan">Burichan</option>
              <option value="Tomorrow">Tomorrow</option>
              <option value="Photon">Photon</option>
            </select>
          </span>
          <NavBar selectedStyle={selectedStyle} style={{
            marginTop: "42px",
          }}>
          <>
            <span className="boardList">
              [
                <Link to={`/p/all`} onClick={() => window.scrollTo(0, 0)}>All</Link>
                 / 
                <Link to={`/p/subscriptions`} onClick={() => window.scrollTo(0, 0)}>Subscriptions</Link>
              ]&nbsp;[
            {defaultSubplebbits.map((subplebbit, index) => (
              <span className="boardList" key={`span-${subplebbit.address}`}>
                {index === 0 ? null : "\u00a0"}
                <Link to={`/p/${subplebbit.address}`} key={`a-${subplebbit.address}`} onClick={() => handleClickTitle(subplebbit.title, subplebbit.address)}
                >{subplebbit.title ? subplebbit.title : subplebbit.address}</Link>
                {index !== defaultSubplebbits.length - 1 ? " /" : null}
                </span>
              ))}
              ]
            </span>
              <span className="nav">
              [
              <span id="button-span" style={{cursor: 'pointer'}} onClick={
              () => {
                window.electron && window.electron.isElectron ? (
                  setIsCreateBoardOpen(true)
                ) : (
                  alert(
                    'You can create a board with the desktop version of plebchan:\nhttps://github.com/plebbit/plebchan/releases/latest\n\nIf you are comfortable with the command line, use plebbit-cli:\nhttps://github.com/plebbit/plebbit-cli\n\n'
                  )
                )
              }
              }>Create Board</span>
              ]
                [
                <Link to={`/p/all/catalog/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
                ]
                [
                <Link to="/" onClick={() => handleStyleChange({target: {value: "Yotsuba"}}
                )}>Home</Link>
                ]
              </span>
            </>
          </NavBar>
          <div id="version">
            plebchan v{version}{commitRef}. GPL-2.0
          </div>
          <div className="footer-links"
            style={{
              textAlign: "center",
              fontSize: "x-small",
              fontFamily: "arial",
              marginTop: "5px",
              marginBottom: "15px",
            }}>
            <a style={{textDecoration: 'underline'}} href="https://plebbit.com" target="_blank" rel="noopener noreferrer">About</a>
            &nbsp;•&nbsp;  
            <a style={{textDecoration: 'underline'}} href="https://github.com/plebbit/plebchan/releases/latest" target="_blank" rel="noopener noreferrer">App</a>
            &nbsp;•&nbsp;
            <a style={{textDecoration: 'underline'}} href="https://twitter.com/plebchan_eth" target="_blank" rel="noopener noreferrer">Twitter</a>
            &nbsp;•&nbsp;  
            <a style={{textDecoration: 'underline'}} href="https://t.me/plebbit" target="_blank" rel="noopener noreferrer">Telegram</a>
          </div>
        </Footer>
      </Container>
    </>
  );
}

export default AllCatalog;