import {
  createSignal,
  mergeProps,
  createResource,
  createEffect,
  onMount,
  onCleanup,
} from "solid-js";
import { computePosition, shift, autoUpdate, offset } from "@floating-ui/dom";

import UserService from "../services/user-service.js";
import ModalRegistry from "../modals/modal-registry.jsx";
import UrlUtils from "../tools/url-utils.js";
import SettingsView from "./settings-view.jsx";
import DevicesView from "./devices-view.jsx";

import {
  DEVICES_VIEW,
  REMOTES_VIEW,
  RECORDINGS_VIEW,
  SETTINGS_VIEW,
} from "../data/constants.js";

let [activeView, setActiveView] = createSignal(DEVICES_VIEW);

const MainView = function (props) {
  props = mergeProps({ onLogout: () => {} }, props);

  const [userInfo] = createResource(() => UserService.getUserInfo());
  const [username, setUsername] = createSignal("");

  createEffect(() => {
    if (userInfo.loading) return;
    setUsername(userInfo().username);
  });

  let Modals = ModalRegistry.getModals();

  let userButtonRef;
  let userMenuRef;
  let userMenuBackRef;
  let cleanUserMenu;

  onMount(() => {
    setViewFromUrl();
    window.addEventListener("popstate", setViewFromUrl);
  });

  onCleanup(() => {
    window.removeEventListener("popstate", setViewFromUrl);
  });

  function setViewFromUrl() {
    let view = UrlUtils.getQueryParameter("view");
    if (view) {
      setActiveView(view);
    }
  }

  function handleLogout() {
    UserService.logout();
    props.onLogout();
  }

  function toggleUserMenu() {
    if (userMenuRef.style.display === "none") {
      showUserMenu();
    } else {
      hideUserMenu();
    }
  }

  function showUserMenu() {
    cleanUserMenu = autoUpdate(userButtonRef, userMenuRef, () =>
      computePosition(userButtonRef, userMenuRef, {
        placement: "bottom-end",
        middleware: [offset(6), shift()],
      }).then(({ x, y }) => {
        Object.assign(userMenuRef.style, {
          left: `${x}px`,
          top: `${y}px`,
        });
      })
    );
    userMenuRef.style.display = "block";
    userMenuBackRef.style.display = "block";
  }

  function hideUserMenu() {
    userMenuRef.style.display = "none";
    userMenuBackRef.style.display = "none";
    cleanUserMenu();
  }

  function handleViewChange(view) {
    if (activeView() === view) return;
    setActiveView(view);
    let url = UrlUtils.getUrl();
    url = UrlUtils.addQueryParameter(url, "view", view);
    UrlUtils.setUrl(url);
  }

  function render() {
    return (
      <div class="d-flex flex-column" style="height:100vh">
        <Modals></Modals>
        <HeaderBar></HeaderBar>
        <ActiveView class={"bg-body-tertiary"}></ActiveView>
      </div>
    );
  }

  function HeaderBar() {
    return (
      <div>
        <div class="container-xl px-3 py-2 d-flex bg-dark-subtle">
          <div class="d-flex align-items-center flex-fill">
            <button
              class={
                "btn me-2" +
                (activeView() === DEVICES_VIEW ? " btn-secondary" : " btn-dark")
              }
              onClick={() => handleViewChange(DEVICES_VIEW)}
            >
              <i class="bi bi-tv me-2"></i>
              Devices
            </button>
            <button
              class={
                "btn me-2" +
                (activeView() === REMOTES_VIEW ? " btn-secondary" : " btn-dark")
              }
              onClick={() => handleViewChange(REMOTES_VIEW)}
            >
              <i class="bi bi-wifi me-2"></i>
              Remotes
            </button>
            <button
              class={
                "btn me-2" +
                (activeView() === RECORDINGS_VIEW
                  ? " btn-secondary"
                  : " btn-dark")
              }
              onClick={() => handleViewChange(RECORDINGS_VIEW)}
            >
              <i class="bi bi-record-circle me-2"></i>
              Recordings
            </button>
          </div>
          <div class="d-flex align-items-center">
            <button
              ref={userButtonRef}
              class="btn btn-dark rounded-circle p-0"
              style="width: 2.4em; height: 2.4em"
              onClick={toggleUserMenu}
            >
              <i class="bi bi-person-fill"></i>
            </button>
            <div
              onClick={hideUserMenu}
              ref={userMenuBackRef}
              style="position:absolute;width:100vw;height:100vh;left:0;right:0;z-index:1060;display:none"
            ></div>
            <div
              class="list-group position-absolute"
              style="display: none; z-index: 1070"
              ref={userMenuRef}
            >
              <li class="list-group-item bg-dark-subtle">{username()}</li>
              <button
                type="button"
                class="list-group-item list-group-item-action"
                onClick={() => {
                  handleViewChange(SETTINGS_VIEW);
                  hideUserMenu();
                }}
              >
                <i class="bi bi-gear-fill me-2"></i>
                Settings
              </button>
              <button
                type="button"
                class="list-group-item list-group-item-action pe-auto"
                onClick={() => handleLogout()}
              >
                <i class="bi bi-box-arrow-in-right me-2"></i>
                Log Out
              </button>
            </div>
          </div>
        </div>
      </div>
    );
  }

  function ActiveView(props) {
    return (
      <div class="container-xl p-0 d-flex flex-column flex-fill overflow-hidden">
        <Switch>
          <Match when={activeView() === SETTINGS_VIEW}>
            <SettingsView {...props} />
          </Match>
          <Match when={activeView() === DEVICES_VIEW}>
            <DevicesView {...props} />
          </Match>
        </Switch>
      </div>
    );
  }

  return render();
};

MainView.setActiveView = setActiveView;

export default MainView;
