<template>
  <div class="size-row">
    <div class="size-col">
      <div
        :class="['size-label', { 'is-setting': getSettingFlag(SIZE_PROPERTY.Width) }]"
        @click="openSetting(SIZE_PROPERTY.Width, $event)"
      >
        <span>宽度</span>
      </div>
      <numeric-select
        :name="getProperty(SIZE_PROPERTY.Width).name"
        :numericalText="getProperty(SIZE_PROPERTY.Width).text"
        @update="updateStyle"
      />
    </div>
    <div class="size-col">
      <div
        :class="['size-label', { 'is-setting': getSettingFlag(SIZE_PROPERTY.Height) }]"
        @click="openSetting(SIZE_PROPERTY.Height, $event)"
      >
        <span>高度</span>
      </div>
      <numeric-select
        :name="getProperty(SIZE_PROPERTY.Height).name"
        :numericalText="getProperty(SIZE_PROPERTY.Height).text"
        @update="updateStyle"
      />
    </div>
  </div>
  <div class="size-row">
    <div class="size-col">
      <div
        :class="['size-label', { 'is-setting': getSettingFlag(SIZE_PROPERTY.MinWidth) }]"
        @click="openSetting(SIZE_PROPERTY.MinWidth, $event)"
      >
        <span>最小宽</span>
      </div>
      <numeric-select
        :name="getProperty(SIZE_PROPERTY.MinWidth).name"
        :numericalText="getProperty(SIZE_PROPERTY.MinWidth).text"
        @update="updateStyle"
      />
    </div>
    <div class="size-col">
      <div
        :class="['size-label', { 'is-setting': getSettingFlag(SIZE_PROPERTY.MinHeight) }]"
        @click="openSetting(SIZE_PROPERTY.MinHeight, $event)"
      >
        <span>最小高</span>
      </div>
      <numeric-select
        :name="getProperty(SIZE_PROPERTY.MinHeight).name"
        :numericalText="getProperty(SIZE_PROPERTY.MinHeight).text"
        @update="updateStyle"
      />
    </div>
  </div>
  <div class="size-row">
    <div class="size-col">
      <div
        :class="['size-label', { 'is-setting': getSettingFlag(SIZE_PROPERTY.MaxWidth) }]"
        @click="openSetting(SIZE_PROPERTY.MaxWidth, $event)"
      >
        <span>最大宽</span>
      </div>
      <numeric-select
        :name="getProperty(SIZE_PROPERTY.MaxWidth).name"
        :numericalText="getProperty(SIZE_PROPERTY.MaxWidth).text"
        @update="updateStyle"
      />
    </div>
    <div class="size-col">
      <div
        :class="['size-label', { 'is-setting': getSettingFlag(SIZE_PROPERTY.MaxHeight) }]"
        @click="openSetting(SIZE_PROPERTY.MaxHeight, $event)"
      >
        <span>最大高</span>
      </div>
      <numeric-select
        :name="getProperty(SIZE_PROPERTY.MaxHeight).name"
        :numericalText="getProperty(SIZE_PROPERTY.MaxHeight).text"
        @update="updateStyle"
      />
    </div>
  </div>

  <div class="overflow-row">
    <div
      :class="[
        'overflow-label',
        { 'is-setting': getSettingFlag(SIZE_PROPERTY.Overflow), selected: Boolean(selectedOverflow) }
      ]"
      @click="openSetting(SIZE_PROPERTY.Overflow, $event)"
    >
      <span>溢出</span>
    </div>
    <tabs-group-configurator
      :options="overflowOpt"
      :modelValue="selectedOverflow"
      :label-width="50"
      :effect="effect"
      :placement="placement"
      @update:modelValue="selectOverflow"
    ></tabs-group-configurator>
  </div>

  <div class="fit-row">
    <div
      :class="[
        'fit-label',
        { 'is-setting': getSettingFlag(SIZE_PROPERTY.ObjectFit), selected: state.value !== 'object-fit:fill' }
      ]"
      title="object-fit"
      @click="openSetting(SIZE_PROPERTY.ObjectFit, $event)"
    >
      <span>适应</span>
    </div>
    <div class="fit-select">
      <select-configurator
        :modelValue="state.value"
        :options="selectOptions"
        @update:modelValue="selectFit"
      ></select-configurator>
    </div>
    <tiny-tooltip :effect="effect" :disabled="state.disabled" :placement="placement" content="Object position 设置">
      <tiny-popover
        placement="bottom"
        popper-class="toolbar-media-popper fit-popper"
        @show="showPopover"
        @hide="hidePopover"
      >
        <template #reference>
          <span
            :class="[
              'more-icon-wrap',
              { selected: state.flag, 'is-setting': getSettingFlag(SIZE_PROPERTY.ObjectPosition) }
            ]"
          >
            <icon-ellipsis></icon-ellipsis>
          </span>
        </template>
        <div class="size-fit-content">
          <div
            :class="['fit-content-label', { 'is-setting': getSettingFlag(SIZE_PROPERTY.ObjectPosition) }]"
            @click="openSetting(SIZE_PROPERTY.ObjectPosition, $event)"
          >
            位置
          </div>
          <div class="size-fit-content-main">
            <div class="coordinate">
              <div
                v-for="(item, index) in originOptions"
                :key="index"
                :class="['coordinate-origin', { selected: state.originActive === index }]"
                @click="selectOrigin(item, index)"
              >
                <svg-icon v-if="state.originActive !== index" :name="item.pointIcon"></svg-icon>
                <svg-icon v-else :name="item.originIcon"></svg-icon>
              </div>
            </div>
            <div class="size-input-wrap">
              <div class="input-wrap-row">
                <span class="size-label">Left</span>
                <tiny-input v-model="state.leftValue" class="left-input" @change="leftValueChange">
                  <template #suffix>
                    <span>%</span>
                  </template>
                </tiny-input>
              </div>
              <div class="input-wrap-row">
                <span class="size-label">Top</span>
                <tiny-input v-model="state.topValue" class="top-input" @change="topValueChange">
                  <template #suffix>
                    <span>%</span>
                  </template>
                </tiny-input>
              </div>
            </div>
          </div>
        </div>
      </tiny-popover>
    </tiny-tooltip>
  </div>

  <modal-mask v-if="showModal" @close="showModal = false">
    <reset-button @reset="reset" />
  </modal-mask>
  <mask-modal :visible="state.showMask" @close="state.showMask = false"></mask-modal>
</template>

<script>
/* metaService: engine.setting.styles.SizeGroup */
import { reactive, ref, computed } from 'vue'
import { Tooltip, Popover, Input } from '@opentiny/vue'
import { MaskModal } from '@opentiny/tiny-engine-common'
import { SelectConfigurator, TabsGroupConfigurator } from '@opentiny/tiny-engine-configurator'
import { iconEllipsis } from '@opentiny/vue-icon'
import ModalMask, { useModal } from '../inputs/ModalMask.vue'
import ResetButton from '../inputs/ResetButton.vue'
import NumericSelect from '../inputs/NumericSelect.vue'
import useEvent from '../../js/useEvent'
import { useProperties } from '../../js/useStyle'
import { OVERFLOW_TYPE } from '../../js/cssType'
import { SIZE_PROPERTY } from '../../js/styleProperty'

export default {
  components: {
    ModalMask,
    ResetButton,
    NumericSelect,
    SelectConfigurator,
    TabsGroupConfigurator,
    MaskModal,
    TinyPopover: Popover,
    TinyInput: Input,
    TinyTooltip: Tooltip,
    IconEllipsis: iconEllipsis()
  },
  props: {
    style: {
      type: Object,
      default: () => ({})
    },
    effect: {
      type: String,
      default: 'light'
    },
    placement: {
      type: String,
      default: 'top'
    }
  },
  emits: useEvent(),
  setup(props, { emit }) {
    let activedName = ''
    const selectOptions = [
      {
        label: 'fill-填充',
        value: 'object-fit:fill'
      },
      {
        label: 'contain-包含',
        value: 'object-fit:contain'
      },
      {
        label: 'cover-原比例填充',
        value: 'object-fit:cover'
      },
      {
        label: 'none-无',
        value: 'object-fit:none'
      },
      {
        label: 'scale-down-缩小',
        value: 'object-fit:scale-down'
      }
    ]
    const originOptions = [
      {
        pointIcon: 'transform-origin-point',
        originIcon: 'transform-origin-top-left',
        left: '0',
        top: '0'
      },
      {
        pointIcon: 'transform-origin-point',
        originIcon: 'transform-origin-top',
        left: '50',
        top: '0'
      },
      {
        pointIcon: 'transform-origin-point',
        originIcon: 'transform-origin-top-right',
        left: '100',
        top: '0'
      },
      {
        pointIcon: 'transform-origin-point',
        originIcon: 'transform-origin-left',
        left: '0',
        top: '50'
      },
      {
        pointIcon: 'transform-origin-point',
        originIcon: 'transform-origin-center',
        left: '50',
        top: '50'
      },
      {
        pointIcon: 'transform-origin-point',
        originIcon: 'transform-origin-right',
        left: '100',
        top: '50'
      },
      {
        pointIcon: 'transform-origin-point',
        originIcon: 'transform-origin-bottom-left',
        left: '0',
        top: '100'
      },
      {
        pointIcon: 'transform-origin-point',
        originIcon: 'transform-origin-bottom',
        left: '50',
        top: '100'
      },
      {
        pointIcon: 'transform-origin-point',
        originIcon: 'transform-origin-bottom-right',
        left: '100',
        top: '100'
      }
    ]
    const overflowOpt = [
      {
        icon: 'eye',
        content: 'visible 溢出可见',
        value: OVERFLOW_TYPE.Visible
      },
      {
        icon: 'eye-invisible',
        content: 'hidden 溢出隐藏',
        value: OVERFLOW_TYPE.Hidden
      },
      {
        icon: 'overflow-scroll',
        content: 'overflow 溢出滚动',
        value: OVERFLOW_TYPE.Scroll
      },
      {
        label: 'Auto',
        content: 'auto 溢出才自动滚动',
        value: OVERFLOW_TYPE.Auto
      }
    ]
    const showModal = ref(false)
    const { setPosition } = useModal()
    const state = reactive({
      flag: false,
      disabled: false,
      showMask: false,
      value: 'object-fit:fill',
      leftValue: '50',
      topValue: '50',
      originActive: 4
    })

    const { getProperty, getSettingFlag, getPropertyValue } = useProperties({
      names: Object.values(SIZE_PROPERTY),
      parseNumber: true
    })

    const selectedOverflow = computed(() => {
      return getPropertyValue(SIZE_PROPERTY.Overflow)
    })

    const updateStyle = (property) => {
      emit('update', property)
    }

    const reset = () => {
      updateStyle({ [activedName]: null })
      state.value = 'object-fit:fill'
      state.topValue = '50'
      state.leftValue = '50'
      state.originActive = 4
      showModal.value = false
    }

    const updatePositionStyle = () => {
      const styleObj = { 'object-position': `${state.leftValue}% ${state.topValue}%` }
      updateStyle(styleObj)
    }

    const openSetting = (name, event) => {
      if (getSettingFlag(name)) {
        activedName = name
        setPosition(event)
        showModal.value = true
      }
    }

    const selectOverflow = (type) => {
      if (type) {
        updateStyle({ overflow: type })
      }
    }

    const showPopover = () => {
      state.flag = true
      state.disabled = true
      state.showMask = true
    }

    const hidePopover = () => {
      state.flag = false
      state.disabled = false
      state.showMask = false
    }

    const selectOrigin = (item, index) => {
      state.originActive = index
      state.topValue = item.top
      state.leftValue = item.left
      updatePositionStyle()
    }

    const selectFit = (val) => {
      if (val?.includes(':')) {
        const styleArr = val.split(':')
        state.value = val
        updateStyle({ [styleArr[0]]: styleArr[1] })
      }
    }

    const leftValueChange = (val) => {
      state.leftValue = val
      updatePositionStyle()
    }

    const topValueChange = (val) => {
      state.topValue = val
      updatePositionStyle()
    }

    return {
      state,
      OVERFLOW_TYPE,
      SIZE_PROPERTY,
      selectOptions,
      originOptions,
      overflowOpt,
      selectedOverflow,
      reset,
      showModal,
      updateStyle,
      openSetting,
      getProperty,
      getSettingFlag,
      selectOverflow,
      showPopover,
      hidePopover,
      selectOrigin,
      selectFit,
      leftValueChange,
      topValueChange
    }
  }
}
</script>

<style lang="less" scoped>
span {
  padding: 2px;
}
.size-row {
  display: flex;
  margin-bottom: var(--te-common-vertical-item-spacing-normal);
  &:last-child {
    margin-bottom: 0;
  }
  .size-col {
    flex: 1;
    display: flex;
    align-items: center;
    &:not(:last-child) {
      margin-right: 8px;
    }

    .size-label {
      flex: 0 0 52px;
      margin-right: 2px;
      line-height: 28px;
      color: var(--te-styles-common-text-color-secondary);
    }
  }
}

.overflow-row {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  &:last-child {
    margin-bottom: 0;
  }
  .overflow-label {
    flex: 0 0 54px;
    line-height: 24px;
    color: var(--te-styles-common-text-color-secondary);
  }
}

.selected-label {
  cursor: pointer;
  border-radius: 2px;
  color: var(--te-styles-common-setting-text-color);
  background-color: var(--te-styles-common-setting-bg-color);
}

.is-setting {
  span {
    .selected-label();
  }
}

.size-fit-content {
  display: block;
  width: 180px;
  .fit-content-label {
    margin-bottom: 10px;
  }
  .size-fit-content-main {
    place-items: start center;
    height: 68px;
    display: grid;
    gap: 4px 8px;
    grid-template-columns: auto auto;
    grid-template-rows: 1fr 3fr;

    .coordinate {
      grid-column-start: 1;
      grid-row: 1 / span 3;
      width: 68px;
      height: 68px;
      background: var(--te-styles-common-bg-color);
      display: inline-grid;
      overflow: hidden;
      justify-items: center;
      border-width: 1px;
      box-sizing: border-box;
      border-style: solid;
      border-color: var(--te-styles-common-border-color);
      border-radius: 4px;
      gap: 0px;
      grid-template-columns: 1fr 1fr 1fr;
      grid-template-rows: 1fr 1fr 1fr;
    }
    .coordinate-origin {
      background-color: var(--te-styles-common-bg-color);
      transition: color 0.1s ease 0s;
      color: var(--te-styles-common-icon-color);
      font-size: 14px;
      &:hover,
      &.selected {
        color: var(--te-styles-background-icon-color-primary);
      }
    }
    .size-input-wrap {
      flex: 1;
      .input-wrap-row {
        display: flex;
        align-items: center;
        margin-bottom: 5px;
        .size-label {
          padding-right: 5px;
          display: inline-block;
          color: var(--te-styles-common-text-color-secondary);
        }

        :deep(.tiny-input) {
          flex: 1;
        }
      }
    }
  }
}

.fit-row {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  &:last-child {
    margin-bottom: 0;
  }
  .fit-label {
    flex: 0 0 54px;
    line-height: 28px;
    color: var(--te-styles-common-text-color-secondary);
    span {
      padding: 2px;
    }
    &.selected {
      span {
        .selected-label();
      }
    }
  }
  .more-icon-wrap {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 20px;
    height: 20px;
    font-size: 18px;
    color: var(--te-styles-common-text-color-secondary);
    margin-left: 4px;
    border-radius: 2px;
    &.selected {
      background: var(--te-styles-common-bg-color-active);
      &.is-setting {
        .selected-label();
      }
    }
  }
}
</style>