<template>
  <div class="hot-styles">
    <div class="add item" v-if="!props.all && styles.length < maxLength">
      <span class="fun-ctrl">
        <ui-input 
          class="input" 
          preview 
          accept=".jpg, .jpeg, .png" 
          @update:modelValue="iconUpload" 
          type="file"
        >
          <template v-slot:replace>
            <ui-icon type="add" class="icon" />
          </template>
        </ui-input>
      </span>
    </div>
    <div 
      v-for="hotStyle in styleAll" 
      class="item" 
      :class="{ active: active === hotStyle }"
      @click="clickHandler(hotStyle)"
    >
      <span>
        <img :src="getFileUrl(hotStyle.icon)" />
        <ui-icon 
          v-if="!hotStyle.default"
          class="delete" 
          type="close" 
          @click.stop="emit('delete', hotStyle)" 
        />
      </span>
    </div>
    <div 
      v-if="!props.all && props.styles.length > maxShowLen"
      class="add item style-more" 
      @click="showAll = !showAll"
    >
      <span class="fun-ctrl">
        <ui-icon :type="showAll ? 'pull-up' : 'pull-down'" class="icon" />
        <ui-bubble 
          class="more-content" 
          :show="showAll" 
          @click.stop 
          type="bottom">
          
          <styles 
            :styles="styles.filter(style => !styleAll.includes(style))" 
            :active="active" 
            all
            @quitMore="showAll = false" 
            @uploadStyles="(style: TaggingStyle) => emit('uploadStyle', style)" 
            @change="clickHandler"
            @delete="(style: TaggingStyle) => emit('delete', style)"
          />
        </ui-bubble>
      </span>
    </div>
  </div>
  <!-- <div class="buttons" v-if="props.all">
    <ui-button type="submit" class="button" @click="emit('quitMore')">取消</ui-button>
    <ui-button type="primary" class="button" @click="enterHandler">保存</ui-button>
  </div> -->
</template>

<script setup lang="ts">
import { TaggingStyle, TaggingStyles } from '@/store'
import { createTaggingStyle } from '@/store'
import { ref, computed, defineEmits } from 'vue'
import { Cropper } from 'bill/index'
import { getFileUrl } from '@/utils'

const props = defineProps<{
  styles: TaggingStyles
  active: TaggingStyle
  all?: boolean
}>()

const maxLength = 40
const maxShowLen = computed(() => props.styles.length < maxLength ? 5 : 6)

const emit = defineEmits<{
  (e: 'change', style: TaggingStyle): void
  (e: 'delete', style: TaggingStyle): void
  (e: 'uploadStyle', styles: TaggingStyle): void
  (e: 'quitMore'): void
}>()

const showAll = ref(false)
const styleAll = computed(() => {
  if (props.all) {
    return props.styles
  } else {
    const styles = props.styles.slice(0, props.styles.length > maxShowLen.value ? maxShowLen.value : maxShowLen.value + 1)
    if (!styles.includes(props.active) && props.active) {
      styles[styles.length - 1] = props.active
    }
    return styles
  }
})

const iconUpload = async ({ file, preview }: { file: File, preview: string }) => {
  const data = await Cropper.open(preview)
  if (data) {
    emit('uploadStyle', createTaggingStyle({ 
      name: file.name,
      icon: { url: data[1], blob: data[0] }
    }))
  }
}

const clickHandler = (hotStyle: TaggingStyle) => {
  if (!props.all) {
    showAll.value = false
  }
  emit('change', hotStyle)
}
</script>

<style lang="scss" scoped>
.hot-styles {
  --size: 40px;
  --icon-size: calc(var(--size) * 0.85);
  margin: 24px 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--size), 1fr));
  gap: calc(var(--size) / 4);
  align-items: start;
  justify-content: center;

  .item {
    --un-active-color: rgba(var(--colors-primary-base-fill), 0);
    --active-transition: .3s ease;
    cursor: pointer;

    &.disable {
      opacity: .3;
      pointer-events: none;
      cursor: inherit;
    }

    span {
      width: var(--size);
      height: var(--size);
      display: flex;
      align-items: center;
      justify-content: center;
      border: 1px solid var(--un-active-color);
      position: relative;
      transition: border var(--active-transition);
      border-radius: 4px;

      .input {
        margin: 0;
      }

      img {
        width: var(--icon-size);
        height: var(--icon-size);
        // outline: 1px dashed var(--un-active-color);
        transition: outline-color var(--active-transition);
        border-radius: 4px;
      }

      .delete {
        --round-size: calc(var(--size) * 0.45);
        position: absolute;
        width: var(--round-size);
        height: var(--round-size);
        border-radius: 50%;
        background-color: rgba(250, 63, 72, 1);
        right: calc(var(--round-size) * -1 / 2);
        top: calc(var(--round-size) * -1 / 2);
        transition: background-color var(--active-transition);
        font-size: 12px;
        display: flex;
        align-items: center;
        justify-content: center;
        color: #fff;
        opacity: 0;
        transition: opacity .3s ease;

      }
    }

    p {
      transition: color var(--active-transition);
      margin-top: calc(var(--size) / 4);
      text-align: center;
      color: rgb(var(--colors-primary-fill));
      font-size: var(--small-size);
    }

    &.active {
      color: rgba(var(--colors-primary-base-fill), 1);
      --un-active-color: rgba(var(--colors-primary-base-fill), 1);

      span img {
        outline-color: rgb(var(--colors-primary-fill));
      }
      p {
        color: currentColor;
      }
    }

    &:not(.style-more):hover {
      .delete {
        opacity: 0.5;

        &:hover {
          opacity: 1;
        }
      }
    }
  }

  .add {
    height: 100%;
    align-items: center;
    display: flex;
    flex: none;

    span {
      font-size: calc(var(--icon-size) * 0.4);
      border: none;

      &::before {
        content: '';
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        width: var(--icon-size);
        height: var(--icon-size);
        border-radius: 2px;
        border: 1px solid var(--colors-border-color);
        transition: border-color .3s ease;
      }

      &:hover::before {
        border-color: rgba(255,255,255,1);
      }
      &:active::before {
        border-color: var(--colors-primary-base) !important;
      }
    }
  }

  .style-more {
    .fun-ctrl {
      position: relative;
    }

    .more-content {
      width: 360px;
      z-index: 9;
      --arrow-width: 20px;
      --bottom-left: 310px;
      --back-color: rgba(0, 0, 0, 0.7);

      .hot-styles {
        margin: 0;
      }
    }
  }
}

</style>
