<template>
  <main class="ssml-app">
    <!-- <span style="font-size:10px;border-radius:4px;background:#ccc" @click="logStore">Log Store</span> -->

    <or-modal
      ref="ssmlEditorModal"
      :size="'large'"
      :dismissible="false"
      remove-header
      @open="onModalOpen"
      @close="onModalClose"
    >
      <div class="modal-header">
        <span class="modal-header__title">Customize speech</span>
        <or-button
          icon="close"
          type="secondary"
          color="black"
          disableRipple
          @click="closeModalCancel"
        />
      </div>
      <or-tabs
        ref="appModeTabs"
        class="flex-box"
        fullwidth
        @tab-change="changeAppModeTab"
      >
        <or-tab id="visualEditor" title="Speech editor">
          <app-visual-editor
            :steps="steps"
            :step-id="stepId"
            :merge-fields="mergeFields"
          />
        </or-tab>

        <or-tab id="codeEditor" title="Code mode">
          <app-code-editor
            :steps="steps"
            :step-id="stepId"
            :merge-fields="mergeFields"
          />
        </or-tab>
      </or-tabs>

      <div slot="footer">
        <or-button type="secondary" color="primary" @click="closeModalCancel">
          Cancel
        </or-button>
        <or-button color="primary" @click="closeModalSave"> Save </or-button>
      </div>
    </or-modal>

    <preview-block-module
      :minimalistic="minimalisticPreview"
      :emptyMessage="emptyMessage"
      :merge-fields="mergeFields"
      :readonly="readonly"
      :invalid="invalid"
    />

    <!-- <or-alert
      v-if="invalid"
      type="error"
      :dismissible="false"
      class="error-text"
    >
      {{ error ? error : "Either text or audio message is required." }}
    </or-alert> -->

    <or-button
      type="secondary"
      color="primary"
      class="open-editor-btn"
      :disabled="customizeDisabled"
      @click="openModal"
    >
      Customize speech
    </or-button>
    <span
      v-if="customizationUnsupported && !readonly"
      class="customize-disable-tooltip"
      >{{ customizeBtnTooltip }}</span
    >
  </main>
</template>

<script>
import Vue from "vue";
import { getEnv } from "./utils/env.js";
import AppVisualEditor from "./App-VisualEditor.vue";
import AppCodeEditor from "./App-CodeEditor.vue";
import PreviewBlockModule from "./modules/preview-block-module/index.vue";
import liteStore from "./store/liteStore.js";
import AppStore from "./modules/app-module/_store/index.js";
import EnvModuleStore from "./modules/env-module/_store/index.js";
import EditableModuleStore from "./modules/editable-module/_store/index.js";
import CodeEditableModuleStore from "./modules/code-editable-module/_store/index.js";
import TagDetailsModuleStore from "./modules/tag-details-module/_store/index.js";
import TagListModuleStore from "./modules/tag-list-module/_store/index.js";
import SelectionModuleStore from "./modules/selection-module/_store/index.js";
import MergeFieldsReplacerModuleStore from "./modules/merge-fields-replacer-module/_store/index.js";

export default {
  components: {
    AppVisualEditor,
    AppCodeEditor,
    PreviewBlockModule,
  },

  props: {
    propLanguage: { type: String, default: "en-US" },
    propProvider: { type: String, default: "polly" },
    propEngine: { type: String, default: "standard" },
    propGender: { type: String, default: "female" },
    propVoice: { type: String, default: "Joanna" },
    propMode: { type: String, default: "visualEditor" },
    propCode: { type: String, default: "" },
    propJson: { type: Array, default: () => [] },
    minimalisticPreview: { type: Boolean, default: true },
    emptyMessage: { type: String, default: "" },
    stepId: { type: String, default: "" },
    steps: { type: Array, default: () => [] },
    mergeFields: { type: Array, default: () => [] },
    readonly: { type: Boolean, default: false },
    isCacheOn: { type: Boolean, default: true },
    tagListCache: { type: Object, default: () => ({}) },
    invalid: { type: Boolean, default: false },
    error: { type: String, default: "" },
  },

  data() {
    return {
      appMode: "visualEditor",
    };
  },

  computed: {
    currentProvider() {
      return this.$liteStore.get("app/provider");
    },
    customizationUnsupported() {
      return _.includes(["elevenlabs", "wellsaid", "openai", "unrealspeech"], this.currentProvider.toLowerCase());
    },
    customizeDisabled() {
      return this.readonly || this.customizationUnsupported;
    },
    customizeBtnTooltip() {
      return this.customizationUnsupported
        ? `Text customization is not supported by ${_.upperFirst(
            this.currentProvider
          )} provider`
        : "";
    },
  },

  watch: {
    isCacheOn(value) {
      this.$liteStore.dispatch("tagList/isCacheOn", value);
    },

    propLanguage(value) {
      this.$liteStore.dispatch("app/saveLanguage", value);
    },

    propProvider(value) {
      this.$liteStore.dispatch("app/saveProvider", value);
    },

    propEngine(value) {
      this.$liteStore.dispatch("app/saveEngine", value);
    },

    propGender(value) {
      this.$liteStore.dispatch("app/saveGender", value);
    },

    propVoice(value) {
      this.$liteStore.dispatch("app/saveVoice", value);
    },
  },

  created() {
    this.initAppMode();
    this.setAppModeTabs();

    this.registerEventBus();
    this.setSchemaUpdateEventEmmiters();

    this.registerStore();
    this.setAppEnv();
    this.saveAppPropsToStore();

    this.$liteStore.dispatch("tagList/setTagsConfig", this.tagListCache);
  },

  mounted() {
    this.$liteStore.dispatch("selection/initSelection");
    this.$liteStore.dispatch("editable/setEditableAreaInitContent");
    this.$liteStore.dispatch("editable/setEditableAreaTmpContent");
  },

  methods: {
    onDestroy() {
      delete this.$root[`liteStore-${this._liteStoreUUID}`];
      delete this.$root[`EventBus-${this._EventBusUUID}`];
    },

    logStore() {
      console.log("STORE", this.$liteStore.get("app/state"));
    },

    setSchemaUpdateEventEmmiters() {
      this.$EventBus.$on("schema-update::code", (value) => {
        this.$emit("schema-update::code", value);
      });
      this.$EventBus.$on("schema-update::json", (value) => {
        this.$emit("schema-update::json", value);
      });
      this.$EventBus.$on("schema-update::mode", (value) => {
        this.$emit("schema-update::mode", value);
      });

      this.$EventBus.$on("cache-update::taglist", (value) => {
        this.$emit("cache-update::taglist", value);
      });

      this.$EventBus.$on("get::mode", () => {
        this.$EventBus.$emit("set::mode", this.appMode);
      });
    },

    registerStore() {
      this.$root[`liteStore-${this._liteStoreUUID}`] = liteStore();

      this.$liteStore.registerModules([
        AppStore,
        SelectionModuleStore,
        EditableModuleStore,
        CodeEditableModuleStore,
        EnvModuleStore,
        TagDetailsModuleStore,
        TagListModuleStore,
        MergeFieldsReplacerModuleStore,
      ]);
    },

    registerEventBus() {
      this.$root[`EventBus-${this._EventBusUUID}`] = new Vue();
    },

    setAppEnv() {
      const env = getEnv(this);

      this.$liteStore.dispatch("env/saveEnv", {
        sdkApiUrl: env.sdkApiUrl,
        providersAccountId: env.providersAccountId(),
        token: env.token,
      });
    },

    saveAppPropsToStore() {
      this.$liteStore.dispatch("tagList/isCacheOn", this.isCacheOn);
      this.$liteStore.dispatch("app/saveLanguage", this.propLanguage);
      this.$liteStore.dispatch("app/saveProvider", this.propProvider);
      this.$liteStore.dispatch("app/saveEngine", this.propEngine);
      this.$liteStore.dispatch("app/saveGender", this.propGender);
      this.$liteStore.dispatch("app/saveVoice", this.propVoice);
      this.$liteStore.dispatch("app/saveReadonly", this.readonly);

      this.$liteStore.dispatch("editable/initContent", this.propJson);
      if (this.appMode === "codeEditor") {
        this.$liteStore.dispatch(
          "codeEditable/saveEditorContent",
          this.propCode
        );
      }
    },

    onModalOpen() {
      this.$liteStore.dispatch("app/saveModalState", true);
      this.$liteStore.dispatch("editable/setEditableAreaInitContent");
      this.$liteStore.dispatch("editable/setEditableAreaTmpContent");
    },

    onModalClose() {
      this.$liteStore.dispatch("app/saveModalState", false);
      this.$EventBus.$emit("modal-close", {});
      this.$liteStore.dispatch("editable/setEditableAreaInitContent");
      this.$liteStore.dispatch("editable/setEditableAreaTmpContent");
    },

    openModal() {
      this.$refs.ssmlEditorModal.open();
      this.setAppModeTabs();
    },

    clear() {
      this.$EventBus.$emit("editable-update::clear");
    },

    closeModalCancel() {
      this.$refs.ssmlEditorModal.close();
      this.appMode = this.propMode;

      this.$liteStore.dispatch("editable/clearEditableAreaTmpContent");
      this.$liteStore.dispatch(
        "codeEditable/saveEditorContent",
        this.appMode === "codeEditor" ? this.propCode : ""
      );
    },

    closeModalSave() {
      this.$EventBus.$emit("schema-update::mode", this.appMode);

      if (this.appMode === "visualEditor") {
        this.$EventBus.$emit("editable-update::save");
        this.$liteStore.dispatch("editable/saveSsml");

        this.$liteStore.dispatch("codeEditable/saveEditorContent", "");

        this.$EventBus.$emit(
          "schema-update::code",
          this.$liteStore.get("editable/ssmlCode")
        );
        this.$EventBus.$emit(
          "schema-update::json",
          _.cloneDeep(this.$liteStore.get("editable/editableContent"))
        );
      }

      if (this.appMode === "codeEditor") {
        let visualEditorContent = new DocumentFragment();
        this.$EventBus.$emit("editable-update::save", visualEditorContent);
        this.$liteStore.dispatch("editable/saveSsml");
        visualEditorContent = null;

        this.$EventBus.$emit(
          "schema-update::code",
          this.$liteStore.get("codeEditable/ssmlCode")
        );
        this.$EventBus.$emit("schema-update::json", []);
      }

      this.$refs.ssmlEditorModal.close();
    },

    changeAppModeTab(tabId) {
      this.appMode = tabId;
    },

    initAppMode() {
      this.appMode = this.propMode;
    },

    setAppModeTabs() {
      this.$nextTick(() => this.$refs.appModeTabs.setActiveTab(this.appMode));
    },
  },
};
</script>

<style lang="scss">
.ssml-app {
  padding-left: 20px;
  overflow: scroll;
  font-weight: normal;

  .builder & {
    padding-left: 0;
  }

  .modal-header {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-content: center;
    margin-top: 8px;
    margin-bottom: 18px;
    &__title {
      color: rgb(30, 35, 43);
      font-size: 18px;
      font-weight: bold;
    }
    .ui-button {
      border: none;
      border-radius: 50%;
      width: 30px;
      height: 30px;
      min-width: 0;
      min-height: 0;
      color: #1e232b;
    }
    .ui-button:hover {
      background-color: unset !important;
    }
  }

  .customize-disable-tooltip {
    display: block;
    margin-top: 12px;
    color: #91969d;
    font-size: 12px;
  }
}

.open-editor-btn {
  display: block;

  &.ui-button.ui-button--type-secondary.ui-button--color-primary {
    margin-bottom: 0;
  }
}

.ui-select__dropdown {
  z-index: 50;
}

#editable {
  -webkit-user-select: text;
  min-height: 202px;
  padding: 20px 16px;
  margin-bottom: 1rem;
  font-size: 14px;
  background-color: #fff;
  border: 1px solid rgb(223, 223, 223);
  border-radius: 4px;
  user-select: text;
}

.ssml-app .text-wrapper {
  position: relative;
  background-color: rgba(64, 159, 236, 0.2);
  border-radius: 4px;

  &::before {
    position: relative;
    top: -2px;
    left: -1px;
    display: inline-block;
    padding-right: 5px;
    padding-left: 5px;
    margin-right: 5px;
    font-size: 10px;
    line-height: 15px;
    color: #fff;
    background-color: #1e232b;
    content: attr(data-label);
    border-radius: 4px 0 0 4px;
  }

  &.active-tag,
  &[data-active-tag] {
    border: solid 1px #409fec;

    &::before {
      left: 0;
      background-color: #409fec;
      border: solid 1px #409fec;
      border-radius: 3px 0 0 3px;
    }
  }

  &.text-wrapper.merge-field,
  &.merge-field[data-active-tag] {
    background: none;
    border: none;
    color: #409fec;

    &::before {
      display: none;
      // position: static;
      // margin: 0;
      // font-size: inherit;
      // color: #409fec;
      // background: none;
      // border: none;
    }
  }

  &.text-wrapper--error {
    background-color: #da1e2833;
  }

  &.text-wrapper--error::before {
    background-color: #da1e28;
  }

  .text-wrapper {
    background-color: rgba(64, 159, 236, 0.3019607843);
  }
}

.ssml-app .text-wrapper--break::before {
  margin-right: 0;
  border-radius: 4px;
}

.ssml-app {
  .ui-modal {
    .ui-tabs {
      .ui-tab-header-item {
        text-transform: none;
      }

      &.flex-box > .ui-tabs__header {
        background: none;
        margin-bottom: 18px;
        &,
        .ui-tabs__header-items {
          padding-right: 0;
          padding-left: 0;
        }
      }
    }

    // & > .ui-modal__wrapper > .ui-modal__container {
    //   & > .ui-modal__body {
    //     padding: 0 2rem 1rem;
    //   }

    //   & > .ui-modal__footer {
    //     padding: 1rem 2rem;
    //   }
    // }
  }

  .ui-select .ui-select__content .ui-select__label .ui-select__label-text,
  .or-code .header .label-text {
    line-height: 24px;
  }

  .or-code {
    margin-bottom: 1rem;
  }

  .error-text {
    font-size: 14px;
    font-weight: normal;
    margin-bottom: 1rem;
  }
}
</style>
