import {
  createEffect,
  createMemo,
  createResource,
  createSignal,
  onCleanup,
  Show,
} from "solid-js";
import WebRTCService from "../../services/webrtc-service";
import Integration from "../../data/integration";
import DeviceService from "../../services/device-service";
import UrlUtils from "../../tools/url-utils";
import RemoteControl from "../../components/remote-control";
import RemoteService from "../../services/remotes-service";

const [integration, setIntegration] = createSignal(new Integration());

function IntegrationView(props) {
  const title = createMemo(() =>
    integration && typeof integration === "function"
      ? integration().getName()
      : "Integration"
  );
  const [connectionState, setConnectionState] = createSignal(
    WebRTCService.STATE_DISCONNECTED
  );
  const showConnectButton = createMemo(
    () =>
      connectionState() === WebRTCService.STATE_DISCONNECTED ||
      connectionState() === WebRTCService.STATE_FAILED ||
      connectionState() === WebRTCService.STATE_CLOSED
  );
  WebRTCService.onStateChanged(handleConnectionStateChanged);
  WebRTCService.onDataChannelOpen(handleDataChannelOpen);
  let videoElement = null;

  const [availableRemotes] = createResource(RemoteService.getRemotes, {
    initialValue: [],
  });
  const [selectedRemote, setSelectedRemote] = createSignal();
  const [remoteControlVisible, setRemoteControlVisible] = createSignal(false);

  createEffect(() =>
    handleRemoteSelected(
      availableRemotes()
        .find(() => true)
        ?.getId()
    )
  );

  createEffect(() => {
    let url = UrlUtils.getUrl();
    url = UrlUtils.addQueryParameter(url, "id", integration()?.getId());
    UrlUtils.setUrl(url);
  });

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

  setIntegrationFromUrl();
  window.addEventListener("popstate", setIntegrationFromUrl);

  async function setIntegrationFromUrl() {
    let integrationId = UrlUtils.getQueryParameter("id");
    if (!integrationId) return;
    let integration = await DeviceService.getIntegration(integrationId);
    setIntegration(integration);
  }

  function handleConnectWebRTC() {
    let integrationId = integration().getId();
    WebRTCService.setVideoElement(videoElement);
    WebRTCService.connect(integrationId);
  }

  function handleDisconnectWebRTC() {
    WebRTCService.disconnect();
  }

  function handleConnectionStateChanged(state) {
    setConnectionState(state);
  }

  function handleDataChannelOpen() {
    setInterval(() => {
      WebRTCService.sendDataJson({ message: "ping" });
    }, 1000);
  }

  async function handleRemoteSelected(remoteId) {
    if (!remoteId) return;
    let remote = await RemoteService.getRemote(remoteId);
    setSelectedRemote(remote);
  }

  function handleRemoteButtonPressed(command) {
    RemoteService.sendCommand(command);
  }

  function toggleRemoteControl() {
    setRemoteControlVisible(!remoteControlVisible());
  }

  return (
    <div
      class={
        "d-flex flex-column overflow-hidden flex-fill px-3 pb-2 pt-3 " +
        props.class
      }
    >
      <a>
        <i class="bi bi-arrow-left-short"></i>
        <span>Integration</span>
      </a>
      <h1>{title}</h1>
      <div class="d-flex flex-row">
        <div class="d-flex flex-row justify-content-end flex-fill">
          <Show when={showConnectButton()}>
            <button
              class="btn btn-dark me-2 mb-3"
              onClick={handleConnectWebRTC}
            >
              <i class="bi bi-plug-fill me-2"></i>
              Connect
            </button>
          </Show>
          <Show when={!showConnectButton()}>
            <button
              class="btn btn-dark me-2 mb-3"
              onClick={handleDisconnectWebRTC}
            >
              <i class="bi bi-x-lg me-2"></i>
              Disconnect
            </button>
          </Show>
        </div>
      </div>
      <div class="flex-fill d-flex flex-row overflow-hidden">
        <div
          class="flex-fill rounded overflow-hidden"
          style="position:relative;"
        >
          <video
            ref={videoElement}
            class="w-100 h-100"
            style="background-color: #000"
          ></video>
          <button
            class="btn btn-dark mt-2 me-2"
            style="transform: rotate(180deg);position:absolute;top:0;right:0;z-index:1000;"
            onClick={toggleRemoteControl}
          >
            <i class="bi bi-building"></i>
          </button>
        </div>
        <Show when={remoteControlVisible()}>
          <div class="d-flex flex-column ps-3">
            <select
              class="form-select mb-3"
              onChange={(e) => handleRemoteSelected(e.target.value)}
            >
              {availableRemotes().map((remote, index) => (
                <option value={remote.getId()} selected={index === 0}>
                  {remote.getTitle()}
                </option>
              ))}
            </select>
            <RemoteControl
              onCommand={handleRemoteButtonPressed}
              remote={selectedRemote()}
            />
          </div>
        </Show>
      </div>
    </div>
  );
}

IntegrationView.setIntegration = setIntegration;
export default IntegrationView;
