<template>
    <div class="form-group">
        <label class="form-label" v-if="label"
            ><span>{{ required ? '*' : '' }}</span> {{ label }}
        </label>
        <template v-if="type === 'text' || type == 'password'">
            <van-field
                class="form-input"
                v-model="inputValueDoc"
                :type="type"
                :placeholder="placeholder ? placeholder : t('common.input')"
                :readonly="readonly"
                :disabled="disabled"
                :clearable="clearable"
                :name="fkey"
                :rules="[...rules]"
                :maxlength="maxlength"
                autocomplete="off"
                :error-message="errorMessage"
                @blur="handleBlur"
                @focus="handleFocus"
                @clear="handleClear"
            >
                <template #left-icon> <slot name="left-icon1"></slot> </template>
                <template #right-icon> <slot name="right-icon1"></slot> </template>
            </van-field>
        </template>
        <template v-if="type === 'number'">
            <van-field
                class="form-input"
                v-model="inputValueDoc"
                :name="fkey"
                type="number"
                :placeholder="placeholder ? placeholder : t('common.input')"
                :readonly="readonly"
                :disabled="disabled"
                :clearable="clearable"
                autocomplete="off"
                :rules="[...rules]"
                :maxlength="maxlength"
                :max="max"
                :error-message="errorMessage"
                @blur="handleBlur"
                @focus="handleFocus"
                @clear="handleClear"
                ><slot></slot
            ></van-field>
        </template>
        <template v-if="type === 'dropdown'">
            <van-field
                class="form-input"
                v-model="inputValueDoc"
                :name="fkey"
                :placeholder="placeholder ? placeholder : t('common.choose')"
                :readonly="true"
                :disabled="disabled"
                :clearable="clearable"
                :rules="[...rules]"
                :error-message="errorMessage"
                is-link
                @click="!disabled && (showPicker = true)"
                @clear="handleClear"
                ><slot></slot
            ></van-field>
            <van-action-sheet v-model:show="showPicker" :actions="filteredColumns" @select="onConfirm" />
        </template>
        <template v-if="type === 'select'">
            <van-field
                class="form-input"
                v-model="inputValueDoc"
                :name="fkey"
                :placeholder="placeholder ? placeholder : t('common.choose')"
                :readonly="true"
                :disabled="disabled"
                :clearable="clearable"
                :rules="[...rules]"
                :error-message="errorMessage"
                is-link
                @click="!disabled && (showPicker = true)"
                @clear="handleClear"
                ><slot></slot
            ></van-field>
            <MoreSelect :showSearch="showSearch" :input-value="inputValueDoc" :options="filteredColumns" v-model="showPicker" @select="onConfirm" />
        </template>
        <template v-if="type === 'date'">
            <van-field
                class="form-input"
                v-model="inputValueDoc"
                :name="fkey"
                :placeholder="placeholder ? placeholder : t('common.choose')"
                :readonly="true"
                :disabled="disabled"
                :rules="[...rules]"
                :clearable="clearable"
                :error-message="errorMessage"
                is-link
                @click="!disabled && (showPicker = true)"
                @clear="handleClear"
            />
            <van-calendar
                v-model:show="showPicker"
                :show-mark="false"
                :title="t('cards.selectDateRange')"
                :subtitle="t('cards.selectDate')"
                color="var(--main-yellow)"
                :min-date="minDate"
                :max-date="maxDate"
                :show-confirm="false"
                @cancel="showPicker = false"
                @confirm="onDateConfirm"
            />
        </template>
        <template v-if="type === 'upload'">
            <van-field name="uploader" class="form-input uploader" :rules="[...rules]">
                <template #input>
                    <van-uploader
                        :disabled="disabled"
                        :accept="accept"
                        v-model="uploader"
                        :max-count="1"
                        :after-read="afterRead"
                        v-if="!isUploadD"
                    ></van-uploader>
                    <van-uploader :disabled="disabled" v-model="uploader" :max-count="1" :after-read="afterRead" v-if="isUploadD">
                        <slot></slot>
                    </van-uploader>
                </template>
            </van-field>
        </template>
    </div>
</template>

<script setup>
import dayjs from 'dayjs'
import { useI18n } from 'vue-i18n'
import { uploadApi } from '@/api/upload'
import { showLoadingToast, closeToast, showToast } from 'vant'
const { t } = useI18n()
const isUploading = ref(false)
const uploader = ref([])
const afterRead = async (file) => {
    isUploading.value = true
    showLoadingToast({
        message: '上传中...',
        forbidClick: true,
    })
    try {
        const result = await uploadApi.uploadFile(file.file)
        closeToast()
        inputValueDoc.value = result.data
        showToast('上传成功')
        setTimeout(() => {
            isUploading.value = false
        }, 100)
    } catch (error) {
        showToast('上传失败')
    }
}

const props = defineProps({
    type: { type: String, default: 'text', validator: (v) => ['text', 'password', 'number', 'select', 'date'].includes(v) },
    label: String,
    fkey: 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) },
    maxDate: { type: Date, default: () => new Date(2050, 11, 31) },
    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 inputValueDoc = ref('')
const selectedValue = ref([])
const showPicker = ref(false)
const loading = ref(false)
const searchText = ref('')

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 (!newVal || 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)
            if (props.fkey == 'areaCode') {
                inputValueDoc.value = matched?.text.match(/\+ \d+$/)[0]
            } else {
                inputValueDoc.value = matched?.text || ''
            }

            selectedValue.value = [matched?.value]
        } else if (props.type === 'upload') {
            uploader.value = [{ url: props.value }]
            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?.value]
        } else {
            inputValueDoc.value = newVal
        }
    },
    { immediate: true },
)

const handleBlur = (event) => {
    emit('blur', event)
}

const handleFocus = (event) => {
    emit('focus', event)
}

const handleClear = () => {
    inputValueDoc.value = ''
    emit('update:value', '')
    emit('clear')
}

const onConfirm = (value) => {
    let selectedText = value.text || ''
    console.log(props.fkey, value.text, 11)
    if (props.fkey == 'areaCode') {
        selectedText = selectedText.match(/\+ \d+$/)[0]
    }

    inputValueDoc.value = selectedText
    showPicker.value = false
}

const onDateConfirm = (value) => {
    const formatted = dayjs(value).format('YYYY-MM-DD')
    inputValueDoc.value = formatted
    showPicker.value = false
    emit('update:value', formatted)
}
</script>

<style scoped lang="scss">
.form-group {
    width: 100%;
    margin-bottom: 24px;
    transform: none;
}

.form-label {
    font-size: var(--font-size-16);
    line-height: 24px;
    letter-spacing: 1px;
    color: #474747;

    span {
        color: red;
    }
}

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

    ::v-deep .van-field__control {
        &::placeholder {
            color: var(--lable) !important;
        }
    }
}
:deep(.van-action-sheet) {
    min-height: 20vh;
    max-height: 50vh;
}
.search-field {
    background: var(--black);
    border: none !important;
    padding-left: 20px !important;
}
.uploader {
    border: none !important;
    background: transparent !important;
    padding-left: 0;
    padding-right: 0;
}
::v-deep .van-popup {
    background: var(--black);
}
:deep(.van-icon) {
    height: 22px;
    color: var(--black1) !important;
    line-height: 22px;
}
::v-deep .van-field {
    background: transparent;
    color: var(--white);
}
::v-deep .van-field__control {
    color: var(--white);
    line-height: 22px;
}
::v-deep .van-calendar {
    background: var(--black);
}
::v-deep .van-picker {
    background: var(--black);
}
::v-deep .van-picker__columns {
    background: var(--black);
}
::v-deep .van-calendar__month-mark {
    display: none;
}
::v-deep .van-calendar__header-subtitle {
    color: var(--white);
}
::v-deep .van-calendar__header-title {
    color: var(--white);
}
::v-deep .van-calendar__month-title {
    color: var(--main-yellow);
}
::v-deep {
    .van-picker {
        background: var(--black);

        .van-picker__toolbar {
            background: var(--black);
            border-bottom: 1px solid #333;
            height: 44px;
            padding: 0 16px;

            .van-picker__title {
                color: #fff;
                font-size: var(--font-size-16);
                font-weight: 500;
            }

            .van-picker__cancel,
            .van-picker__confirm {
                color: var(--white);
                font-size: var(--font-size-14);
                padding: 0 8px;
                height: 28px;
                line-height: 28px;
                border-radius: 14px;
                transition: all 0.3s ease;

                &:active {
                    opacity: 0.8;
                    background: rgba(255, 193, 7, 0.1);
                }
            }
        }

        .van-picker-column {
            color: var(--white);

            .van-picker-column__item {
                color: var(--white);
                font-size: var(--font-size-14);
                padding: 0 16px;
                height: 44px;
                line-height: 44px;
                transition: all 0.3s ease;

                &--selected {
                    color: var(--main-yellow);
                    font-weight: 500;
                    font-size: var(--font-size-16);
                }

                &:active {
                    background: rgba(255, 255, 255, 0.05);
                }
            }

            .van-picker-column__wrapper {
                &::after {
                    border-color: #333;
                }
            }
        }

        .van-picker__indicator {
            height: 44px;
        }
    }
}
</style>
