import {
  Component,
  For,
  onCleanup,
  createSignal,
  Show,
  untrack,
  Match,
  Switch as JsSwitch,
  ErrorBoundary,
  type Ref,
} from "solid-js";
import { type mastodon } from "masto";
import { Button, LinearProgress } from "@suid/material";
import { createTimeline } from "../masto/timelines";
import { vibrate } from "../platform/hardware";
import PullDownToRefresh from "./PullDownToRefresh";
import TootComposer from "./TootComposer";
import Thread from "./Thread.jsx";
import { useDefaultSession } from "../masto/clients";

const TootList: Component<{
  ref?: Ref<HTMLDivElement>;
  threads: string[];
  onUnknownThread: (id: string) => { value: mastodon.v1.Status }[] | undefined;
  onChangeToot: (id: string, value: mastodon.v1.Status) => void;
}> = (props) => {
  const session = useDefaultSession();
  const [expandedThreadId, setExpandedThreadId] = createSignal<string>();

  const onBookmark = async (
    client: mastodon.rest.Client,
    status: mastodon.v1.Status,
  ) => {
    const result = await (status.bookmarked
      ? client.v1.statuses.$select(status.id).unbookmark()
      : client.v1.statuses.$select(status.id).bookmark());
    props.onChangeToot(result.id, result);
  };

  const onBoost = async (
    client: mastodon.rest.Client,
    status: mastodon.v1.Status,
  ) => {
    vibrate(50);
    const rootStatus = status.reblog ? status.reblog : status;
    const reblogged = rootStatus.reblogged;
    if (status.reblog) {
      status.reblog = { ...status.reblog, reblogged: !reblogged };
      props.onChangeToot(status.id, status);
    } else {
      props.onChangeToot(
        status.id,
        Object.assign(status, {
          reblogged: !reblogged,
        }),
      );
    }
    const result = reblogged
      ? await client.v1.statuses.$select(status.id).unreblog()
      : (await client.v1.statuses.$select(status.id).reblog()).reblog!;
    props.onChangeToot(
      status.id,
      Object.assign(status.reblog ?? status, result.reblog),
    );
  };

  return (
    <ErrorBoundary
      fallback={(err, reset) => {
        return <p>Oops: {String(err)}</p>;
      }}
    >
      <div ref={props.ref}>
        <For each={props.threads}>
          {(itemId, index) => {
            const path = props.onUnknownThread(itemId)!;
            const toots = path.reverse().map((x) => x.value);

            return (
              <Thread
                toots={toots}
                onBoost={onBoost}
                onBookmark={onBookmark}
                onReply={({ status }, element) => {}}
                client={session()?.client!}
                isExpended={(status) => status.id === expandedThreadId()}
                onItemClick={(status, event) => {
                  if (status.id !== expandedThreadId()) {
                    setExpandedThreadId((x) => (x ? undefined : status.id));
                  } else {
                    // TODO: open full-screen toot
                  }
                }}
              />
            );
          }}
        </For>
      </div>
    </ErrorBoundary>
  );
};

export default TootList;
