<template>
  <view class="upload-file">
    <view class="upload-area" @click="chooseFile">
      <view v-if="!uploading" class="upload-placeholder">
        <text class="upload-icon">{{ getUploadIcon() }}</text>
        <text class="upload-text">{{ getUploadText() }}</text>
      </view>

      <view v-if="uploading" class="uploading">
        <text class="upload-icon">⏳</text>
        <text class="upload-text">上传中...</text>
        <progress :percent="uploadProgress" show-info />
      </view>

<!--      <view v-if="fileInfo && !uploading" class="file-info">
        <text class="file-name">{{ fileInfo.name }}</text>
        <text class="file-size">{{ formatFileSize(fileInfo.size) }}</text>
      </view> -->
    </view>

<!--    <view v-if="error" class="error-message">
      <text>{{ error }}</text>
    </view> -->
  </view>
</template>

<script setup>
import { ref } from "vue";
import {
	useAuthStore
} from "@/store/modules/auth";

// 定义 props
const props = defineProps({
  // 允许的文件类型
  accept: {
    type: String,
    default: "*",
  },
  // 最大文件大小 (MB)
  maxSize: {
    type: Number,
    default: 10,
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false,
  },
});

// 定义 emits
const emit = defineEmits(["onSuccess", "onError", "onProgress"]);

// 响应式数据
const uploading = ref(false);
const uploadProgress = ref(0);
const fileInfo = ref(null);
const error = ref(null);

// 选择文件
const chooseFile = () => {
  if (props.disabled || uploading.value) return;

  error.value = null;

  // 根据 accept 属性判断文件类型并选择对应的方法
  const fileType = getFileTypeFromAccept();

  if (fileType === "image") {
    chooseImageFile();
  } else if (fileType === "video") {
    chooseVideoFile();
  } else {
    chooseMessageFile();
  }
};

// 根据 accept 属性判断文件类型
const getFileTypeFromAccept = () => {
  if (props.accept === "*") return "file";

  const accept = props.accept.toLowerCase();

  // 检查是否为图片类型
  const imageTypes = [
    ".jpg",
    ".jpeg",
    ".png",
    ".gif",
    ".bmp",
    ".webp",
    "image/",
  ];
  if (imageTypes.some((type) => accept.includes(type))) {
    return "image";
  }

  // 检查是否为视频类型
  const videoTypes = [
    ".mp4",
    ".avi",
    ".mov",
    ".wmv",
    ".flv",
    ".webm",
    "video/",
  ];
  if (videoTypes.some((type) => accept.includes(type))) {
    return "video";
  }

  // 其他文件类型
  return "file";
};

// 选择图片
const chooseImageFile = () => {
  uni.chooseImage({
    count: 1,
    sourceType: ["album", "camera"],
    success: (res) => {
      console.log("选择图片成功:", res);
      if (res.tempFilePaths && res.tempFilePaths.length > 0) {
        // 获取文件信息
        uni.getFileInfo({
          filePath: res.tempFilePaths[0],
          success: (fileInfo) => {
            const file = {
              name: "image_" + Date.now() + ".jpg",
              size: fileInfo.size,
              path: res.tempFilePaths[0],
            };
            validateAndUpload(file);
          },
          fail: () => {
            // 如果获取文件信息失败，使用默认值
            const file = {
              name: "image_" + Date.now() + ".jpg",
              size: 0,
              path: res.tempFilePaths[0],
            };
            validateAndUpload(file);
          },
        });
      } else {
        error.value = "未选择到图片";
      }
    },
    fail: (err) => {
      console.error("选择图片失败:", err);
      error.value = "选择图片失败: " + (err.errMsg || "请重试");
      emit("onError", err);
    },
  });
};

// 选择视频
const chooseVideoFile = () => {
  uni.chooseVideo({
    sourceType: ["album", "camera"],
    maxDuration: 60,
    camera: "back",
    success: (res) => {
      console.log("选择视频成功:", res);
      const file = {
        name: "video_" + Date.now() + ".mp4",
        size: res.size || 0,
        path: res.tempFilePath,
      };
      validateAndUpload(file);
    },
    fail: (err) => {
      console.error("选择视频失败:", err);
      error.value = "选择视频失败: " + (err.errMsg || "请重试");
      emit("onError", err);
    },
  });
};

// 选择文件
const chooseMessageFile = () => {
  uni.chooseMessageFile({
    count: 1,
    type: "all",
    success: (res) => {
      console.log("选择文件成功:", res);
      if (res.tempFiles && res.tempFiles.length > 0) {
        const file = res.tempFiles[0];
        validateAndUpload(file);
      } else {
        error.value = "未选择到文件";
      }
    },
    fail: (err) => {
      console.error("选择文件失败:", err);
      error.value = "选择文件失败: " + (err.errMsg || "请重试");
      emit("onError", err);
    },
  });
};

// 验证文件类型
const validateFileType = (fileName) => {
  if (props.accept === "*") return true;

  const acceptTypes = props.accept.split(",").map((type) => type.trim());
  const fileExt = "." + fileName.split(".").pop().toLowerCase();

  return acceptTypes.some((type) => {
    if (type.startsWith(".")) {
      return type.toLowerCase() === fileExt;
    }
    return fileName.toLowerCase().includes(type.toLowerCase());
  });
};

// 验证并上传文件
const validateAndUpload = (file) => {
  error.value = null;

  // 验证文件大小
  if (file.size > props.maxSize * 1024 * 1024) {
    error.value = `文件大小不能超过 ${props.maxSize}MB`;
    return;
  }

  // 验证文件类型
  if (props.accept !== "*" && !validateFileType(file.name)) {
    error.value = "文件类型不支持";
    return;
  }

  fileInfo.value = {
    name: file.name,
    size: file.size,
    path: file.path,
  };

  uploadFile(file);
};

// 处理上传错误
const handleUploadError = (message) => {
  uploading.value = false;
  uploadProgress.value = 0;
  error.value = message;
  emit("onError", message);
};

// 上传文件
const uploadFile = (file) => {
  uploading.value = true;
  uploadProgress.value = 0;

  console.log("开始上传文件:", file);

  const uploadTask = uni.uploadFile({
    url: "https://lift-dev.ruixininfo.com/filestransfer/upload",
    filePath: file.path,
    name: "file",
	header:{
		session:useAuthStore().accessToken
	},
    // formData: {
    //   fileName: file.name,
    // },
    success: (res) => {
      console.log("上传成功:", res);
      try {
        const data = JSON.parse(res.data);
        uploading.value = false;
        uploadProgress.value = 100;

        // 将接口返回信息传递给父组件的 onSuccess 方法
        emit("onSuccess", {
          response: data,
          fileInfo: fileInfo.value,
        });
      } catch (err) {
        console.error("解析响应失败:", err);
        handleUploadError("响应数据解析失败");
      }
    },
    fail: (err) => {
      console.error("上传失败:", err);
      handleUploadError(err.errMsg || "上传失败");
    },
  });

  // 监听上传进度
  uploadTask.onProgressUpdate((res) => {
    console.log("上传进度:", res.progress);
    uploadProgress.value = res.progress;
    emit("onProgress", res.progress);
  });
};

// 格式化文件大小
const formatFileSize = (bytes) => {
  if (bytes === 0) return "0 B";

  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));

  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
};

// 获取上传图标
const getUploadIcon = () => {
  const fileType = getFileTypeFromAccept();
  switch (fileType) {
    case "image":
      return "🖼️";
    case "video":
      return "🎬";
    default:
      return "📁";
  }
};

// 获取上传文字
const getUploadText = () => {
  const fileType = getFileTypeFromAccept();
  switch (fileType) {
    case "image":
      return "点击选择图片";
    case "video":
      return "点击选择视频";
    default:
      return "点击选择文件";
  }
};

// 重置组件状态
const reset = () => {
  uploading.value = false;
  uploadProgress.value = 0;
  fileInfo.value = null;
  error.value = null;
};

// 暴露方法给父组件使用
defineExpose({
  reset,
});
</script>

<style scoped>
.upload-file {
  width: 100%;
}

.upload-area {
  border: 2px dashed #dcdfe6;
  border-radius: 8px;
  padding: 0 20px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.3s;
  background-color: #fafafa;
}

.upload-area:hover {
  border-color: #409eff;
}

.upload-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.upload-icon {
  font-size: 24px;
}

.upload-text {
  color: #606266;
  font-size: 14px;
}

.uploading {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.file-info {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
}

.file-name {
  font-size: 16px;
  font-weight: bold;
  color: #303133;
}

.file-size {
  font-size: 12px;
  color: #909399;
}

.error-message {
  margin-top: 10px;
  padding: 8px 12px;
  background-color: #fef0f0;
  border: 1px solid #fbc4c4;
  border-radius: 4px;
  color: #f56c6c;
  font-size: 12px;
  text-align: center;
}

progress {
  width: 100%;
  height: 100%;
  margin-top: 10px;
}
</style>