import {
  createSignal,
  Show,
  onMount,
  type ParentComponent,
  createRenderEffect,
} from "solid-js";
import { useDocumentTitle } from "../utils";
import Scaffold from "~material/Scaffold";
import {
  AppBar,
  ListItemSecondaryAction,
  ListItemText,
  MenuItem,
  Switch,
  Toolbar,
} from "@suid/material";
import { css } from "solid-styled";
import { TimeSourceProvider, createTimeSource } from "~platform/timesrc";
import ProfileMenuButton from "./ProfileMenuButton";
import Tabs from "~material/Tabs";
import Tab from "~material/Tab";
import { makeEventListener } from "@solid-primitives/event-listener";
import { $settings } from "../settings/stores";
import { useStore } from "@nanostores/solid";
import TrendTimelinePanel from "./TrendTimelinePanel";
import TimelinePanel from "./TimelinePanel";
import { useSessions } from "../masto/clients";
import {
  createSingluarItemSelection,
  default as ItemSelectionProvider,
} from "./toots/ItemSelectionProvider";

const Home: ParentComponent = (props) => {
  let panelList: HTMLDivElement;
  useDocumentTitle("Timelines");
  const now = createTimeSource();
  const [, selectionState] = createSingluarItemSelection(
    undefined as string | undefined,
  );

  const settings$ = useStore($settings);

  const profiles = useSessions();
  const client = () => {
    const all = profiles();
    return all?.[0]?.client;
  };

  const prefetching = () => !settings$().prefetchTootsDisabled;
  const [focusRange, setFocusRange] = createSignal([0, 0] as readonly [
    number,
    number,
  ]);

  let scrollEventLockReleased = true;

  const recalculateTabIndicator = () => {
    scrollEventLockReleased = false;
    try {
      const { x: panelX, width: panelWidth } =
        panelList.getBoundingClientRect();
      let minIdx = +Infinity,
        maxIdx = -Infinity;
      const items = panelList.querySelectorAll(".tab-panel");
      const ranges = Array.from(items).map((x) => {
        const rect = x.getBoundingClientRect();
        const inlineStart = rect.x - panelX;
        const inlineEnd = rect.width + inlineStart;
        return [inlineStart, inlineEnd] as const;
      });
      for (let i = 0; i < items.length; i++) {
        const e = items.item(i);
        const [inlineStart, inlineEnd] = ranges[i];
        if (inlineStart >= 0 && inlineEnd <= panelWidth) {
          minIdx = Math.min(minIdx, i);
          maxIdx = Math.max(maxIdx, i);
          e.classList.add("active");
        } else {
          e.classList.remove("active");
        }
      }

      if (isFinite(minIdx) && isFinite(maxIdx)) {
        setFocusRange([minIdx, maxIdx]);
      }
    } finally {
      scrollEventLockReleased = true;
    }
  };

  const requestRecalculateTabIndicator = () => {
    if (scrollEventLockReleased) {
      requestAnimationFrame(recalculateTabIndicator);
    }
  };

  createRenderEffect(() => {
    makeEventListener(window, "resize", requestRecalculateTabIndicator);
  });

  onMount(() => {
    requestAnimationFrame(recalculateTabIndicator);
  });

  const isTabFocus = (idx: number) => {
    const [start, end] = focusRange();
    if (!isFinite(start) || !isFinite(end)) return false;
    return idx >= start && idx <= end;
  };

  const onTabClick = (idx: number) => {
    const items = panelList.querySelectorAll(".tab-panel");
    if (items.length > idx) {
      items.item(idx).scrollIntoView({ block: "start", behavior: "smooth" });
    }
    if (isTabFocus(idx)) {
      items.item(idx).scrollTo({
        top: 0,
        behavior: "smooth",
      });
    }
  };

  css`
    .tab-panel {
      overflow: visible auto;
      max-width: 560px;
      height: 100%;
      padding: 0 16px;
      scroll-snap-align: center;
      overscroll-behavior-block: none;
      contain: strict;
      contain-intrinsic-size: auto 560px auto 100vh;
      contain-intrinsic-size: auto 560px auto 100dvh;

      @media (max-width: 600px) {
        padding: 0;
      }
    }

    .panel-list {
      display: grid;
      grid-auto-columns: 560px;
      grid-auto-flow: column;
      overflow: auto hidden;
      scroll-snap-type: x mandatory;
      scroll-snap-stop: always;
      height: calc(100vh - var(--scaffold-topbar-height, 0px));
      height: calc(100dvh - var(--scaffold-topbar-height, 0px));
      padding-left: var(--safe-area-inset-left, 0);
      padding-right: var(--safe-area-inset-right, 0);

      & > * {
        content-visibility: auto;
      }

      @media (max-width: 600px) {
        grid-auto-columns: 100%;
      }
    }
  `;

  return (
    <>
      <Scaffold
        topbar={
          <AppBar position="static">
            <Toolbar
              variant="dense"
              class="responsive"
              sx={{ paddingTop: "var(--safe-area-inset-top, 0px)" }}
            >
              <Tabs>
                <Tab focus={isTabFocus(0)} onClick={[onTabClick, 0]}>
                  Home
                </Tab>
                <Tab focus={isTabFocus(1)} onClick={[onTabClick, 1]}>
                  Trending
                </Tab>
                <Tab focus={isTabFocus(2)} onClick={[onTabClick, 2]}>
                  Public
                </Tab>
              </Tabs>
              <ProfileMenuButton profile={profiles()[0]}>
                <MenuItem
                  onClick={(e) =>
                    $settings.setKey(
                      "prefetchTootsDisabled",
                      !$settings.get().prefetchTootsDisabled,
                    )
                  }
                >
                  <ListItemText>Prefetch Toots</ListItemText>
                  <ListItemSecondaryAction>
                    <Switch checked={prefetching()}></Switch>
                  </ListItemSecondaryAction>
                </MenuItem>
              </ProfileMenuButton>
            </Toolbar>
          </AppBar>
        }
      >
        <ItemSelectionProvider value={selectionState}>
          <TimeSourceProvider value={now}>
            <Show when={!!client()}>
              <div
                class="panel-list"
                ref={panelList!}
                onScroll={requestRecalculateTabIndicator}
              >
                <div class="tab-panel">
                  <div>
                    <TimelinePanel
                      client={client()}
                      name="home"
                      prefetch={prefetching()}
                    />
                  </div>
                </div>
                <div class="tab-panel">
                  <div>
                    <TrendTimelinePanel client={client()} />
                  </div>
                </div>
                <div class="tab-panel">
                  <div>
                    <TimelinePanel
                      client={client()}
                      name="public"
                      prefetch={prefetching()}
                    />
                  </div>
                </div>
                <div></div>
              </div>
            </Show>
          </TimeSourceProvider>
        </ItemSelectionProvider>
      </Scaffold>
    </>
  );
};

export default Home;
