<template>
  <div class="img-cropper" :class="{ 'img-cropper-auto': $slots.default }">
    <slot name="default"></slot>
    <template v-if="!$slots.default">
      <template v-if="src">
        <div class="img-cropper-img" @click="openCropper">
          <div class="img-boxs">
            <img :src="src" :class="{ circled: circled }" />
          </div>
          <div class="mask" :class="{ circled: circled }" @click.stop>
            <div class="handle-icon" @click="openCropper">
              <span class="icon"><FormOutlined /></span>
            </div>
            <div class="handle-icon" @click="viewImg">
              <span class="icon"><ZoomInOutlined /></span>
            </div>
            <div class="handle-icon" @click="deleteImg">
              <span class="icon"><DeleteOutlined /></span>
            </div>
          </div>
        </div>
      </template>
      <template v-else>
        <div class="img-cropper-img" @click="openCropper">
          <div class="addImg">
            <span class="icon"><PlusOutlined /></span>
          </div>
        </div>
      </template>
    </template>
    <CropperModal
      ref="cropperRef"
      :title="title"
      subBtuText="确认上传"
      :uploadApi="uploadApi"
      :name="name"
      :circled="circled"
      @upload-success="handleSuccess"
    />
  </div>
</template>

<script lang="ts" setup>
  import { ref } from 'vue';
  import CropperModal from './CropperModal.vue';
  import { UploadOutlined } from '@ant-design/icons-vue';
  import {
    PlusOutlined,
    ZoomInOutlined,
    DeleteOutlined,
    FormOutlined,
  } from '@ant-design/icons-vue';
  import { cssUnit } from '@/utils';

  const cropperRef = ref();

  const props = defineProps({
    title: { type: String, default: '图片上传' },
    src: { type: String, required: true },
    circled: { type: Boolean, default: false },
    width: { type: [String, Number], default: 120 },
    uploadApi: {
      type: Function as PropType<(params) => Promise<any>>,
    },
    name: { type: String, default: 'name' },
  });

  const getWidth = cssUnit(props.width);

  const iconSize = cssUnit(Math.ceil(parseInt(getWidth) / 4));

  // const emit = defineEmits(['change']);
  const emit = defineEmits(['uploadSuccess']);
  const viewImg = () => {
    window.open(props.src);
  };
  const deleteImg = () => {
    emit('uploadSuccess', { fileUrl: '' });
  };
  function handleSuccess(value) {
    emit('uploadSuccess', value);
  }
  function openCropper() {
    cropperRef.value.openModal();
  }

  defineExpose({
    openCropper,
  });
</script>

<style lang="less" scoped>
  .img-cropper {
    width: v-bind(getWidth);
    height: v-bind(getWidth);
    overflow: hidden;
    text-align: center;
    position: relative;

    &-img {
      position: relative;
      width: 100%;
      height: 100%;
      border-radius: 50%;
      .img-boxs {
        border: 1px dashed #999999;
        padding: 5px;
      }
      .addImg {
        width: v-bind(getWidth);
        height: v-bind(getWidth);
        border: 1px dashed #999999;
        display: flex;
        justify-content: center;
        align-items: center;
        .icon {
          color: #999999;
          font-size: v-bind(iconSize);
        }
      }

      .mask {
        position: absolute;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: 10;
        left: 0;
        top: 0;
        opacity: 0;
        transition: opacity 0.4s;
        .handle-icon {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          padding: 0 6%;
          color: aliceblue;
          .icon {
            color: #fff;
            font-size: 20px;
          }
        }
      }

      &:hover {
        cursor: pointer;

        .mask {
          opacity: 1;
        }
      }
    }
  }

  .img-cropper-auto {
    width: auto;
    height: auto;
    display: inline-block;
  }

  .circled {
    border-radius: 50%;
  }
</style>
