<template>
  <view class="form-group">
    <view v-if="label" class="form-label"><text class="required-mark">{{ required ? "*" : "" }}</text> {{ label }}
    </view>
    <u-form-item :prop="rulesKey">
      <template v-if="type === 'text' || type === 'password'">
        <up-input v-model="inputValueDoc" class="form-input" :type="type"
          :placeholder="placeholder ? placeholder : t('common.input')" :readonly="readonly" :disabled="disabled"
          :clearable="clearable" :maxlength="maxlength" :errorMessage="errorMessage" @blur="handleBlur"
          @focus="handleFocus" @clear="handleClear">
          <template #prefix>
            <slot name="left-icon1"></slot>
          </template>
          <template #suffix>
            <slot name="right-icon1"></slot>
          </template>
        </up-input>
      </template>
      <template v-if="type === 'number'">
        <up-input v-model="inputValueDoc" class="form-input" type="number"
          :placeholder="placeholder ? placeholder : t('common.input')" :readonly="readonly" :disabled="disabled"
          :clearable="clearable" :maxlength="maxlength" :errorMessage="errorMessage" @blur="handleBlur"
          @focus="handleFocus" @clear="handleClear">
          <slot></slot>
        </up-input>
      </template>
      <template v-if="type === 'dropdown'">
        <view class="input-wrapper" @click.stop="handleInputClick">
          <view class="input-bg"></view>
          <up-input v-model="inputValueDoc" class="form-input"
            :placeholder="placeholder ? placeholder : t('common.choose')" :readonly="true" :disabled="disabled"
            :clearable="clearable" :errorMessage="errorMessage" @clear="handleClear">
            <template #suffix>
              <up-icon name="arrow-down" size="14"></up-icon>
            </template>
            <slot></slot>
          </up-input>
        </view>
        <up-action-sheet :show="filteredColumns.length && showPicker" :actions="filteredColumns"
          @select="onActionSheetConfirm" @close="showPicker = false" />
      </template>
      <template v-if="type === 'select'">
        <view class="input-wrapper" @click.stop="handleInputClick">
          <view class="input-bg"></view>
          <up-input v-model="inputValueDoc" class="form-input"
            :placeholder="placeholder ? placeholder : t('common.choose')" :readonly="true" :disabled="disabled"
            :clearable="clearable" :errorMessage="errorMessage" @clear="handleClear">
            <template #suffix>
              <up-icon name="arrow-down" size="14"></up-icon>
            </template>
            <slot></slot>
          </up-input>
        </view>
        <!-- :showSearch="false" :options="selectPopup.options" v-model="selectPopup.show" @select="onSelectConfirm" -->
        <cwg-more-select v-if="showPicker" :showSearch="showSearch" :input-value="inputValueDoc"
          :options="filteredColumns" v-model="showPicker" @select="onConfirm" />
      </template>
      <template v-if="type === 'date'">
        <view class="input-wrapper" @click="handleInputClick">
          <view class="input-bg"></view>
          <up-input v-model="inputValueDoc" class="form-input"
            :placeholder="placeholder ? placeholder : t('common.choose')" :readonly="true" :disabled="disabled"
            :clearable="clearable" :errorMessage="errorMessage" @clear="handleClear">
            <template #suffix>
              <up-icon name="calendar" size="14"></up-icon>
            </template>
          </up-input>
        </view>
        <cwg-date-picker v-model:show="showPicker" v-model="inputValueDoc" mode="date" @confirm="onDateConfirm"
          :minDate="minDate" :maxDate="maxDate" />
      </template>
      <template v-if="type === 'upload'">
        <view class="form-input uploader">
          <up-upload v-if="!isUploadD" :fileList="uploader" :disabled="disabled" :deletable="!disabled" :accept="accept"
            :maxCount="1" @afterRead="afterRead" @delete="handleDelete"></up-upload>
          <up-upload v-if="isUploadD" :fileList="uploader" :disabled="disabled" :deletable="!disabled" :maxCount="1"
            @afterRead="afterRead" @delete="handleDelete">
            <slot></slot>
          </up-upload>
        </view>
      </template>
    </u-form-item>
  </view>
</template>

<script setup>
import { ref, onMounted, watch, computed, defineProps } from "vue";
import dayjs from "dayjs";
import { upload } from "@/utils/request";
import { uploadApi } from "@/api/upload";
import config from "@/config";
import { useI18n } from "vue-i18n";

const { t } = useI18n();
const props = defineProps({
  type: {
    type: String,
    default: "text",
    validator: (v) =>
      [
        "text",
        "password",
        "number",
        "select",
        "date",
        "dropdown",
        "upload",
      ].includes(v),
  },
  label: String,
  fkey: String,
  rulesKey: String,
  accept: String,
  showSearch: Boolean,
  isUploadD: { type: Boolean, default: false },
  value: { type: [String, Number] },
  placeholder: String,
  direction: { type: String, default: "down" },
  disabled: Boolean,
  readonly: Boolean,
  required: Boolean,
  max: Number,
  clearable: { type: Boolean, default: true },
  columns: { type: Array, default: () => [] },
  rules: { type: Array, default: () => [] },
  maxlength: Number,
  errorMessage: String,
  minDate: { type: Date, default: () => new Date(1920, 0, 1).getTime() },
  maxDate: { type: Date, default: () => new Date().getTime() },
  dateFormatter: { type: Function, default: (_type, val) => val },
  displayFormatter: {
    type: Function,
    default: (val) => dayjs(val).format("YYYY-MM-DD"),
  },
});
const emit = defineEmits([
  "update:value",
  "blur",
  "focus",
  "clear",
  "confirm",
  "change",
]);

const isUploading = ref(false);
const uploader = ref([]);
const inputValueDoc = ref("");
const selectedValue = ref([]);
const showPicker = ref(false);
const onConfirm = (value) => {
  let selectedText = value.text || ''
  if (props.fkey == 'areaCode') {
    selectedText = selectedText
  }
  inputValueDoc.value = selectedText
  showPicker.value = false
}
// 处理输入框点击事件
function handleInputClick() {
  if (props.disabled || props.readonly) return;
  showPicker.value = true;
}

function absoluteUrl(url) {
  if (!url) {
    return "";
  }
  if (/^https?:\/\//.test(url)) {
    return url;
  }
  const prefix = config.Host85 || "";
  if (!prefix) {
    return url;
  }
  return `${prefix}${url.startsWith("/") ? url : `/${url}`}`;
}

async function afterRead(file) {
  isUploading.value = true;
  uni.showLoading({
    title: "上传中...",
    mask: true,
  });
  try {
    console.log(file.file, file);

    const result = await uploadApi.uploadFile(file.file);
    console.log(500, result);
    uni.hideLoading();
    if (result.code === 200) {
      inputValueDoc.value = result.data;
      uploader.value = [{ url: absoluteUrl(result.data) }];
      uni.showToast({
        title: "上传成功",
        icon: "success",
      });
      setTimeout(() => {
        isUploading.value = false;
      }, 100);
    } else {
      uni.showToast({
        title: result.message || "上传失败",
        icon: "none",
      });
      isUploading.value = false;
      inputValueDoc.value = "";
      uploader.value = [];
    }
  } catch (_error) {
    uni.hideLoading();
    uni.showToast({
      title: _error.message || "上传失败",
      icon: "none",
    });
  }
}

async function afterRead1(event) {
  console.log(event, 198);

  isUploading.value = true;
  uni.showLoading({
    title: "上传中...",
    mask: true,
  });
  try {
    // uview-plus 的 upload 组件返回的是 { file, fileList }
    // file 对象包含 url（临时路径）或 path 属性
    const file = event.file || (Array.isArray(event) ? event[0] : event);
    const filePath = file.url || file.path || file.tempFilePath;

    if (!filePath) {
      throw new Error("文件路径不存在");
    }

    // 使用 uni-app 的 upload 方法，需要传入 filePath
    const result = await upload({
      url: "/wasabi/api/upload/file",
      filePath: filePath,
    });

    uni.hideLoading();
    console.log(500, result);
    if (result.code === 200) {
      inputValueDoc.value = result.data;
      uploader.value = [{ url: absoluteUrl(result.data) }];
      uni.showToast({
        title: "上传成功",
        icon: "success",
      });
      setTimeout(() => {
        isUploading.value = false;
      }, 100);
    } else {
      uni.showToast({
        title: result.message || "上传失败",
        icon: "none",
      });
      isUploading.value = false;
      inputValueDoc.value = "";
      uploader.value = [];
    }
  } catch (_error) {
    uni.hideLoading();
    uni.showToast({
      title: _error.message || "上传失败",
      icon: "none",
    });
    isUploading.value = false;
    uploader.value = [];
  }
}

function handleDelete(event) {
  const index = event.index;
  uploader.value.splice(index, 1);
  inputValueDoc.value = "";
  emit("update:value", "");
  emit("change", { value: "", key: props.fkey });
}

const filteredColumns = computed(() => {
  if (props.type === "dropdown") {
    return props.columns.map((item) => {
      return { ...item, name: item.text };
    });
  }
  return props.columns;
});

watch(
  () => inputValueDoc.value,
  (newVal) => {
    // if (!newVal) return
    if (
      props.type === "text" ||
      props.type === "number" ||
      props.type === "password"
    ) {
      emit("update:value", newVal);
      emit("change", { value: newVal, key: props.fkey });
    } else if (props.type === "select") {
      const matched = props.columns.find((opt) => opt.text === newVal);
      emit("update:value", matched?.value || "");
      emit("change", { value: matched?.value || "", key: props.fkey });
    } else if (props.type === "date") {
      emit("update:value", newVal);
      emit("change", { value: newVal, key: props.fkey });
    } else if (props.type === "upload") {
      emit("update:value", newVal);
      emit("change", { value: newVal, key: props.fkey });
    } else if (props.type === "dropdown") {
      const matched = props.columns.find((opt) => opt.text === newVal);
      emit("update:value", matched?.value || "");
      emit("change", { value: matched?.value || "", key: props.fkey });
    }
  }
);

watch(
  () => props.value,
  (newVal) => {
    if (isUploading.value) return;
    if (props.type === "date") {
      inputValueDoc.value = newVal ? dayjs(newVal).format("YYYY-MM-DD") : "";
    } else if (props.type === "select") {
      const matched = props.columns.find((opt) => opt.value === newVal);
      inputValueDoc.value = matched?.text || "";
      selectedValue.value = matched ? [matched.value] : [];
    } else if (props.type === "upload") {
      uploader.value = props.value
        ? [{ url: absoluteUrl(String(props.value)) }]
        : [];
      console.log(uploader.value, 198);
      inputValueDoc.value = props.value || "";
    } else if (props.type === "dropdown") {
      const matched = props.columns.find((opt) => opt.value === newVal);
      inputValueDoc.value = matched?.text || "";
      selectedValue.value = matched ? [matched.value] : [];
    } else {
      inputValueDoc.value = newVal || "";
    }
  },
  { immediate: true }
);

function handleBlur(event) {
  emit("blur", event);
}

function handleFocus(event) {
  emit("focus", event);
}

function handleClear() {
  inputValueDoc.value = "";
  emit("update:value", "");
  emit("clear");
}

function onActionSheetConfirm(value) {
  const selectedText = value.text || value.name || "";
  inputValueDoc.value = selectedText;
  showPicker.value = false;
  const matched = props.columns.find(
    (opt) => opt.text === selectedText || opt.name === selectedText
  );
  emit("update:value", matched?.value || "");
  emit("change", { value: matched?.value || "", key: props.fkey });
}

function onPickerConfirm(event) {
  const { value } = event;
  const selectedItem =
    Array.isArray(value) && value.length > 0 ? value[0] : value;
  const matched = props.columns.find(
    (opt) => opt.value === selectedItem || opt.value === selectedItem?.value
  );
  if (matched) {
    inputValueDoc.value = matched.text;
    emit("update:value", matched.value);
    emit("change", { value: matched.value, key: props.fkey });
  }
  showPicker.value = false;
}

function onDateConfirm(event) {
  const { formatted } = event;
  inputValueDoc.value = formatted;
  showPicker.value = false;
  emit("update:value", formatted);
  emit("change", { value: formatted, key: props.fkey });
}
</script>

<style scoped lang="scss">
@import "@/uni.scss";


.form-group {
  width: 100%;
  margin-bottom: px2rpx(12);
  transform: none;
}

.form-label {
  font-size: var(--font-size-16);
  line-height: px2rpx(44);
  letter-spacing: px2rpx(1);
  color: #474747;
  margin-bottom: px2rpx(4);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: flex;
  align-items: center;

  .required-mark {
    color: red;
  }
}

.form-input {
  width: 100%;
  border: 1px solid var(--border) !important;
  border-radius: 10px !important;
  font-size: px2rpx(31) !important;
  margin-top: px2rpx(4) !important;
  padding: px2rpx(10) px2rpx(12) !important;
  box-sizing: border-box;
}

.search-field {
  background: var(--black);
  border: none !important;
  padding-left: px2rpx(10) !important;
}

.uploader {
  border: none !important;
  background: transparent !important;
  padding-left: 0;
  padding-right: 0;
  width: 100%;
}

.input-wrapper {
  position: relative;
  width: 100%;

  .input-bg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 100;
  }
}

// uview-plus 组件样式覆盖
:deep(.u-input) {
  border-radius: 10px !important;
  font-size: px2rpx(31) !important;
  padding: px2rpx(12);
  background: transparent;
  color: var(--white);

  &::after {
    border: none !important;
  }
}

:deep(.up-input__content__field-wrapper__field) {
  color: var(--white);
  line-height: px2rpx(22);

  &::placeholder {
    color: var(--lable) !important;
  }
}

:deep(.up-icon) {
  color: var(--black1) !important;
}

:deep(.u-upload__wrap) {
  width: 100%;

  >view {
    width: 100% !important;
  }

  .u-upload__wrap__preview__image {
    width: 100% !important;
    height: px2rpx(160) !important;
    border-radius: px2rpx(4);
  }

  .u-upload__deletable {
    width: px2rpx(24) !important;
    height: px2rpx(24) !important;
    background-color: rgba(0, 0, 0, 0.6) !important;
  }

  .u-icon__icon {
    width: px2rpx(18) !important;
    height: px2rpx(18) !important;
    font-size: px2rpx(18) !important;
  }
}
</style>