import { createEffect, createMemo, mergeProps } from "solid-js";
import Remote from "../data/remote";
import Command from "../data/command";

function RemoteControl(props) {
  props = mergeProps(
    {
      remote: new Remote(),
      onCommand: () => {},
    },
    props
  );

  const BUTTON_SIZE_REGULAR = "regular";
  const BUTTON_SIZE_SMALL = "small";

  const BUTTON_HEIGHT = 2;
  const BUTTON_WIDTH = BUTTON_HEIGHT * 1.4;
  const SMALL_BUTTON_HEIGHT = 1.5;
  const SMALL_BUTTON_WIDTH = SMALL_BUTTON_HEIGHT * 1.3334;
  const TYPES = Command.TYPES;

  const commandMap = createMemo(() =>
    props.remote
      .getCommands()
      .reduce(
        (map, command) => ({ ...map, [command.getCommandType()]: command }),
        {}
      )
  );

  let layout = [
    [TYPES.POWER, null, TYPES.INPUT],
    [TYPES.ONE, TYPES.TWO, TYPES.THREE],
    [TYPES.FOUR, TYPES.FIVE, TYPES.SIX],
    [TYPES.SEVEN, TYPES.EIGHT, TYPES.NINE],
    [TYPES.VOLUME_UP, TYPES.ZERO, TYPES.CHANNEL_UP],
    [TYPES.VOLUME_DOWN, TYPES.MUTE, TYPES.CHANNEL_DOWN],
    [TYPES.MENU, TYPES.HOME, TYPES.SETTINGS],
    [TYPES.OPTIONS, TYPES.UP, TYPES.INFO],
    [TYPES.LEFT, TYPES.ENTER, TYPES.RIGHT],
    [TYPES.RETURN, TYPES.DOWN, TYPES.EXIT],
    [TYPES.RED, TYPES.GREEN, TYPES.YELLOW, TYPES.BLUE],
    [TYPES.PLAY, TYPES.PAUSE, TYPES.STOP],
    [TYPES.REWIND, null, TYPES.FORWARD],
  ];

  function toButtonProps(type) {
    let mapping = {
      [TYPES.POWER]: () => ({ icon: "bi-power", text: "" }),
      [TYPES.INPUT]: () => ({ icon: "bi-box-arrow-in-right", text: "" }),
      [TYPES.VOLUME_UP]: () => ({ icon: "bi-volume-up", text: "" }),
      [TYPES.VOLUME_DOWN]: () => ({ icon: "bi-volume-down", text: "" }),
      [TYPES.MUTE]: () => ({ icon: "bi-volume-mute", text: "" }),
      [TYPES.CHANNEL_UP]: () => ({ icon: "bi-chevron-up", text: "" }),
      [TYPES.CHANNEL_DOWN]: () => ({ icon: "bi-chevron-down", text: "" }),
      [TYPES.HOME]: () => ({ icon: "bi-house-door", text: "" }),
      [TYPES.SETTINGS]: () => ({ icon: "bi-gear", text: "" }),
      [TYPES.INFO]: () => ({ icon: "bi-info-circle", text: "" }),
      [TYPES.UP]: () => ({ icon: "bi-arrow-up", text: "" }),
      [TYPES.DOWN]: () => ({ icon: "bi-arrow-down", text: "" }),
      [TYPES.LEFT]: () => ({ icon: "bi-arrow-left", text: "" }),
      [TYPES.RIGHT]: () => ({ icon: "bi-arrow-right", text: "" }),
      [TYPES.ENTER]: () => ({ icon: "", text: "OK" }),
      [TYPES.EXIT]: () => ({ icon: "", text: "EXIT" }),
      [TYPES.OPTIONS]: () => ({ icon: "bi-list-task", text: "" }),
      [TYPES.RETURN]: () => ({ icon: "bi-arrow-return-left", text: "" }),
      [TYPES.ONE]: () => ({ icon: "", text: "1" }),
      [TYPES.TWO]: () => ({ icon: "", text: "2" }),
      [TYPES.THREE]: () => ({ icon: "", text: "3" }),
      [TYPES.FOUR]: () => ({ icon: "", text: "4" }),
      [TYPES.FIVE]: () => ({ icon: "", text: "5" }),
      [TYPES.SIX]: () => ({ icon: "", text: "6" }),
      [TYPES.SEVEN]: () => ({ icon: "", text: "7" }),
      [TYPES.EIGHT]: () => ({ icon: "", text: "8" }),
      [TYPES.NINE]: () => ({ icon: "", text: "9" }),
      [TYPES.ZERO]: () => ({ icon: "", text: "0" }),
      [TYPES.MENU]: () => ({ icon: "", text: "MENU" }),
      [TYPES.PLAY]: () => ({ icon: "bi-play", text: "" }),
      [TYPES.PAUSE]: () => ({ icon: "bi-pause", text: "" }),
      [TYPES.STOP]: () => ({ icon: "bi-stop", text: "" }),
      [TYPES.REWIND]: () => ({ icon: "bi-rewind", text: "" }),
      [TYPES.FORWARD]: () => ({ icon: "bi-fast-forward", text: "" }),
      [TYPES.RED]: () => ({
        class: "bg-danger",
        buttonSize: BUTTON_SIZE_SMALL,
      }),
      [TYPES.GREEN]: () => ({
        class: "bg-success",
        buttonSize: BUTTON_SIZE_SMALL,
      }),
      [TYPES.YELLOW]: () => ({
        class: "bg-warning",
        buttonSize: BUTTON_SIZE_SMALL,
      }),
      [TYPES.BLUE]: () => ({
        class: "bg-primary",
        buttonSize: BUTTON_SIZE_SMALL,
      }),
    };

    if (!(type in mapping)) return {};
    let props = mapping[type]();
    props.type = type;
    props.text = props.text || "";
    return props;
  }

  function PlaceholderButton() {
    return (
      <div
        style={`width: ${BUTTON_WIDTH}em; height: ${BUTTON_HEIGHT}em; margin: 0.2em;`}
      ></div>
    );
  }

  function RemoteButton(props) {
    props = mergeProps(
      {
        onClick: () => {},
        disabled: false,
        class: "",
        buttonSize: BUTTON_SIZE_REGULAR,
        icon: "",
        text: "",
      },
      props
    );

    let buttonWidth = BUTTON_WIDTH;
    let buttonHeight = BUTTON_HEIGHT;
    if (props.buttonSize === BUTTON_SIZE_SMALL) {
      buttonWidth = SMALL_BUTTON_WIDTH;
      buttonHeight = SMALL_BUTTON_HEIGHT;
    }
    let buttonFontSize = buttonHeight * 0.4;
    let iconSize = buttonHeight * 0.5;
    return (
      <button
        class={
          "btn btn-dark d-flex justify-content-center align-items-center " +
          props.class
        }
        style={`width: ${buttonWidth}em; height: ${buttonHeight}em; margin: 0.2em;`}
        onClick={props.onClick}
        disabled={props.disabled}
      >
        <i style={`font-size: ${iconSize}em;`} class={"bi " + props.icon} />
        <span style={`font-size: ${buttonFontSize}em;`}>{props.text}</span>
      </button>
    );
  }

  return (
    <div class="d-flex flex-column justify-content-center align-items-center p-1 bg-secondary rounded">
      {layout.map((row) => (
        <div class="d-flex flex-row justify-content-center align-items-center">
          {row
            .map(toButtonProps)
            .map(({ type, class: className, buttonSize, icon, text }) =>
              !type ? (
                <PlaceholderButton />
              ) : (
                <RemoteButton
                  class={className}
                  buttonSize={buttonSize}
                  onClick={() => props.onCommand(commandMap()[type])}
                  disabled={!commandMap()[type]}
                  icon={icon}
                  text={text}
                />
              )
            )}
        </div>
      ))}
    </div>
  );
}

export default RemoteControl;
