<script setup lang="ts">
import CardHeader from '@af-mobile-client-vue3/components/data/CardContainer/CardHeader.vue'
import { mobileUtil } from '@af-mobile-client-vue3/utils/mobileUtil'
import {
  showFailToast,
  showImagePreview,
} from 'vant'
import { computed } from 'vue'

export interface FileItem {
  uid: string
  name: string
  size: number
  type: string
  url?: string
  filePath?: string
  userType?: string
  result?: any // android上传图片返回的结果示例数据：  {"f_file_size":0.0671,"f_form_type":"image","f_use_type":"Default","f_downloadpath":"/resource/af-revenue/images/15868b507cc0460a9913a6b94f1912d5.jpg","f_stock_id":0,"f_realpath":"/usr/local/tomcat/files/af-revenue/images/15868b507cc0460a9913a6b94f1912d5.jpg","f_type":"IMAGE","f_operator":"server","fusetype":"Default","f_filetype":"jpg","f_upload_mode":"server","id":"57900","f_filename":"15868b507cc0460a9913a6b94f1912d5.jpg"}
  status: 'success' | 'error' | 'uploading'
}

const props = defineProps({
  title: {
    type: String,
    default: '上传附件',
  },
  icon: {
    type: String,
    default: '',
  },
  fileList: {
    type: Array as () => FileItem[],
    default: () => [],
  },
  showFileList: {
    type: Boolean,
    default: true,
  },
  multiple: {
    type: Boolean,
    default: false,
  },
  accept: {
    type: String,
    default: '',
  },
  maxSize: {
    type: Number,
    default: 10 * 1024 * 1024, // 10MB
  },
  allowedTypes: {
    type: Array as () => string[],
    default: () => ['image/png', 'image/jpeg', 'application/pdf'],
  },
  useType: {
    type: String,
    default: 'Default',
  },
})

const emit = defineEmits(['update:fileList', 'fileAdded', 'fileRemoved'])

// const fileInput = ref<HTMLInputElement | null>(null)
const fileTypesText = computed(() => {
  return `单个文件不超过${formatFileSize(props.maxSize)}`
})

// 判断是否为开发环境
const isDev = import.meta.env.MODE === 'development'

// 模拟图片的base64数据
const mockImageBase64 = 'iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABmJLR0QA/wD/AP+gvaeTAAABdUlEQVRoge3ZsU4CQRAG4H9BYQyhgoTCGF/Axlfw0FdQKysrKwvfwsJEn8JECxKthAQbe2I8QgyRGIgFhRazJOqR7N3ezc6GKXeamW+zNze3N0Dg36PqXrDdbpfudjcRKWezWU9rPbXxXZoG0loPAbycTqdfIwBvs9nsnrbQzWbzhYg+T8/vP6HMcQbAMIyRlBK9Xm+nlLLaYCETAExT1iQiAgAiEgBc5fJDiMh1URQHXdJa92wCVb5RKSWKLWIB4FqWZWITyBrIdrJsE1UDWa1WViWrG8jlThWvbwwUqOlBFm9dXKBaTbBarVar/CKuWK1RFQVqNaiiKE7nrxPVZdSYyGQyUYPBgOu1Nq7xAjUTMrGBiIgQEUJp5zqWZtcwVFmWOB6PSKdTLJdLJEniOJEaIjJst1uUZWlUC7n27GQyQZZlyOdzxHGM+XwOz/O45n9nPB5ju90iyzLc7/eo1WrYbDZwHMd1NIPBYGDUDXl/1EAgYMwPPB0oPT3eUE4AAAAASUVORK5CYII='

function triggerFileInput() {
  console.log('点击事件')

  // 判断是否为开发环境
  if (isDev) {
    console.log('开发环境，使用模拟上传并调用真实接口')

    // 基本信息
    const filename = 'test.png'
    const fileSize = 0.0003 // MB
    const operator = '测试管理员'

    // 创建临时文件对象（将base64转换为文件）
    const byteString = atob(mockImageBase64)
    const ab = new ArrayBuffer(byteString.length)
    const ia = new Uint8Array(ab)
    for (let i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i)
    }
    const blob = new Blob([ab], { type: 'image/png' })
    const file = new File([blob], filename, { type: 'image/png' })

    // 创建FormData
    const formData = new FormData()
    formData.append('avatar', file) // 文件二进制数据
    formData.append('resUploadMode', 'server')
    formData.append('formType', 'file')
    formData.append('useType', props.useType)
    formData.append('resUploadStock', '1')
    formData.append('filename', filename)
    formData.append('filesize', fileSize.toString())
    formData.append('f_operator', operator)

    // 调用接口上传
    fetch('/api/af-revenue/resource/upload', {
      method: 'POST',
      body: formData,
    })
      .then(response => response.json())
      .then((result) => {
        console.log('上传成功:', result)
        // 创建临时文件项
        const newFile: FileItem = {
          uid: Date.now() + Math.random().toString(36).substr(2, 5),
          name: filename,
          size: file.size,
          type: 'image/png',
          status: 'success',
          url: `data:image/png;base64,${mockImageBase64}`,
          result: result.data.data,
        }
        updateFileList([...props.fileList, newFile])
        emit('fileAdded', newFile)
      })
      .catch((error) => {
        console.error('上传失败:', error)
        showFailToast(`上传文件失败: ${error.message || error.msg || '请稍后重试'}`)
      })

    return
  }

  // 非开发环境，使用原生功能
  mobileUtil.execute({
    funcName: 'takePicture',
    param: {},
    callbackFunc: (result: any) => {
      if (result.status === 'success') {
        uploadFile(result.data)
      }
    },
  })
  // fileInput.value?.click()
}
function uploadFile(file: any) {
  mobileUtil.execute({
    funcName: 'uploadResource',
    param: {
      resUploadMode: 'server',
      pathKey: props.useType,
      formType: 'image',
      useType: props.useType,
      resUploadStock: '1',
      filename: file?.name,
      filesize: file?.size,
      f_operator: 'server',
      imgPath: file?.filePath,
      urlPath: '/api/af-revenue/resource/upload',
    },
    callbackFunc: (result: any) => {
      if (result.status === 'success') {
        const newFile: FileItem = {
          uid: Date.now() + Math.random().toString(36).substr(2, 5),
          name: file.name,
          size: file.size,
          type: 'image/jpeg',
          status: 'success',
          url: `data:image/png;base64,${file.content}`,
          filePath: file?.filePath,
          result: result.data,
        }
        updateFileList([...props.fileList, newFile])
        emit('fileAdded', newFile)
      }
      else {
        showFailToast(`上传图片失败,${result.message}`)
      }
    },
  })
}
/* function handleFileChange(event: Event) {
  console.log('触发变更===')
  const input = event.target as HTMLInputElement
  if (!input.files?.length)
    return

  const files = Array.from(input.files)

  files.forEach((file) => {
    // 检查文件类型
    if (props.allowedTypes.length && !props.allowedTypes.includes(file.type)) {
      // 可以添加错误处理
      return
    }

    // 检查文件大小
    if (file.size > props.maxSize) {
      // 可以添加错误处理
      return
    }
    console.log('file==', file)
    const newFile: FileItem = {
      uid: Date.now() + Math.random().toString(36).substr(2, 5),
      name: file.name,
      size: file.size,
      type: file.type,
      status: 'success',
    }
    console.log('newFile==', newFile)
    // 处理图片预览
    if (file.type.startsWith('image/')) {
      const reader = new FileReader()
      reader.onload = (e) => {
        if (e.target?.result) {
          newFile.url = e.target.result as string
          updateFileList([...props.fileList, newFile])
        }
      }
      reader.readAsDataURL(file)
    }
    else {
      updateFileList([...props.fileList, newFile])
    }

    emit('fileAdded', { file, fileItem: newFile })
  })

  // 重置文件输入，允许选择相同文件
  input.value = ''
} */

function removeFile(file: FileItem) {
  const newFileList = props.fileList.filter(item => item.uid !== file.uid)
  updateFileList(newFileList)
  emit('fileRemoved', file)
}

function updateFileList(files: FileItem[]) {
  emit('update:fileList', files)
}

function getFileIcon(type: string) {
  if (type.startsWith('image/'))
    return 'fas fa-image text-green-500'
  if (type === 'application/pdf')
    return 'fas fa-file-pdf text-red-500'
  if (type.includes('word') || type.includes('document'))
    return 'fas fa-file-word text-blue-500'
  if (type.includes('excel') || type.includes('sheet'))
    return 'fas fa-file-excel text-green-600'
  return 'fas fa-file-alt text-gray-500'
}

function formatFileSize(size: number) {
  if (size < 1024)
    return `${size} B`
  if (size < 1024 * 1024)
    return `${(size / 1024).toFixed(1)} KB`
  return `${(size / (1024 * 1024)).toFixed(1)} MB`
}

// 打开图片预览
function previewImage(file: FileItem) {
  if (file.url) {
    const imageUrls = props.fileList
      .filter(item => item.url)
      .map(item => item.url as string)

    const startPosition = imageUrls.findIndex(url => url === file.url)

    showImagePreview({
      images: imageUrls,
      startPosition: startPosition >= 0 ? startPosition : 0,
      closeable: true,
    })
  }
}

defineExpose({
  triggerFileInput,
})
</script>

<template>
  <div class="file-uploader">
    <div class="file-uploader__header">
      <CardHeader :title="title" />
    </div>

    <div class="file-uploader__container">
      <div class="file-uploader__dropzone" @click="triggerFileInput">
        <svg class="file-uploader__icon" stroke="currentColor" fill="none" viewBox="0 0 48 48" aria-hidden="true">
          <path d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
        </svg>
        <div class="file-uploader__text">
          <label class="file-uploader__button">
            <span>{{ isDev ? '上传图片' : '拍照' }}</span>
            <!--            <input
              ref="fileInput"
              type="file"
              class="file-uploader__input"
              :multiple="multiple"
              :accept="accept"
              @change="handleFileChange"
            > -->
          </label>
          <!--          <p class="file-uploader__hint">
            点击上传
          </p> -->
        </div>
        <p class="file-uploader__tip">
          {{ fileTypesText }}
        </p>
      </div>

      <!-- 文件列表 -->
      <div v-if="showFileList && fileList.length > 0" class="file-uploader__list-container">
        <h5 class="file-uploader__list-title">
          已上传附件 ({{ fileList.length }})
        </h5>
        <div class="file-uploader__list">
          <div v-for="file in fileList" :key="file.uid" class="file-uploader__file-item">
            <div class="file-uploader__file-item-content">
              <!-- 图片预览 -->
              <div v-if="file.url" class="file-uploader__preview" @click.stop="previewImage(file)">
                <img :src="file.url" class="file-uploader__preview-image">
              </div>

              <!-- 文件图标 -->
              <div v-else class="file-uploader__file-icon">
                <div class="file-uploader__file-icon-container">
                  <i :class="getFileIcon(file.type)" />
                </div>
              </div>

              <div class="file-uploader__file-info">
                <p class="file-uploader__file-name">
                  {{ file.name }}
                </p>
                <p class="file-uploader__file-size">
                  <span>{{ formatFileSize(file.size) }}</span>
                  <span v-if="file.status === 'success'" class="file-uploader__file-status">
                    <i class="fas fa-check-circle" />
                  </span>
                  <span v-else-if="file.status === 'uploading'" class="file-uploader__file-status file-uploader__file-status--uploading">
                    <i class="fas fa-circle-notch fa-spin" />
                  </span>
                  <span v-else-if="file.status === 'error'" class="file-uploader__file-status file-uploader__file-status--error">
                    <i class="fas fa-exclamation-circle" />
                  </span>
                </p>
              </div>
            </div>

            <div class="file-uploader__file-actions">
              <button
                type="button"
                class="file-uploader__file-remove"
                @click="removeFile(file)"
              >
                <svg class="file-uploader__file-remove-icon" fill="currentColor" viewBox="0 0 20 20">
                  <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
                </svg>
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="less" scoped>
.file-uploader {
  &__header {
    margin-bottom: 8px;
  }

  &__container {
    display: flex;
    flex-direction: column;
  }

  &__dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 16px;
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    background-color: #fafafa;
    cursor: pointer;
    transition: border-color 0.3s;

    &:hover {
      border-color: var(--van-primary-color);
    }
  }

  &__icon {
    width: 32px;
    height: 32px;
    color: #c0c4cc;
    margin-bottom: 6px;
  }

  &__text {
    display: flex;
    align-items: center;
    font-size: 14px;
    color: #666;
  }

  &__button {
    display: inline-block;
    padding: 6px 12px;
    background-color: #fff;
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    font-size: 14px;
    color: var(--van-primary-color);
    cursor: pointer;
    margin-right: 4px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);

    &:hover {
      color: #409eff;
      border-color: #c6e2ff;
      background-color: #ecf5ff;
    }
  }

  &__input {
    display: none;
  }

  &__hint {
    font-size: 14px;
    color: #666;
  }

  &__tip {
    margin-top: 6px;
    font-size: 12px;
    color: #666;
  }

  &__list-container {
    margin-top: 16px;
  }

  &__list-title {
    font-size: 16px;
    font-weight: 600;
    color: #333;
    margin-bottom: 12px;
  }

  &__list {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }

  &__file-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px;
    border: 1px solid #e8e8e8;
    border-radius: 8px;
    background-color: #f5f7fa;
  }

  &__file-item-content {
    display: flex;
    align-items: center;
    flex: 1;
  }

  &__preview {
    width: 36px;
    height: 36px;
    margin-right: 12px;
    overflow: hidden;
    flex-shrink: 0;
    cursor: pointer;
    position: relative;
    border-radius: 4px;
    border: 1px solid #e8e8e8;

    &:hover::after {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.1);
      border-radius: 4px;
    }
  }

  &__preview-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 4px;
  }

  &__file-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    margin-right: 12px;
    flex-shrink: 0;
  }

  &__file-icon-container {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    border-radius: 4px;
    background-color: #fff;

    i {
      font-size: 16px;
    }
  }

  &__file-info {
    flex: 1;
    min-width: 0;
  }

  &__file-name {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: #333;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  &__file-size {
    margin: 4px 0 0;
    font-size: 12px;
    color: #666;
    display: flex;
    align-items: center;
  }

  &__file-status {
    margin-left: 4px;
    color: #67c23a;

    &--uploading {
      color: #409eff;
    }

    &--error {
      color: #f56c6c;
    }
  }

  &__file-actions {
    display: flex;
  }

  &__file-remove {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background-color: #e0e0e0;
    border: none;
    cursor: pointer;
    color: #606266;

    &:hover {
      background-color: #f56c6c;
      color: #fff;
    }
  }

  &__file-remove-icon {
    width: 14px;
    height: 14px;
  }
}
</style>
