<script lang="ts">
import { defineComponent } from 'vue';
import {
  DEFAULT_FOCUS_TRAP_OPTS,
  useBasicSetupFocusTrap,
  getFirstFocusableElement,
  useWatcherBasedSetupFocusTrapWithDestroyIncluded
} from '@shell/composables/focusTrap';

export const DEFAULT_ITERABLE_NODE_SELECTOR = 'body;';

export default defineComponent({
  name: 'AppModal',

  emits: ['close'],

  inheritAttrs: false,
  props:        {
    /**
     * If set to false, it will not be possible to close modal by clicking on
     * the background or by pressing Esc key.
     */
    clickToClose: {
      type:    Boolean,
      default: true,
    },
    /**
     * Width in pixels or percents (50, "50px", "50%").
     *
     * Supported string values are <number>% and <number>px
     */
    width: {
      type:    [Number, String],
      default: 610,
      validator(value) {
        if (typeof value === 'number') {
          return value > 0;
        }

        if (typeof value === 'string') {
          return /^(0*(?:[1-9][0-9]*|0)\.?\d*)+(px|%)$/.test(value);
        }

        return false;
      }
    },
    /**
     * List of class that will be applied to the modal window
     */
    customClass: {
      type:    String,
      default: '',
    },
    /**
     * Style that will be applied to the modal window
     */
    styles: {
      type:    String,
      default: '',
    },
    /**
     * Name of the modal
     */
    name: {
      type:    String,
      default: '',
    },
    /**
     * trigger focus trap
     */
    triggerFocusTrap: {
      type:    Boolean,
      default: false,
    },
    /**
     * forcefully set return focus element based on this selector
     */
    returnFocusSelector: {
      type:    String,
      default: '',
    },
    /**
     * will return focus to the first iterable node of this container select
     */
    returnFocusFirstIterableNodeSelector: {
      type:    String,
      default: DEFAULT_ITERABLE_NODE_SELECTOR,
    },
    /**
     * trigger focus trap - but watcher based
     */
    triggerFocusTrapWatcherBased: {
      type:    Boolean,
      default: false,
    },
    /**
     * watcher-based focus trap variable to watch
     */
    focusTrapWatcherBasedVariable: {
      type:    Boolean,
      default: false,
    },
  },
  computed: {
    modalWidth(): string {
      if (this.isValidWidth(this.width)) {
        const uom = typeof (this.width) === 'number' ? 'px' : '';

        return `${ this.width }${ uom }`;
      }

      return '610px';
    },
    stylesPropToObj(): object {
      return this.styles.split(';')
        .map((line) => line.trim().split(':'))
        .reduce((lines, [key, val]) => {
          return {
            ...lines,
            [key]: val
          };
        }, { });
    },
    modalStyles(): object {
      return {
        width: this.modalWidth,
        ...this.stylesPropToObj,
      };
    },
  },
  setup(props) {
    if (props.triggerFocusTrap) {
      let opts:any = DEFAULT_FOCUS_TRAP_OPTS;

      // if we have a "returnFocusFirstIterableNodeSelector" on top of "returnFocusSelector"
      // then we will use "returnFocusFirstIterableNodeSelector" as a fallback of "returnFocusSelector"
      if (props.returnFocusFirstIterableNodeSelector && props.returnFocusFirstIterableNodeSelector !== DEFAULT_ITERABLE_NODE_SELECTOR && props.returnFocusSelector) {
        opts = {
          ...DEFAULT_FOCUS_TRAP_OPTS,
          setReturnFocus: () => {
            return document.querySelector(props.returnFocusSelector) ? props.returnFocusSelector : getFirstFocusableElement(document.querySelector(props.returnFocusFirstIterableNodeSelector));
          }
        };
      // otherwise, if we are sure of permanent existance of "returnFocusSelector"
      // we just return to that element
      } else if (props.returnFocusSelector) {
        opts = {
          ...DEFAULT_FOCUS_TRAP_OPTS,
          setReturnFocus: props.returnFocusSelector
        };
      }

      if (!props.triggerFocusTrapWatcherBased) {
        useBasicSetupFocusTrap('#modal-container-element', opts);
      }
    }
  },
  created() {
    // This usecase is to cover the PromptModal scenario where it's renders a generic component inside.
    // Due to the architecture of the PromptModal it needs to be handled with a watcher based focus trap
    // but with a dedicated unmount hook
    if (this.triggerFocusTrapWatcherBased) {
      const opts:any = DEFAULT_FOCUS_TRAP_OPTS;

      useWatcherBasedSetupFocusTrapWithDestroyIncluded(() => this.focusTrapWatcherBasedVariable, '#modal-container-element', opts, true);
    }
  },
  mounted() {
    document.addEventListener('keydown', this.handleEscapeKey);
  },
  beforeUnmount() {
    document.removeEventListener('keydown', this.handleEscapeKey);
  },
  methods: {
    handleClickOutside(event: MouseEvent) {
      if (
        this.clickToClose &&
        this.$refs.modalRef &&
        !(this.$refs.modalRef as HTMLElement).contains(event.target as Node)
      ) {
        this.$emit('close');
      }
    },
    close(event: MouseEvent) {
      console.log('close');
      
      if (
        this.$refs.modalRef
      ) {
        console.log('clickcolse');
        
        this.$emit('close');
      }
      // this.$emit('close');
    },
    handleEscapeKey(event: KeyboardEvent) {
      if (this.clickToClose && event.key === 'Escape') {
        this.$emit('close');
      }
    },
    isValidWidth(value: number | string) {
      if (typeof value === 'number') {
        return value > 0;
      }

      if (typeof value === 'string') {
        return /^(0*(?:[1-9][0-9]*|0)\.?\d*)+(px|%)$/.test(value);
      }

      return false;
    }
  }
});
</script>

<template>
  <teleport to="#modals">
    <transition
      name="modal-fade"
      appear
    >
      <div
        class="modal-overlay"
        :data-modal="name"
        @click="handleClickOutside"
      >
        <div
          v-bind="$attrs"
          id="modal-container-element"
          ref="modalRef"
          :class="customClass"
          class="modal-container"
          :style="modalStyles"
          @click.stop
        >
        <div
            class="close-dailog-icon"
          >
            <button
              class="btn btn-sm role-link hide-bar"
              @click="close"
            >
              <i class="icon icon-x" />
            </button>
          </div>
        <div>
          <slot><!--Empty content--></slot>
        </div>
        </div>
      </div>
    </transition>
  </teleport>
</template>

<style lang="scss">
  .modal-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    /* background-color: var(--overlay-bg); */
    background-color: var(--overlay-model-bg);
    display: flex;
    justify-content: center;
    align-items: center;
    /* z-index: z-index('modalOverlay'); */
    z-index: 50;

    .modal-container {
      background-color: var(--modal-bg);
      border-radius: var(--border-radius);
      max-height: 95vh;
      overflow: auto;
      border: 0px;
      position: relative;
    }
  }

  .modal-fade-enter-active,
  .modal-fade-leave-active {
    transition: opacity 200ms;
  }

  .modal-fade-enter,
  .modal-fade-leave-to {
    opacity: 0;
  }
  .hide-bar{
    width: 32px;
    min-width: 32px !important;
  }
  .close-dailog-icon{
    position: absolute;
    right: 13px;
    top: 18px;
    & > button{
      color:var(--body-text) !important;
      min-width: 32px !important;
      width: 32px !important;
      & > button:hover{
        color:var(--body-text) !important;
      }
    }

  }
</style>
