<template>
  <DialogBox :title="dialogTitle" v-model="dialogVisible" width="600" :before-clone="closeConfirm">
    <el-form ref="formDataRef" :model="formData" :rules="rules" label-position="top" require-asterisk-position="right" @submit.prevent>
      <!-- 智能体头像 -->
      <el-form-item label="智能体头像" prop="imgUrl" class="acatar_box">
        <span class="avatar_text">仅支持.png .jpg 格式，文件大小100KB以内</span>
        <!--上传图片组件-->
        <el-upload 
          class="avatar-uploader" 
          :show-file-list="false" 
          v-model="formData.imgUrl"
          action="/dada/base/anyone/file/upload" 
          :headers="getHeaders()" 
          :data="{
            bizType: 'AIAPPLICATION_AVATAR'
          }" 
          :on-success="handleSuccess" 
          :before-upload="handleBeforeAvatarUpload"
        >
          <div class="avatar-uploader-content">
            <!--已经上传过图片-->
            <div v-if="formData.imgUrl" class="avatar-uploader-content-right">
              <img :src="formData.imgUrl" class="avatar"  v-pathToSrc="formData.imgUrl" />
              <div class="avatar-move">
                <!--预览图片-->
                <lz-svg-icon icon-class="chakan" style="margin-right: 10px" @click.stop="handlePictureCardPreview(formData.imgUrl)" />
                <!--重新上传图片-->
                <lz-svg-icon icon-class="shangchuan" />
              </div>
            </div>
             <!--未上传过图片-->
            <div v-else class="avatar-uploader-content-right avatar-uploader-content-def">
              <div class="avatar-uploader-content-def-img">
                <img src="@/assets/agent/chat/upload-img.svg" alt="" />
                上传
              </div>
            </div>
          </div>
        </el-upload>
      </el-form-item>
      <!-- 智能体名称-->
      <el-form-item label="智能体名称" prop="name">
        <el-input v-model="formData.name" maxlength="20" placeholder="请输入智能体名称" show-word-limit
          @blur="formData.name = formData.name?.trim()" />
      </el-form-item>
      <!-- 智能体描述-->
      <el-form-item label="智能体描述" prop="applicationDesc">
        <el-input v-model="formData.applicationDesc" type="textarea" placeholder="请输入智能体描述" :rows="6" maxlength="500"
          show-word-limit />
      </el-form-item>
    </el-form>
    <!-- 按钮操作 -->
    <template #footer>
      <span class="dialog-footer res_el-dialog__footer">
        <el-button @click.prevent="closeConfirm" :loading="loading"> 取消 </el-button>
        <el-button type="primary" @click="submitHandle(formDataRef)" :loading="loading">{{ dialogBtn }}</el-button>
      </span>
    </template>
    <!-- 预览头像弹框-->
    <el-dialog v-model="PreviewDialogVisible" append-to-body="true" width="600px" style="text-align: center" draggable="true">
      <img w-full :src="PreviewdialogImageUrl" alt="Preview Image" v-pathToSrc="PreviewdialogImageUrl" />
    </el-dialog>
  </DialogBox>
</template>
<script setup lang="ts">
import { ref, watch, reactive, computed } from 'vue'
import { cloneDeep, isEqual, isFunction } from 'lodash-es'
import type { FormInstance, FormRules } from 'element-plus'
import { MsgSuccess, MsgError, MsgConfirm } from '@/utils/message'
import type { UploadProps } from 'element-plus'
import { getHeaders } from '@/request/http'
import { useRouter } from 'vue-router'
import { save14, update14, checkName3 } from '@/servers/finyx/api/zhinengti'

const router = useRouter()
const emit = defineEmits(['refresh'])

/** mock data */
const baseImgUrl = ref('')

const formDataRef = ref()
const loading = ref(false)
const dialogVisible = ref<boolean>(false)
const PreviewdialogImageUrl = ref('') /* 图片预览 */
const PreviewDialogVisible = ref(false)
const formData = ref<any>({
  name: '', /* 智能体名称 */
  applicationDesc: '', /* 智能体描述 */
  imgUrl: baseImgUrl.value, /* 图片地址 */
})

/** 标题 */
const dialogTitle = computed(() => {
  return formData.value.id ? '编辑智能体' : '创建智能体'
})

/** 按钮 */
const dialogBtn = computed(() => {
  return formData.value.id ? '保存' : '创建'
})

/** 智能体名称校验-是否重复*/
const validateNameDuplicate = async (_rule: any, value: string, callback: any) => {
  if (!value) {
    return callback(new Error('智能体名称不能为空'));
  }
  try {
    const params: any = { name: value}
    formData.value.id && (params.id = formData.value.id);
    const res = await checkName3(params);
    res ? callback() : callback(new Error('智能体名称重复，请重新输入'));
  } catch (error: any) {
    callback(new Error(error?.response?.data?.msg || '智能体名称检查失败'));
  }
};

/** 智能体名称校验-是否为空*/
const validateNameEmpty = (rule: any, value: string, callback: any) => {
  if (!value || value.trim() === '') {
    callback(new Error('智能体名称不能为空'));
  } else if (value.trim().length > 20) {
    callback(new Error('智能体名称长度不能大于20个字符'));
  } else {
    callback();
  }
};
/** 智能体名称校验-特殊字符 */
const validateNameSpecialChars = (rule: any, value: string, callback: any) => {
  const specialChars = /[*?"<>]/;
  if (specialChars.test(value)) {
    callback(new Error('智能体名不能包含特殊符号：*？"<>'));
  } else {
    callback();
  }
};

/** 表单验证 */
const rules = reactive<FormRules<any>>({
  name: [
    { required: true, validator: validateNameEmpty, trigger: 'blur' },
    { validator: validateNameSpecialChars, trigger: 'blur' },
    { validator: validateNameDuplicate, trigger: 'blur' },
  ],
  applicationDesc: [
    {
      max: 500,
      message: '智能体描述长度不能大于500个字符',
      trigger: 'change'
    }
  ]
})

/** 监听弹框打开 */
watch(dialogVisible, (bool) => {
  if (!bool) {
    formData.value = {
      name: '', // 	智能体名称
      applicationDesc: '', // 智能体描述
      imgUrl: baseImgUrl.value, // 图片地址
    }
    initFormData.value = cloneDeep(formData.value)
    formDataRef.value?.clearValidate()
  }
})

const handleSuccess = (uploadFile: any) => {
  formData.value.imgUrl = uploadFile.data.path
  MsgSuccess('上传成功')
}

/**
 * 处理头像上传前的验证逻辑
 *
 * 该函数在用户选择头像文件后、文件上传之前被调用，用于验证文件类型和大小是否符合要求。
 *
 * @param {File} uploadFile - 当前上传的文件对象，包含文件的基本信息如名称、大小、类型等。
 * @returns {boolean} - 如果文件符合要求返回 true，否则返回 false。
 */
const handleBeforeAvatarUpload = (uploadFile: any) => {
  const isJpgOrPng = uploadFile.type === 'image/jpeg' || uploadFile.type === 'image/png';
  const isLt100KB = uploadFile.size / 1024 < 100;

  if (!isJpgOrPng) {
    MsgError('仅支持.png 和.jpg 格式的文件')
    return false;
  }
  if (!isLt100KB) {
    MsgError('文件大小不能超过 100KB')
    return false;
  }
  return true;
}

const handlePictureCardPreview: UploadProps['onPreview'] = (url: any) => {
  PreviewdialogImageUrl.value = url
  PreviewDialogVisible.value = true
}

const open = (row?: any) => {
  if (row) {
    formData.value = cloneDeep(row)
    initFormData.value = cloneDeep(row)
  };
  dialogVisible.value = true
}

const submitHandle = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  const valid = await formEl.validate()
  if (!valid) return;
  loading.value = true
  const params: any = {
    name: formData.value.name,
    applicationDesc: formData.value.applicationDesc,
    imgUrl: formData.value.imgUrl,
  }
  if (formData.value.id) {
    params.id = formData.value.id
    update14(params).then(() => {
      MsgSuccess('编辑成功')
      dialogVisible.value = false
      emit('refresh')
    }).catch((err) => {
      MsgError(err.response.data.msg)
    }).finally(() => {
      loading.value = false
    })
  } else {
    save14(params).then((res: any) => {
      MsgSuccess('创建成功')
      const path = `/smart/answer/${res.id}/setting`
      dialogVisible.value = false
      router.push({ path })
    }).catch((err) => {
      MsgError(err.response.data.msg)
    }).finally(() => {
      loading.value = false
    })
  }
}
const initFormData: any = ref(formData.value)

function closeConfirm(done: () => void) {
  if (isEqual(formData.value, initFormData.value)) {
    return close(done)
  }
  MsgConfirm('提示', '修改后的信息未保存，确定不保存并关闭弹窗？').then(() => {
    close(done)
  })
}

function close(done: () => void) {
  isFunction(done) && done()
  dialogVisible.value = false
}

defineExpose({ open })
</script>
<style lang="scss" scoped>
.radio-card {
  line-height: 22px;
  &.active {
    border-color: var(--el-color-primary);
    color: var(--el-color-primary);
  }
}
.acatar_box {
  padding-top: 18px;
  position: relative;
  .avatar_text {
    position: absolute;
    width: 100%;
    left: 0;
    top: -10px;
    color: #8C8C8C;
  }
}
.avatar-uploader {
  width: 100%;
  position: relative;
  &-content {
    display: flex;
    flex-direction: row;
    font-weight: 400;
    font-size: 14px;
    color: #8c8c8c;
    line-height: 20px;
    &-right {
      position: absolute;
      top: -48px;
      right: 0;
      width: 80px;
      height: 80px;
      border-radius: 50%;
      border: 1px solid #dfe0e3;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      font-weight: 400;
      font-size: 12px;
      color: #fff;
      overflow: hidden;
      .avatar-move {
        position: absolute;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        background: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
      }
      img {
        width: 14px;
      }
      .avatar {
        width: 80px;
        height: 80px;
      }
    }
    &-def {
      background: url(../../../../assets/agent/def_agent.svg);
      background-position: center;
      background-repeat: no-repeat;
      background-size: cover;
      z-index: 1;
    }
    &-def-img {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      position: absolute;
    }
    &-def::before {
      content: '';
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      left: 0;
      background: rgba(0, 0, 0, 0.6);
      z-index: 0;
    }
  }
}
.personnel-list {
  width: 100%;
  display: flex;
  padding: 6px 12px;
  border: 1px solid #dfe0e3;
  border-radius: 6px;
  align-items: center;
  justify-content: space-between;
  &-content {
    flex: 1;
    line-height: 20px;
    max-width: 430px;
    font-size: 14px;
    color: #191919;
  }
  &-right {
    width: 70px;
    font-size: 12px;
    line-height: 20px;
    color: #3067ef;
    text-align: right;
    cursor: pointer;
    display: flex;
    &-num {
      overflow: hidden;
      max-width: 150px;
      margin-right: 6px;
    }
  }
}
</style>