import { createEffect, For, Match, onMount, Switch } from "solid-js";
import { ExprREPL } from "./REPL";
import { clearFocus, DigithId, scrowl } from "./scrowlStore";
import { NewFunctionDraftDigith } from "./Function/NewFunctionDraftDigith";
import { FunctionDigith } from "./Function/FunctionDigith";
import { Digith } from "./Digith";

// WTF are these names?
// Scrowl
// - thining about "scrawling", "howl", "crows", "owls", "nests", "scrolling", "soul", "crawling"
// Digith
// - thinking about fingers/digits. Hand is an object to think with (counting).
// - Thinking of a prosthesis that's an extension of your body doing your bidding without you knowing exactly how.
// - digital

export function Scrowl() {
  return (
    <div
      id="scrowl"
      style={{
        display: "flex",
        "flex-direction": "column",
        gap: "1.5rem",
      }}
    >
      <For each={scrowl.digiths}>
        {(digith) => (
          <DigithWrapper id={digith.id}>
            <Switch>
              <Match when={digith.tag === 'repl'}>
                <article class="digith">
                   <header><strong>REPL</strong></header>
                   <ExprREPL />
                </article>
              </Match>
              
              <Match when={digith.tag === 'new-fn-draft'}>
                <NewFunctionDraftDigith draft={digith as Digith.NewFunctionDraft} />
              </Match>

              <Match when={digith.tag === 'fn'}>
                <FunctionDigith function={digith as Digith.Function} />
              </Match>
            </Switch>
          </DigithWrapper>
        )}
      </For>

    </div>
  );
}

// For focusing on a Digith
// This works basically in two ways:
// - We have the list of digiths, and each time any of them is mounted, there's `attemptScroll` check done on all of them.
// - Whenever `scrowl.focusTarget` changes, it reactively broadcasts the change to each of the digith,
//   and each digith asks itself, "Am I focus-target?".
function DigithWrapper(props: { id: DigithId, children: any }) {
  let ref: HTMLDivElement | undefined;

  // The Logic: Run this whenever 'scrowl.focusTarget' changes OR when this component mounts
  const attemptScroll = () => {
    if (scrowl.focusTarget === props.id && ref) {
      ref.scrollIntoView({ behavior: "smooth", block: "start" });
      setTimeout(clearFocus, 0); // This sets asynchronously the focus-target to null.
    }
  };

  onMount(attemptScroll);
  createEffect(attemptScroll);

  return (
    <div 
      ref={ref} 
      style={{ "scroll-margin-top": "2rem" }}
    >
      {props.children}
    </div>
  );
}
