<!-- Created by henian.xu on 2018/9/19. -->

<template>
    <div class="lat-lng-picker">
        <div
            :class="['inner',{'empty':!isModel},{disabled:isDisabled}]"
            @click="onPicker"
        >
            <div class="label">
                <template v-if="isModel">
                    {{ value }}
                </template>
                <template v-else>
                    {{ placeholder }}
                </template>
            </div>
        </div>
        <el-dialog
            :title="dialogTitle"
            width="50%"
            :visible.sync="dialog.visible"
            append-to-body
            center
        >
            <div class='lat-lng-picker-body'>
                <baidu-map
                    class="lat-lng-picker-map"
                    :center="centerLatLng"
                    :zoom="zoom"
                    :scroll-wheel-zoom="true"
                    :map-click="false"
                    @zoomend="syncCenterAndZoom"
                    @click="onMapClick"
                >
                    <bm-marker
                        v-if="isSelected"
                        :position="currentLatLng"
                        animation="BMAP_ANIMATION_BOUNCE"
                    />
                    <bm-geolocation
                        anchor="BMAP_ANCHOR_BOTTOM_RIGHT"
                        :show-address-bar="true"
                        :auto-location="true"
                    />
                    <bm-control :style="{width: '100%'}">
                        <bm-auto-complete
                            v-model="keyword"
                            :sug-style="{zIndex: 9999999999}"
                        >
                            <el-input
                                :placeholder="$$t('vmf_place_name_key', '请输入地名关键字')"
                                v-model="keyword"
                            />
                        </bm-auto-complete>
                    </bm-control>
                    <bm-local-search
                        v-show="false"
                        :keyword="keyword"
                        :auto-viewport="true"
                    />
                </baidu-map>
                <el-form
                    v-if='addressEditable'
                    class='lat-lng-picker-form'
                    inline
                    size="mini"
                    label-position="right"
                    label-width="6em"
                >
                    <el-form-item
                        label-width="3em"
                        :label="$$t('vmf_name', '名称')"
                    >
                        <el-input
                            v-model="dialog.formModel.name"
                        />
                    </el-form-item>
                    <el-form-item
                        label-width="3em"
                        :label="$$t('vmf_address', '地址')"
                    >
                        <el-input
                            v-model="dialog.formModel.address"
                        />
                    </el-form-item>
                </el-form>
            </div>
            <div
                slot="footer"
                class="dialog-footer"
            >
                <el-button
                    type="primary"
                    @click="onConfirm"
                >
                    {{ $$t('vmf_confirm', '确 定') }}
                </el-button>
                <el-button
                    type="danger"
                    @click="onClear"
                >
                    {{ $$t('vmf_clear', '清 空') }}
                </el-button>
                <el-button @click="dialog.visible = false">
                    {{ $$t('vmf_cancel', '取 消') }}
                </el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
import emitter from 'element-ui/src/mixins/emitter';
import coordtransform from 'coordtransform';

export default {
    name: 'LatLngPicker',
    mixins: [emitter],
    inject: {
        elForm: {
            default: '',
        },
        elFormItem: {
            default: '',
        },
    },
    data() {
        return {
            dialog: {
                visible: false,
                formModel: {
                    name: '',
                    address: '',
                },
            },
            zoom: 15,
            currentLatLng: {
                lat: 0,
                lng: 0,
            },
            keyword: '',
        };
    },
    props: {
        value: {
            type: [String, Object],
            required: true,
            default: '',
        },
        returnType: {
            type: [String, Number],
            default: '1',
        },
        placeholder: {
            type: String,
            default() {
                return this.$$t('vmf_please_select_coordinates', '请选择坐标');
            },
        },
        disabled: {
            type: Boolean,
            default: false,
        },
    },
    computed: {
        returnType_() {
            return +this.returnType || 0;
        },
        model: {
            get() {
                const { value, returnType_: returnType } = this;
                if (returnType === 1) {
                    const val = value || '';
                    const valArr = val.split(',');
                    if (valArr.length < 2) {
                        return {};
                    }
                    let bd09Arr = [0, 0];
                    if (+valArr[0] && +valArr[1]) {
                        bd09Arr = coordtransform.gcj02tobd09(+valArr[0], +valArr[1]);
                    }
                    return {
                        lng: bd09Arr[0],
                        lat: bd09Arr[1],
                    };
                }
                let [lng, lat] = [0, 0];
                if (+value.lng && +value.lat) {
                    [lng, lat] = coordtransform.gcj02tobd09(+value.lng, +value.lat);
                }
                return {
                    ...value,
                    lng,
                    lat,
                };
            },
            set(val) {
                let value = val || '';
                if (this.returnType_ === 1) {
                    value = this.latLngToStr(val);
                }
                this.$emit('input', value);
                this.dispatch('ElFormItem', 'el.form.change', [value]);
            },
        },
        isModel() {
            return !!this.model.lat && !!this.model.lng;
        },
        isSelected() {
            return !!this.currentLatLng.lat && !!this.currentLatLng.lng;
        },
        centerLatLng() {
            return this.isModel ? this.model : { lng: 116.404, lat: 39.915 };
        },
        dialogTitle() {
            const { currentLatLng } = this;
            if (this.isSelected) {
                const gcj02Arr = coordtransform.bd09togcj02(currentLatLng.lng, currentLatLng.lat);
                return `${this.$$t('vmf_selected', '已选择')} (${gcj02Arr[0]},${gcj02Arr[1]})`;
            }
            return this.$$t('vmf_placeholder', '请选择');
        },
        isDisabled() {
            return this.disabled || (this.elForm || {}).disabled;
        },
        addressEditable() {
            return this.returnType_ === 2;
        },
    },
    watch: {
        model: {
            handler(val) {
                // if (!val || (val.lat === oldVal.lat && val.lng === oldVal.lng)) return;
                this.currentLatLng = {
                    lat: val.lat || 0,
                    lng: val.lng || 0,
                };
                this.dialog.formModel = {
                    name: val.name || '',
                    address: val.address || '',
                };
            },
            immediate: true,
        },
    },
    methods: {
        onPicker() {
            if (this.isDisabled) return;
            this.dialog.visible = true;
        },
        onMapClick($event) {
            const { point } = $event;
            this.currentLatLng = point;
        },
        latLngToStr(latLng) {
            if (!latLng || !latLng.lat || !latLng.lng) {
                return '';
            }
            // const gcj02Arr = coordtransform.bd09togcj02(latLng.lng, latLng.lat);
            return `${latLng.lng},${latLng.lat}`;
        },
        onClear() {
            this.$emit('input', {});
            this.dispatch('ElFormItem', 'el.form.change', [{}]);
            this.model = {};
            this.dialog.visible = false;
        },
        onConfirm() {
            const { dialog, model, currentLatLng } = this;
            const [lng, lat] = coordtransform.bd09togcj02(currentLatLng.lng, currentLatLng.lat);
            this.model = {
                ...model,
                ...dialog.formModel,
                lat,
                lng,
            };
            dialog.visible = false;
        },
        syncCenterAndZoom($event) {
            this.zoom = $event.target.getZoom();
        },
    },
};
</script>

<style lang="scss">
.lat-lng-picker {
    > .inner {
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        align-items: center;

        border: 1px solid #dcdfe6;
        border-radius: 4px;
        cursor: pointer;

        > .label {
            flex: 1 1 1%;
            padding: 0 $padding-small;
        }

        &.empty {
            > .label {
                opacity: 0.5;
            }
        }

        &.disabled {
            background-color: #f5f7fa;
            border-color: #e4e7ed;
            color: #c0c4cc;
            cursor: not-allowed;
        }
    }
}
.lat-lng-picker-body {
    height: 450px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    > .lat-lng-picker-map {
        flex: 1 1 1%;
    }
    > .lat-lng-picker-form {
        flex: 0 0 auto;
        margin-top: $margin;
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        align-items: flex-start;

        > .el-form-item {
            flex: 1 1 1%;
            display: flex;
            flex-direction: row;
            justify-content: space-between;
            align-items: flex-start;

            > .el-form-item__label {
                flex: 0 0 auto;
            }
            > .el-form-item__content {
                flex: 1 1 1%;
            }
        }
    }
}
</style>
