import React, { CSSProperties } from "react";
import { Spinner } from "reactstrap";
import { useTranslation } from "react-i18next";
import { fromEvent } from "rxjs";
import Svg from "react-inlinesvg";
import clsx from "clsx";
import arrowsAngleContractIcon from "bootstrap-icons/icons/arrows-angle-contract.svg";
import arrowsAngleExpandIcon from "bootstrap-icons/icons/arrows-angle-expand.svg";
import { getAlertHost } from "../common/alert-service";
import { useEventEmiiter, UiLogicError } from "../common";
import {
  TimelineInfo,
  TimelinePostsWithSyncState,
  timelineService,
} from "../data/timeline";
import { userService } from "../data/user";
import AppBar from "../common/AppBar";
import Timeline, {
  TimelinePostInfoEx,
  TimelineDeleteCallback,
} from "./Timeline";
import TimelinePostEdit, { TimelinePostSendCallback } from "./TimelinePostEdit";
type TimelinePostSyncState = "syncing" | "synced" | "offline";
const TimelinePostSyncStateBadge: React.FC<{
  state: TimelinePostSyncState;
  style?: CSSProperties;
  className?: string;
}> = ({ state, style, className }) => {
  const { t } = useTranslation();
  return (
    
      {(() => {
        switch (state) {
          case "syncing": {
            return (
              <>
                
                  {t("timeline.postSyncState.syncing")}
                 
              >
            );
          }
          case "synced": {
            return (
              <>
                
                  {t("timeline.postSyncState.synced")}
                 
              >
            );
          }
          case "offline": {
            return (
              <>
                
                  {t("timeline.postSyncState.offline")}
                 
              >
            );
          }
          default:
            throw new UiLogicError("Unknown sync state.");
        }
      })()}
    
  );
};
export interface TimelineCardComponentProps {
  timeline: TimelineInfo;
  onManage?: (item: TManageItems | "property") => void;
  onMember: () => void;
  className?: string;
  onHeight?: (height: number) => void;
}
export interface TimelinePageTemplateUIProps {
  avatarKey?: string | number;
  timeline?: TimelineInfo;
  postListState?: TimelinePostsWithSyncState;
  CardComponent: React.ComponentType>;
  onMember: () => void;
  onManage?: (item: TManageItems | "property") => void;
  onPost?: TimelinePostSendCallback;
  onDelete: TimelineDeleteCallback;
  error?: string;
}
export default function TimelinePageTemplateUI(
  props: TimelinePageTemplateUIProps
): React.ReactElement | null {
  const { timeline, postListState } = props;
  const { t } = useTranslation();
  const bottomSpaceRef = React.useRef(null);
  const onPostEditHeightChange = React.useCallback((height: number): void => {
    const { current: bottomSpaceDiv } = bottomSpaceRef;
    if (bottomSpaceDiv != null) {
      bottomSpaceDiv.style.height = `${height}px`;
    }
    if (height === 0) {
      const alertHost = getAlertHost();
      if (alertHost != null) {
        alertHost.style.removeProperty("margin-bottom");
      }
    } else {
      const alertHost = getAlertHost();
      if (alertHost != null) {
        alertHost.style.marginBottom = `${height}px`;
      }
    }
  }, []);
  const timelineRef = React.useRef(null);
  const [getResizeEvent, triggerResizeEvent] = useEventEmiiter();
  React.useEffect(() => {
    const { current: timelineElement } = timelineRef;
    if (timelineElement != null) {
      let loadingScrollToBottom = true;
      let pinBottom = false;
      const isAtBottom = (): boolean =>
        window.innerHeight + window.scrollY + 10 >= document.body.scrollHeight;
      const disableLoadingScrollToBottom = (): void => {
        loadingScrollToBottom = false;
        if (isAtBottom()) pinBottom = true;
      };
      const checkAndScrollToBottom = (): void => {
        if (loadingScrollToBottom || pinBottom) {
          window.scrollTo(0, document.body.scrollHeight);
        }
      };
      const subscriptions = [
        fromEvent(timelineElement, "wheel").subscribe(
          disableLoadingScrollToBottom
        ),
        fromEvent(timelineElement, "pointerdown").subscribe(
          disableLoadingScrollToBottom
        ),
        fromEvent(timelineElement, "keydown").subscribe(
          disableLoadingScrollToBottom
        ),
        fromEvent(window, "scroll").subscribe(() => {
          if (loadingScrollToBottom) return;
          if (isAtBottom()) {
            pinBottom = true;
          } else {
            pinBottom = false;
          }
        }),
        fromEvent(window, "resize").subscribe(checkAndScrollToBottom),
        getResizeEvent().subscribe(checkAndScrollToBottom),
      ];
      return () => {
        subscriptions.forEach((s) => s.unsubscribe());
      };
    }
  }, [getResizeEvent, triggerResizeEvent, timeline, postListState]);
  const [cardHeight, setCardHeight] = React.useState(0);
  const genCardCollapseLocalStorageKey = (uniqueId: string): string =>
    `timeline.${uniqueId}.cardCollapse`;
  const cardCollapseLocalStorageKey =
    timeline != null ? genCardCollapseLocalStorageKey(timeline.uniqueId) : null;
  const [infoCardCollapse, setInfoCardCollapse] = React.useState(true);
  React.useEffect(() => {
    if (cardCollapseLocalStorageKey != null) {
      const savedCollapse =
        window.localStorage.getItem(cardCollapseLocalStorageKey) === "true";
      setInfoCardCollapse(savedCollapse);
    }
  }, [cardCollapseLocalStorageKey]);
  let body: React.ReactElement;
  if (props.error != null) {
    body = {t(props.error)}
;
  } else {
    if (timeline != null) {
      let timelineBody: React.ReactElement;
      if (postListState != null) {
        if (postListState.type === "notexist") {
          throw new UiLogicError(
            "Timeline is not null but post list state is notexist."
          );
        }
        if (postListState.type === "forbid") {
          timelineBody = (
            {t("timeline.messageCantSee")}
          );
        } else {
          const posts: TimelinePostInfoEx[] = postListState.posts.map(
            (post) => ({
              ...post,
              deletable: timelineService.hasModifyPostPermission(
                userService.currentUser,
                timeline,
                post
              ),
            })
          );
          const topHeight: string = infoCardCollapse
            ? "calc(68px + 1.5em)"
            : `${cardHeight + 60}px`;
          const syncState: TimelinePostSyncState = postListState.syncing
            ? "syncing"
            : postListState.type === "synced"
            ? "synced"
            : "offline";
          timelineBody = (
            
              
          );
          if (props.onPost != null) {
            timelineBody = (
              <>
                {timelineBody}
                
                
            
        );
      }
      const { CardComponent } = props;
      body = (
        <>
          
             {
                const newState = !infoCardCollapse;
                setInfoCardCollapse(newState);
                window.localStorage.setItem(
                  genCardCollapseLocalStorageKey(timeline.uniqueId),
                  newState.toString()
                );
              }}
              className="float-right m-1 info-card-collapse-button text-primary icon-button"
            />
             
          {timelineBody}
        >
      );
    } else {
      body = (
        
          
      );
    }
  }
  return (
    <>