<template>
    <view class="address" :class="'address--layout' + layout">
        <!-- 无地址 -->
        <template v-if="formInfo && formInfo.length">
            <view class="address__not">
                <address-form
                    class="address-form"
                    :area-infos="areaInfos"
                    :placesuggestion="apis.placesuggestion"
                    :forms="formInfo"
                    :region-url="apis.regionlist"
                    api-host="go"
                    @selectAreaTap="changgeAddressFormState(true)"
                    @changeAreaInfo="changeAreaInfo"
                    @formBlur="addressFormBlur"
                />
                <address-popup
                    :area-infos="areaInfos"
                    :region-url="apis.regionlist"
                    :show="showAddressForm"
                    api-host="go"
                    @changeAddress="changeAddress"
                    @popupClose="changgeAddressFormState(false)"
                />
            </view>
        </template>
        <!-- 有地址 样式1 -->
        <template v-else-if="layout === 1">
            <view class="address__have" @tap="onJump(data.addressListUrl)">
                <view class="address__have__icon">
                    <c-icon
                        name="location-crude"
                        font-size="0.16rem"
                        class="modal-title-right"
                    />
                </view>
                <view class="address__have__info c-gap-right">
                    <view
                        class="address__have__info__province c-font-15 c-color-gray"
                    >{{ areaInfos.regionData }}</view>
                    <view
                        class="address__have__info__town c-font-big-less c-color-title"
                    >{{ areaInfos.address }}</view>
                    <view class="c-font-15 c-color-title">
                        <text class="address__have__info__name">{{ areaInfos.name }}</text>
                        <text>{{ areaInfos.mobile }}</text>
                    </view>
                </view>
                <view>
                    <c-icon
                        name="right"
                        font-size="0.12rem"
                        class="modal-title-right"
                        style="color: #858585"
                    />
                </view>
            </view>
        </template>
        <!-- 有地址 样式2 -->
        <template v-else-if="layout === 2">
            <!-- 样式2 -->
            <view class="order__adress">
                <view class="order__adress__icon">
                    <c-icon
                        name="location-crude"
                        font-size="0.16rem"
                        class="modal-title-right"
                    />
                </view>
                <view class="order__adress__text">
                    <view class="order__adress__name c-font-big">{{ data.name }}  {{ data.phone }}</view>
                    <view class="order__adress__detail c-font-15">
                        {{ data.province }}{{ data.city }}{{ data.district }}{{ data.town }}{{ data.showText }}
                    </view>
                </view>
            </view>
        </template>
    </view>
</template>

<script>
import CIcon from '@baidu/med-ui/components/Icon/Icon';
import AddressPopup from '@components/common/address-popup';
import AddressForm from '@components/gy/address-form';
import {navigate} from '@utils/navigate';
import {deepCopy} from '@utils/core';
import {isEmojiCharacter, isValidPhone} from '@utils/validate';
import {request} from '@utils/request';
import * as conf from '@utils/conf';
import {debounce} from '@utils/core';
/**
 * @file 基因检测-地址模块
 * @author mayifan02
 * @categories 业务组件
 * @tags [component]
 */
export default {
    config: {
        component: true
    },
    options: {
        addGlobalClass: true
    },
    components: {
        CIcon,
        AddressPopup,
        AddressForm
    },
    props: {
        /* 数据 */
        data: {
            type: Object,
            default: () => {
                return {};
            }
        },
        /** layout */
        layout: {
            type: Number,
            default: 1
        }
    },
    watch: {
        data(n, o) {
            if (n) {
                this.initComponentData();
            }
        }
    },
    created() {
        this.initComponentData();
    },
    data() {
        return {
            // 用户地址选择的信息
            areaInfos: {},
            // 表单信息
            formInfo: [],
            // 经纬度转地址
            getTownUrl: '/med/api/latlng2ad?vn=med',
            // 显示添加地址
            showAddressForm: false,
            // 上一次blur时候的form值
            preForms: null,
            // 经纬度信息
            location: {},
            // api地址
            apis: {}
        };
    },
    methods: {
        // 跳转
        onJump(url) {
            if (url) {
                navigate({
                    url
                });
            }
        },
        // 初始化组件数据
        initComponentData() {
            const data = JSON.parse(JSON.stringify(this.data || {}));
            // 表单数据
            this.formInfo = data.formInfo;
            // 默认地址数据
            this.areaInfos = data.areaData;
            // api数据
            this.apis = {
                placesuggestion: data.placesuggestion,
                regionlist: data.regionlist
            };
        },
        // sug change
        changeAreaInfo(areaInfo) {
            const location = areaInfo.location;
            const lat = location && location.lat;
            const lng = location && location.lng;
            if (lat && lng) {
                const townUrl = `${conf.apiHost}${this.getTownUrl}&lat=${lat}&lng=${lng}`;

                request({
                    url: townUrl,
                    method: 'GET',
                    isFirstScreen: true,
                    isNeedLogin: true
                })
                    .then(({data}) => {
                        const addressInfo = data && data.addressComponent;
                        const areaInfos = {
                            province: addressInfo.province || '',
                            city: addressInfo.city || '',
                            county: addressInfo.county || addressInfo.district || '',
                            district: addressInfo.county || addressInfo.district || '',
                            town: addressInfo.town || '',
                            street: addressInfo.street || ''
                        };

                        if (addressInfo.town !== this.areaInfos.town) {
                            const area = `${addressInfo.province || ''}${addressInfo.city || ''}${
                                addressInfo.county || addressInfo.district || ''
                            }${addressInfo.town || ''}`;

                            this.$api.showToast({
                                icon: 'none',
                                title: '已同步修改所在地区',
                                duration: 2000
                            });
                            this.$set(this.formInfo[areaInfo.addressIndex], 'value', area);
                            this.$set(this, 'areaInfos', areaInfos);

                            // 地区不同才触发重新计算运费
                            if ((addressInfo.county !== this.areaInfos.county) && this.validate(false)) {
                                this.questPostage();
                            }
                        }
                    })
                    .catch(({data}) => {
                        this.$api.showToast({
                            title: '获取街镇信息错误',
                            icon: 'none'
                        });
                        const areaInfos = {
                            province: areaInfo.province || '',
                            city: areaInfo.city || '',
                            county: areaInfo.county || areaInfo.district || '',
                            district: areaInfo.county || areaInfo.district || '',
                            town: areaInfo.town || '',
                            street: areaInfo.street || ''
                        };
                        const area = `${areaInfo.province || ''}${areaInfo.city || ''}${
                            areaInfo.county || areaInfo.district || ''
                        }${areaInfo.town || ''}`;
                        if (areaInfo.city !== this.areaInfos.city) {
                            this.questPostage();
                        }
                        this.$set(this.formInfo[areaInfo.addressIndex], 'value', area);
                        this.$set(this, 'areaInfos', areaInfos);
                    });
            }
        },
        // 地址弹窗change
        changeAddress(params) {
            const value = `${params.province}${params.city}${params.county}${params.town}`;
            let oldAreaValue;
            
            this.changgeAddressFormState(false);
            this.areaInfos = params;
            this.formInfo.forEach(item => {
                if (item.inputName === 'area') {
                    oldAreaValue = item.value;
                    this.$set(item, 'value', value);
                }
            });
            // 获取经纬度
            this.locationChange(value);
            // 省市区不同，进行运费计算
            if (oldAreaValue !== value && this.validate(false)) {
                this.questPostage();
            }
        },
        // 更改地址编辑显示状态
        changgeAddressFormState(state) {
            this.showAddressForm = state;
        },
        // 地址转经纬度
        locationChange(address) {
            if (!address) {
                return;
            }
            request({
                url: conf.apiHost + '/med/api/ad2latlng?vn=med',
                data: {address},
                method: 'GET',
                isFirstScreen: true,
                isNeedLogin: true
            })
                .then(({data}) => {
                    if (data.toast) {
                        return;
                    }
                    let location = data && data.location;
                    Object.assign(this.location, {
                        lat: location.lat,
                        lng: location.lng
                    });
                })
                .catch(({data}) => {
                    this.$api.showToast({
                        title: '请求错误，收货地址解析失败',
                        icon: 'none'
                    });
                });
        },
        addressFormBlur(forms) {
            // 地址校验
            if (!this.validate(false)) {
                return;
            }
            if (!this.preForms) {
                this.questPostage();
            } else {
                const dif = forms.every((item, index) => {
                    return item.value === this.preForms[index].value;
                });
                !dif && this.questPostage();
            }
            this.$set(this, 'preForms', deepCopy(forms));
        },
        // 校验表单
        validate(showToast = true) {
            let formInfo = this.formInfo;
            for (let i = 0, len = formInfo.length; i < len; i++) {
                let form = formInfo[i];
                // 必填项检验
                if (form.required === '1' && !form.value) {
                    showToast && this.$api.showToast({
                        title: form.msg,
                        icon: 'none'
                    });
                    this.$set(form, 'focus', true);
                    return false;
                }
                // 校验input类型
                if (form.type === 'input' || form.type === 'tel' || form.type === 'chooseLocation') {
                    // 去掉首尾空格
                    form.value = this.trim(form.value);
                    // 校验手机号码
                    if (form.inputName === 'mobile' && !isValidPhone(form.value, this.pageType === 'edit')) {
                        showToast && this.$api.showToast({
                            title: '手机号格式错误',
                            icon: 'none'
                        });
                        this.$set(formInfo[i], 'focus', true);
                        return false;
                    }
                    // 校验输入长度
                    if (
                        typeof form.value === 'string' &&
                        form.required !== '0' &&
                        (form.value.length < form.minlength || form.value.length > form.maxlength)
                    ) {
                        // 错误提示
                        showToast && this.$api.showToast({
                            title: form.title + '应为' + form.minlength + '-' + form.maxlength + '个字',
                            icon: 'none'
                        });
                        this.$set(formInfo[i], 'focus', true);
                        return false;
                    }
                    // 校验表情符号
                    if (isEmojiCharacter(form.value)) {
                        showToast && this.$api.showToast({
                            title: form.msg,
                            icon: 'none'
                        });
                        this.$set(formInfo[i], 'focus', true);
                        return false;
                    }
                }
            }
            return true;
        },

        // 重新算价(后端限制1s，所以600ms没啥问题)
        questPostage: debounce(function () {
            this.__questPostage();
        }, 600, true),
        __questPostage() {
            /** 重新算价 */
            this.$emit('questPostage');
        },
        // 去空格
        trim(str) {
            if (typeof str === 'string') {
                return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
            }
        },
        // 获取用户填写地址的结果
        getUserResult(isValidate, showToast) {
            // 表单校验
            if (isValidate && !this.validate(!!showToast)) {
                return;
            }
            
            let result = {};
            const formInfo = this.formInfo;

            if (formInfo && formInfo.length) {
                formInfo.forEach(item => {
                    result[item.inputName] = item.value;
                });
                result = Object.assign(result, this.location, this.areaInfos);
            }
            return result;
        }
    }
};
</script>

<style lang="less" scoped>
.img-background {
    background-size: 100% auto;
    background-position: 0 0;
    background-repeat: no-repeat;
}
.address--layout1 {
    .address {
        &__have {
        background-color: #fff;
        border-radius: 0.12rem;
        padding: 0.1rem 0.13rem;
        display: flex;
        align-items: center;
        &__icon {
            width: 0.3rem;
            height: 0.3rem;
            line-height: 0.3rem;
            text-align: center;
            background-image: linear-gradient(90deg, #fd503e 0%, #f7603e 100%);
            border-radius: 50%;
            margin-right: 0.08rem;
            color: #fff;
            margin-top: 0.05rem;
            align-self: flex-start;
        }
        &__info {
            flex: 1;
            overflow: hidden;
            &__town {
                font-weight: bold;
            }
            &__name {
                margin-right: 0.08rem;
            }
        }
    }
    }
}
.address--layout2 {
    .order__adress {
        width: 100%;
        background-color: #FFFFFF;
        border-radius: 0.12rem;
        display: flex;
        margin-bottom: 0.08rem;
        padding-bottom: 0.11rem;
        &__icon {
            width: 0.3rem;
            height: 0.3rem;
            line-height: 0.3rem;
            text-align: center;
            background-image: linear-gradient(90deg, #fd503e 0%, #f7603e 100%);
            border-radius: 50%;
            color: #fff;
            margin: 0.21rem 0.08rem 0 0.13rem;
            align-self: flex-start;
        }
        &__text {
            width: 2.55rem;
            .order__adress__name {
                color: #1F1F1F;
                letter-spacing: 0;
                margin: 0.11rem 0 0 0;
                font-weight: bold;
            }
            .order__adress__detail {
                color: #858585;
                letter-spacing: 0;
                line-height: 0.21rem;
            }
        }
    }
}

</style>
