import { createMemo, createResource, createSignal, onMount } from "solid-js";
import ValidatedTextInput from "../components/validated-text-input.jsx";
import RemotesService from "../services/remotes-service.js";
import EventEmitter from "../tools/event-emitter.js";
import ModalHandler from "./modal-handler.js";
import Modal from "./modal.jsx";
import ListManager from "../components/list-manager.jsx";
import Remote from "../data/remote.js";

const eventEmitter = new EventEmitter();
const REMOTE_CREATED_EVENT = "success";
const MIN_TITLE_LENGTH = 3;
const modalHandler = new ModalHandler();

function CreateRemoteModal(props) {
  const [title, setTitle] = createSignal("");
  const [commands, setCommands] = createSignal([]);
  const [availableCommands, { refetch: refetchAvailableCommands }] =
    createResource(RemotesService.getCommands);
  const [error, setError] = createSignal("");

  const isTitleValid = createMemo(() => title().length >= MIN_TITLE_LENGTH);
  const isFormValid = createMemo(() => isTitleValid());

  modalHandler.onShow(() => {
    refetchAvailableCommands();
  });

  async function handleCreateRemote() {
    let remote;
    try {
      remote = await RemotesService.createRemote(
        new Remote({
          title: title(),
          commands: commands(),
        })
      );
    } catch (e) {
      setError(e.message);
      console.error(e);
      return;
    }
    resetFields();
    CreateRemoteModal.Handler.hide();
    eventEmitter.dispatchEvent(REMOTE_CREATED_EVENT, remote);
  }

  function resetFields() {
    setTitle("");
    setCommands([]);
    setError("");
  }

  function handleCommandSelect(item) {
    setCommands([...commands(), item]);
  }

  function handleCommandDeselect(item) {
    setCommands(
      commands().filter((command) => command.getId() !== item.getId())
    );
  }

  return (
    <Modal
      ref={props.ref}
      id="createRemoteModal"
      modalTitle="New Remote"
      centered={true}
    >
      <div class="modal-body bg-body-tertiary">
        <Show when={error() !== ""}>
          <div class="alert alert-danger" role="alert">
            {error()}
          </div>
        </Show>
        <div class="mb-3 row">
          <label for="new_remote_title" class="col-form-label col-sm-1">
            Title
          </label>
          <ValidatedTextInput
            class="col-sm-11"
            id="new_remote_title"
            valid={isTitleValid()}
            value={title()}
            onInput={(e) => setTitle(e.target.value)}
            errorText={`Title must be at least ${MIN_TITLE_LENGTH} characters long`}
          />
        </div>
        <ListManager
          style="height: 20em;"
          items={commands()}
          availableItems={availableCommands()}
          itemToString={(command) =>
            `${command.getTitle()} (${command.getProtocol()}:${command.getCommandType()})`
          }
          onItemSelect={handleCommandSelect}
          onItemDeselect={handleCommandDeselect}
          itemsTitle="Selected Commands"
          availableItemsTitle="Available Commands"
        />
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
          Cancel
        </button>
        <button
          type="button"
          onClick={handleCreateRemote}
          class="btn btn-primary"
          disabled={!isFormValid()}
        >
          Create
        </button>
      </div>
    </Modal>
  );
}

CreateRemoteModal.Handler = modalHandler;
CreateRemoteModal.onRemoteCreated = (callback) =>
  eventEmitter.on(REMOTE_CREATED_EVENT, callback);

export default CreateRemoteModal;
