<script setup lang="ts">
// import cameraIcon from '@af-mobile-client-vue3/assets/img/component/camera.png'
import { deleteFile, upload } from '@af-mobile-client-vue3/services/api/common'
import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil'
import { formatNow } from '@af-mobile-client-vue3/utils/timeUtil'
import {
  ActionSheet,
  showDialog,
  showFailToast,
  Icon as VanIcon,
  Uploader as VanUploader,
} from 'vant'
import { inject, ref } from 'vue'

interface WatermarkConfig {
  fontSize?: number | string
  color?: string
  alpha?: number
  userName?: string
  enableRePhotoCheck?: boolean
  blurThreshold?: number | string
}

const props = defineProps({
  imageList: Array<any>,
  outerIndex: { default: undefined },
  authority: { default: 'user' },
  uploadMode: { default: 'server' },
  attr: { type: Object as () => { addOrEdit?: string, acceptCount?: number, uploadImage?: boolean, watermark?: WatermarkConfig }, default: () => ({}) },
  mode: { default: '新增' }, // 预览
  // 新增：禁用交互（仍允许预览）
  disabled: { type: Boolean, default: false },
})
const emit = defineEmits(['updateFileList', 'updateAllFileList', 'photoQualityChange'])

// 从父组件获取 commonId，仅读取字符串值，不持有父级 provideParent 对象
const parentCommonId = (() => {
  try {
    const parent = inject<any>('provideParent', undefined)
    if (!parent) {
      return ''
    }
    if (typeof parent.commonId === 'object' && parent.commonId && 'value' in parent.commonId) {
      return String(parent.commonId.value ?? '')
    }
    return String(parent.commonId ?? '')
  }
  catch {
    return ''
  }
})()
const imageList = ref<Array<any>>(props.imageList ?? [])

// 浏览器模式：隐藏的文件输入（选择 / 拍照）
const fileInputRef = ref<HTMLInputElement | undefined>()
const cameraInputRef = ref<HTMLInputElement | undefined>()

function openBrowserFilePicker() {
  if (fileInputRef.value) {
    fileInputRef.value.value = ''
    fileInputRef.value.click()
  }
}

function openBrowserCameraPicker() {
  if (cameraInputRef.value) {
    cameraInputRef.value.value = ''
    cameraInputRef.value.click()
  }
}

function buildWatermarkText() {
  const wm = props.attr?.watermark ?? {}
  const user = wm.userName ?? ''
  const time = formatNow()

  // 构建带标签的换行格式
  const lines: string[] = []

  if (user) {
    lines.push(`拍摄人：${user}`)
  }

  if (time) {
    lines.push(`拍摄时间：${time}`)
  }

  return lines.join('\n')
}

function emitUpdatesAfterChange() {
  // 新增：对外抛出完整与ID列表
  (emit as any)('updateAllFileList', imageList.value.filter(item => item.status === 'done').map(item => item))
  const doneIds = Object.values(imageList.value)
    .filter(item => item.status === 'done')
    .map(item => item.id)
  if (props.outerIndex !== undefined) {
    (emit as any)('updateFileList', doneIds, props.outerIndex)
  }
  else {
    (emit as any)('updateFileList', doneIds)
  }
}

function createTempUploadingItem(name: string, previewUrl: string) {
  const temp = {
    uid: Date.now() + Math.random().toString(36).substr(2, 5),
    name,
    status: 'uploading',
    message: '上传中...',
    url: previewUrl,
  }
  if (!imageList.value)
    imageList.value = [temp]
  else imageList.value.push(temp)
  return temp
}

function uploadFileViaHttp(file: File, previewUrl: string, temp: any) {
  const formData = new FormData()
  formData.append('avatar', file)
  formData.append('resUploadMode', props.uploadMode)
  formData.append('pathKey', 'Default')
  formData.append('formType', 'image')
  formData.append('useType', 'Default')
  formData.append('resUploadStock', '1')
  formData.append('filename', file.name)
  formData.append('filesize', (file.size / 1024 / 1024).toFixed(4))
  formData.append('f_operator', 'server')

  upload(formData, import.meta.env.VITE_APP_SYSTEM_NAME, { 'Content-Type': 'multipart/form-data' }).then((res: any) => {
    const index = imageList.value.findIndex(item => item.uid === temp.uid)
    if (res?.data?.id) {
      if (index !== -1) {
        imageList.value[index].uid = res.data.id
        imageList.value[index].id = res.data.id
        delete imageList.value[index].message
        imageList.value[index].status = 'done'
        imageList.value[index].url = res.data.f_downloadpath
      }
    }
    else {
      if (index !== -1) {
        imageList.value[index].status = 'failed'
        imageList.value[index].message = '上传失败'
      }
    }
    emitUpdatesAfterChange()
  })
}

function handleBrowserFiles(files: FileList | null) {
  if (!files || files.length === 0)
    return
  const max = props.attr?.acceptCount ?? Number.POSITIVE_INFINITY
  for (let i = 0; i < files.length; i++) {
    if (imageList.value.length >= max)
      break
    const file = files[i]
    const reader = new FileReader()
    reader.onload = (e: any) => {
      const previewUrl = e.target?.result as string
      const temp = createTempUploadingItem(file.name, previewUrl)
      uploadFileViaHttp(file, previewUrl, temp)
    }
    reader.readAsDataURL(file)
  }
}
// 触发拍照
function triggerCamera() {
  if (props.disabled)
    return

  // 构建参数对象
  const param: any = {}

  // 只有在有有效水印配置时才添加水印参数
  const watermark = { ...props.attr?.watermark }
  if (watermark) {
    const watermarkText = buildWatermarkText()
    if (watermarkText) {
      param.watermark = watermarkText
    }
    if (watermark.fontSize && watermark.fontSize !== '') {
      param.watermarkFontSize = watermark.fontSize
    }

    if (watermark.color && watermark.color !== '') {
      param.watermarkColor = watermark.color
    }

    if (watermark.alpha !== undefined && watermark.alpha !== null && String(watermark.alpha) !== '') {
      param.watermarkAlpha = watermark.alpha
    }
  }

  param.blurThreshold = props.attr?.watermark?.blurThreshold ?? 30

  mobileUtil.execute({
    funcName: 'takePicture',
    param,
    callbackFunc: (result: any) => {
      if (result.status === 'success') {
        rePhotoCheck(result.data)
      }
      else if (result.status === 'error') {
        if (result.message && result.message.startsWith('图片质量检测失败')) {
          emit('photoQualityChange', 'quality-failed')
        }
        showDialog({
          title: '拍照异常',
          message: result.message || '拍照失败，请重试',
        })
      }
      else {
        // 浏览器模式：调起相机输入
        // openBrowserCameraPicker()
        // showToast('此处不允许浏览器上传，请在移动端操作')
      }
    },
  })
}

// 处理拍照后的上传
function getImageMimeType(fileName: string): string {
  const ext = fileName.split('.').pop()?.toLowerCase()
  if (ext === 'jpg' || ext === 'jpeg')
    return 'image/jpeg'
  if (ext === 'png')
    return 'image/png'
  if (ext === 'gif')
    return 'image/gif'
  return 'image/png' // 默认
}
/**
 * 检测并上传图片
 * @param photoData
 */
function rePhotoCheck(photoData: any) {
  // 看看图片是否正常

  // 检查是否需要进行翻拍检测（只有拍照的图片才检测）
  const watermark = { ...(props.attr as any)?.watermark }
  console.warn('watermark:', JSON.stringify(watermark))
  const enableRePhotoCheck = watermark?.enableRePhotoCheck ?? false
  // console.warn('enableRePhotoCheck', enableRePhotoCheck)

  if (enableRePhotoCheck) {
    // 进行翻拍检测
    mobileUtil.execute({
      funcName: 'detectAntiCopy',
      param: {
        image_base64: photoData.content,
      },
      callbackFunc: (result: any) => {
        try {
          if (result && result.status === 'success') {
            const checkRePhotoResult = result.data
            if (checkRePhotoResult.is_rephoto === true || checkRePhotoResult.is_rephoto === 'true') {
              emit('photoQualityChange', 'rephoto-detected')
              console.warn(`检测到当前图片属于翻拍照片\n请上传合法图片！`)
              showFailToast({
                message: `当前图片属于翻拍照片\n请上传合法图片！`,
                duration: 3000,
              })
            }
            else {
              handlePhotoUpload(photoData)
            }
          }
          else {
            console.error(`翻拍检测失败照片,${result.message}`)
            showFailToast(`翻拍检测失败照片,${result.message}`)
          }
        }
        catch (e) {
          console.error('翻拍检测', JSON.stringify(e))
        }
      },
    })
  }
  else {
    handlePhotoUpload(photoData)
  }
}
function handlePhotoUpload(photoData: any) {
  // 添加临时预览
  const mimeType = getImageMimeType(photoData.filePath)
  const tempFile = {
    uid: Date.now() + Math.random().toString(36).substr(2, 5),
    name: photoData.filePath.split('/').pop(),
    status: 'uploading',
    message: '上传中...',
    // 使用 base64 作为预览与大图展示来源
    // content: `data:${mimeType};base64,${photoData.content}`,
    url: `data:${mimeType};base64,${photoData.content}`,
    isImage: true,
    type: mimeType,
  }

  if (!imageList.value) {
    imageList.value = [tempFile]
  }
  else {
    imageList.value.push(tempFile)
  }

  const param = {
    resUploadMode: props.uploadMode,
    pathKey: 'Default',
    formType: 'image',
    useType: 'Default',
    resUploadStock: '1',
    filename: photoData.name,
    filesize: photoData.size,
    f_operator: 'server',
    imgPath: photoData.filePath,
    urlPath: `/api/${import.meta.env.VITE_APP_SYSTEM_NAME}/resource/upload`,
    commonId: parentCommonId,
  }
  // 添加上传队列
  mobileUtil.execute({
    funcName: 'queueUpload',
    param,
    callbackFunc: (res: any) => {
      console.warn('上传结果', res)
      // 成功
      if (res.data && res.data.enqueued) {
        const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
        if (index !== -1) {
          delete imageList.value[index].message
          imageList.value[index].status = 'done'
          imageList.value[index].photo_name = photoData.name
          imageList.value[index].type = mimeType
        }
        else {
          if (index !== -1) {
            imageList.value[index].status = 'failed'
            imageList.value[index].message = '上传失败'
          }
        }
      }

      emit('updateAllFileList', imageList.value.filter(item => item.status === 'done').map(item => item)) // 新增

      const doneIds = Object.values(imageList.value)
        .filter(item => !item.status || item.status === 'done')
        .map(item => item.photo_name)

      if (props.outerIndex !== undefined)
        emit('updateFileList', doneIds, props.outerIndex)
      else
        emit('updateFileList', doneIds)
    },
  })
  // 上传到服务器
  /* mobileUtil.execute({
    funcName: 'uploadResource',
    param,
    callbackFunc: (result: any) => {
      const index = imageList.value.findIndex(item => item.uid === tempFile.uid)
      if (result.status === 'success') {
        if (index !== -1) {
          imageList.value[index].uid = result.data.id
          imageList.value[index].id = result.data.id
          delete imageList.value[index].message
          imageList.value[index].status = 'done'
          imageList.value[index].url = result.data.f_downloadpath
          imageList.value[index].type = mimeType
        }
      }
      else {
        if (index !== -1) {
          imageList.value[index].status = 'failed'
          imageList.value[index].message = '上传失败'
        }
      }

      emit('updateAllFileList', imageList.value.filter(item => item.status === 'done').map(item => item)) // 新增

      const doneIds = Object.values(imageList.value)
        .filter(item => item.status === 'done')
        .map(item => item.id)

      if (props.outerIndex !== undefined)
        emit('updateFileList', doneIds, props.outerIndex)
      else
        emit('updateFileList', doneIds)
    },
  }) */
}

// 删除图片
function deleteFileFunction(file: any) {
  // 情况1：有后端id的已上传文件，先调接口再本地移除
  if (file.id) {
    deleteFile({ ids: [file.id], f_state: '删除' }).then((res: any) => {
      if (res.msg !== undefined) {
        const targetIndex = imageList.value.findIndex(item => item.id === file.id)
        if (targetIndex !== -1)
          imageList.value.splice(targetIndex, 1)

        emit('updateAllFileList', imageList.value.filter(item => item.status === 'done').map(item => item))

        const doneIds = Object.values(imageList.value)
          .filter(item => !item.status || item.status === 'done')
          .map(item => item.photo_name)
        if (props.outerIndex !== undefined)
          emit('updateFileList', doneIds, props.outerIndex)
        else
          emit('updateFileList', doneIds)
      }
    })
    return false // 已手动移除，阻止van-uploader再次移除
  }

  // 情况2：上传失败/上传中的临时文件（无id），允许直接删除
  const targetIndex = imageList.value.findIndex(item => item.uid === file.uid || item.url === file.url)
  if (targetIndex !== -1)
    imageList.value.splice(targetIndex, 1)

  emit('updateAllFileList', imageList.value.filter(item => item.status === 'done').map(item => item))

  const doneIds = Object.values(imageList.value)
    .filter(item => !item.status || item.status === 'done')
    .map(item => item.photo_name)
  if (props.outerIndex !== undefined)
    emit('updateFileList', doneIds, props.outerIndex)
  else
    emit('updateFileList', doneIds)

  return false // 阻止van-uploader二次处理
}

const showActionSheet = ref(false)
const uploaderRef = ref()

const actionOptions = [
  { name: '拍照', key: 'camera' },
  { name: '上传', key: 'file' },
]

function handleUploadAreaClick() {
  if (props.disabled)
    return
  if (props.attr?.uploadImage) {
    showActionSheet.value = true
  }
  else {
    triggerCamera()
  }
}

function handleActionSelect(option: any) {
  showActionSheet.value = false
  if (option.key === 'camera') {
    triggerCamera()
  }
  else if (option.key === 'file') {
    mobileUtil.execute({
      funcName: 'photoAlbum',
      param: {},
      callbackFunc: (result: any) => {
        if (result.status === 'success') {
          result.data?.photos.forEach((photo: any) => {
            rePhotoCheck(photo)
          })
        }
        else {
          // 浏览器模式：调起相机输入
          // openBrowserCameraPicker()
          // showToast('此处不允许浏览器上传，请在移动端操作')
        }
      },
    })
  }
}
</script>

<template>
  <div class="uploader-container">
    <!-- {{ imageList }} -->
    <!-- 浏览器模式隐藏输入：文件选择 -->
    <input
      ref="fileInputRef"
      type="file"
      multiple
      accept="image/*"
      style="display:none"
      @change="(e:any) => handleBrowserFiles(e.target.files)"
    >
    <!-- 浏览器模式隐藏输入：拍照（相机） -->
    <input
      ref="cameraInputRef"
      type="file"
      accept="image/*"
      capture="environment"
      style="display:none"
      @change="(e:any) => handleBrowserFiles(e.target.files)"
    >
    <VanUploader
      ref="uploaderRef"
      v-model="imageList"
      class="custom-trigger-uploader"
      :show-upload="true"
      :deletable="!props.disabled && (props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin') && props.mode !== '预览'"
      :multiple="props.authority === 'admin'"
      :preview-image="true"
      :preview-full-image="true"
      :before-delete="!props.disabled && props.attr?.addOrEdit !== 'readonly' && props.authority === 'admin' ? deleteFileFunction : undefined"
      :before-read="() => false"
    >
      <template #default>
        <div
          v-if="!props.disabled && props.mode !== '预览' && (imageList.length < props.attr?.acceptCount && props.attr?.addOrEdit !== 'readonly')"
          class="custom-upload-area"
          @click="handleUploadAreaClick"
        >
          <VanIcon name="plus" size="35" color="#d9d9d9" />
          <div v-if="props.attr?.acceptCount" class="upload-desc">
            {{ imageList.length }} / {{ props.attr?.acceptCount }}
          </div>
        </div>
      </template>
    </VanUploader>
    <ActionSheet
      v-model:show="showActionSheet"
      :actions="actionOptions"
      cancel-text="取消"
      @select="handleActionSelect"
    />
  </div>
</template>

<style scoped lang="less">
.uploader-container {
  display: flex;
  flex-direction: column;
}
/* 让自定义上传按钮可点击：关闭 Vant 覆盖在上方的透明 input 的事件捕获 */
:deep(.custom-trigger-uploader .van-uploader__input) {
  pointer-events: none;
}
.custom-upload-area {
  width: 82px;
  height: 82px;
  box-sizing: border-box;
  border: 1px dashed #d9d9d9;
  border-radius: 10px;
  background: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 12px 0 10px 0;
  .upload-camera-img {
    width: 28px;
    height: 28px;
    margin-bottom: 6px;
    object-fit: contain;
    display: block;
  }
  .upload-title {
    font-size: 14px;
    color: #bfc1c6;
    font-weight: 400;
    margin-bottom: 2px;
  }
  .upload-desc {
    font-size: 12px;
    color: #bfc1c6;
    margin-top: 0;
  }
}
</style>
