<template>
    <view class="address-popup">
        <c-popup
            :show="show"
            :show-close="true"
            :title="title"
            :row-tile="true"
            :scroll-view="false"
            :show-title-line="showTitleLine"
            :height="'8.76rem'"
            :max-height="'80%'"
            :show-close-handler="false"
            :scroll-in-to-view="scrollInToView"
            :scroll-with-animation="false"
            :close-icon="closeIcon"
            :close-icon-size="closeIconSize"
            :title-style="titleStyle"
            :border-radius="borderRadius"
            @close="handlePopupClose"
        >
            <view
                v-if="tabs && tabs.length"
                slot="topSlot"
                class="address-popup__tab c-gap-left-large c-gap-right-large"
            >
                <c-tabs
                    :selected="selectedIndex"
                    :wrap-style="{
                        background: '#fff',
                        display: 'flex',
                        height: '0.46rem',
                        lineHeight: '0.46rem',
                    }"
                    :selected-style="{color: selectedStyle}"
                    :item-style="tabItemStyle"
                    :data="tabs"
                    @handleItemTap="handleTabTap"
                />
                <view class="c-line-superfine-after"/>
            </view>
            <view class="address-popup__content">
                <view class="address-popup__areabox c-gap-left-boundary c-gap-right-boundary">
                    <view v-if="hotList.length && !tabs.length" class="address-popup__hotarea">
                        <view class="address-popup__hotarea__title c-font-normal">热门城市</view>
                        <view class="address-popup__hotarea__tagbox">
                            <view
                                v-for="(area, idx) in hotList"
                                :key="`${area}_${idx}`"
                                class="address-popup__hotarea__tag c-color c-font-normal"
                                @tap.stop="hotTagTap(area)"
                            >{{ area.name }}</view>
                        </view>
                    </view>
                    <view v-if="currentAreaList.length" class="address-popup__areacontainer">
                        <view v-if="currentTitle" class="address-popup__area__title">{{ currentTitle }}</view>
                        <view
                            v-for="(area, areaIndex) in currentAreaList"
                            :key="`${area}_${areaIndex}`"
                            class="address-popup__area"
                            @tap.stop="tagTap(area)"
                        >
                            <view class="address-popup__area__pre">
                                <text
                                    v-if="area.name_py_init"
                                    :id="area.name_py_init"
                                    class="address-popup__area__pretext"
                                >{{
                                    area.name_py_init
                                }}</text>
                            </view>
                            <view class="address-popup__area__name">{{ area.name }}</view>
                        </view>
                    </view>
                </view>
            </view>
            <!-- todo 滑动穿透问题导致无法定位 -->
            <!-- <view v-if="showLetter" class="address-popup__nav">
                <view
                    v-for="(item, index) in letter"
                    :key="index"
                    class="address-popup__nav__item"
                    @tap.stop="navTap(item)"
                >
                    {{ item }}
                </view>
            </view> -->
        </c-popup>
    </view>
</template>

<script>
import CPopup from '@baidu/med-ui/components/Popup/Popup';
import CTabs from '@baidu/med-ui/components/Tabs/Tabs';
import {request} from '@utils/request';
import * as conf from '@utils/conf';

/**
 * @author kangpuqing01
 * @file 地址选择popup组件
 * @categories 通用组件
 * @tags [component]
 */

const PROVINCE = 'province';
const CITY = 'city';
const COUNTY = 'county';
const TOWN = 'town';
const TAG = 'tag';
const TAB = 'tab';

export default {
    config: {
        component: true
    },
    components: {
        CPopup,
        CTabs
    },
    props: {
        /**
         * 请求地址类型
         */
        apiHost: {
            type: String,
            default: '56'
        },
        /**
         * show
         * @param
         */
        show: {
            type: Boolean,
            default: false
        },
        /**
         * regionUrl 访问获取区域地址url
         * @param
         */
        regionUrl: {
            type: String,
            default: ''
        },
        /**
         * areaInfos 默认信息
         * @param
         */
        areaInfos: {
            type: Object,
            default: () => {
                return {
                    province: '',
                    city: '',
                    county: '',
                    town: ''
                };
            }
        },
        /**
         * disableTownLevel 阻止town层级的选择
         * @param
         */
        disableTownLevel: {
            type: Boolean,
            default: false
        },
        /**
         * selectedStyle 选中区域tab的颜色
         * @param
         */
        selectedStyle: {
            type: String,
            default: '#FD503E'
        },
        showTitleLine: {
            type: Boolean,
            default: true
        },
        titleStyle: {
            type: Object
        },
        borderRadius: {
            type: String,
            default: '13px'
        },
        closeIcon: {
            type: String
        },
        closeIconSize: {
            type: String
        }
    },
    data() {
        return {
            id: 'CHN',
            pageLoading: true,
            hotList: [],
            title: '请选择所在地区',
            tabItemStyle: {
                width: 'auto',
                'margin-right': '.2rem',
                'font-size': '.15rem',
                'line-height': '0.46rem'
            },
            currentTab: PROVINCE,
            currentProvince: '',
            provinceList: [],
            currentCity: '',
            cityList: [],
            currentCounty: '',
            countyList: [],
            currentTown: '',
            townList: [],
            letter: [],
            scrollInToView: '',
            showLetter: false
        };
    },
    mounted() {
        if (this.regionUrl) {
            this.getFirstview();
        }
    },
    watch: {
        regionUrl(nUrl) {
            if (nUrl) {
                // 获取地址数据
                this.getFirstview();
            }
        },
        show(nShow) {
            // 显示的时候判断数据变更，初始化状态
            if (nShow) {
                // 各个级是否有变动
                if (this.areaInfos.province && (!this.currentProvince || (this.currentProvince.name !== this.areaInfos.province))) {
                    this.init(PROVINCE);
                } else if (this.areaInfos.city && (!this.currentCity || (this.currentCity.name !== this.areaInfos.city))) {
                    this.init(CITY);
                } else if (this.areaInfos.county && (!this.currentCounty || (this.currentCounty.name !== this.areaInfos.county))) {
                    this.init(COUNTY);
                } else if (this.areaInfos.town && (!this.currentTown || (this.currentTown.name !== this.areaInfos.town))) {
                    this.init(TOWN);
                }
            }
        }
    },
    computed: {
        currentAreaList() {
            let list = this[`${this.currentTab}List`];
            list = this.filterData(list);
            return list;
        },
        currentTitle() {
            return this.currentTab === PROVINCE ? '按省份/地区' : '';
        },
        tabs() {
            const tabMap = ['currentProvince', 'currentCity', 'currentCounty', 'currentTown'];
            const tabList = [];
            const tagList = [TOWN];
            let lastTag = null;

            tabMap.forEach(name => {
                if (this[name]) {
                    tabList.push({
                        text: this[name].name,
                        tag: this[name]
                    });
                    lastTag = this[name];
                }
            });

            this.disableTownLevel && tagList.push(COUNTY);

            if (lastTag && !tagList.includes(lastTag.type)) {
                tabList.push({
                    text: '请选择',
                    tag: {
                        type: lastTag.leafType,
                        name: '请选择',
                        useless: true
                    }
                });
            }
            // todo 增加街道默认不选择按钮
            return tabList;
        },
        selectedIndex() {
            const map = {
                province: 0,
                city: 1,
                county: 2,
                town: 3
            };
            return map[this.currentTab];
        },
        host() {
            return this.apiHost === '56' ? conf.apiHost : conf.goApiHost;
        }
    },
    methods: {
        // 获取首屏数据
        getFirstview() {
            this.questList(this.id, true);
        },
        async init(type) {
            let tabType;

            this.reset(type);
            switch (type) {
                case PROVINCE:
                    const id = 'CHN';
                    await this.changeListAndCur(type, id);
                    await this.changeListAndCur(CITY, this.currentProvince.id);
                    tabType = CITY;
                    if (this.areaInfos.city) {
                        await this.changeListAndCur(COUNTY, this.currentCity.id);
                        tabType = COUNTY;
                    }
                    if (this.areaInfos.county) {
                        await this.changeListAndCur(TOWN, this.currentCounty.id);
                        tabType = TOWN;
                    }
                    break;
                case CITY:
                    await this.changeListAndCur(type, this.currentProvince.id);
                    await this.changeListAndCur(COUNTY, this.currentCity.id);
                    tabType = COUNTY;
                    if (this.areaInfos.county) {
                        await this.changeListAndCur(TOWN, this.currentCounty.id);
                        tabType = TOWN;
                    }
                    break;
                case COUNTY:
                    await this.changeListAndCur(type, this.currentCity.id);
                    await this.changeListAndCur(TOWN, this.currentCounty.id);
                    tabType = TOWN;
                    break;
                case TOWN:
                    await this.changeListAndCur(type, this.currentCounty.id);
                    tabType = TOWN;
                    break;
            }
            this.$set(this, 'currentTab', tabType);
        },
        changeListAndCur(type, id) {
            return new Promise((res, rej) => {
                let cur;
                this.questList(id, true).then(() => {
                    const name = type.slice(0, 1).toUpperCase() + type.slice(1).toLowerCase();

                    cur = this[`${type}List`].find(item =>
                        item.name === this.areaInfos[type]
                    ) || '';
                    this.$set(this, `current${name}`, cur);
                    res();
                });
            });
        },
        /**
         * @description: 是否阻止城镇一级的显示
         * @param {*} tag 地址信息
         * @return {*} 是否阻止显示
         */
        whetherDisableTownLevel(tag) {
            return tag && tag.type === COUNTY && this.disableTownLevel;
        },
        /**
         * @description: 切换tab类型
         * @param {*} tag 地址信息
         * @param {*} type 切换类型
         * @return {*}
         */
        switchCurrentTab(tag, type) {
            const disableTownLevel = this.whetherDisableTownLevel(tag);
            switch (tag.type) {
                case PROVINCE:
                    tag.useless ? '' : (this.currentProvince = tag);
                    type === TAB ? (this.currentTab = PROVINCE) : (this.currentTab = CITY);
                    break;
                case CITY:
                    tag.useless ? '' : (this.currentCity = tag);
                    type === TAB ? (this.currentTab = CITY) : (this.currentTab = COUNTY);
                    break;
                case COUNTY:
                    tag.useless ? '' : (this.currentCounty = tag);
                    if (type === TAB) {
                        this.currentTab = COUNTY;
                    } else {
                        this.currentTab = disableTownLevel ? COUNTY : TOWN;
                        this.currentTown = '';
                        this.townList = [];
                    }
                    break;
                case TOWN:
                    tag.useless ? '' : (this.currentTown = tag);
                    this.currentTab = TOWN;
                    break;
            }
            if (type === TAG && !disableTownLevel) {
                this.reset(this.currentTab);
            }
        },
        reset(type) {
            if (type === PROVINCE) {
                this.currentProvince = '';
                this.ProvinceList = [];
                this.currentCity = '';
                this.cityList = [];
                this.currentCounty = '';
                this.countyList = [];
                this.currentTown = '';
                this.townList = [];
            }
            if (type === CITY) {
                this.currentCity = '';
                this.cityList = [];
                this.currentCounty = '';
                this.countyList = [];
                this.currentTown = '';
                this.townList = [];
            }
            if (type === COUNTY) {
                this.currentCounty = '';
                this.countyList = [];
                this.currentTown = '';
                this.townList = [];
            }
        },
        handlePopupClose() {
            if (this.currentProvince && this.currentCity && this.currentCounty) {
                this.changeAddress();
            }
            /** 弹窗关闭 */
            this.$emit('popupClose');
        },
        // 地区tab选择只切换显示列表，不更新列表数据
        handleTabTap({index, tab}) {
            this.switchCurrentTab(tab.tag, TAB);
        },
        /**
         * @description: 热门城市点击只切换tab类型切换当前列表显示，不更新列表数据
         * @param {*} area 点击的地址信息
         * @return {*}
         */
        hotTagTap(area) {
            // 热门城市只考虑省市两级tag存在，超出不考虑
            this.switchCurrentTab(area, TAG);
            // 请求下一级地区列表
            this.questList(area.id, false);
            if (area.type === CITY) {
                // 请求本级地区列表
                this.questList(area.pid, false);
            }
        },
        // 请求下一级列表，或者更改地址数据
        tagTap(tag) {
            const disableTownLevel = this.whetherDisableTownLevel(tag);
            this.switchCurrentTab(tag, TAG);

            // 最后一级点击，修改数据，否着请求下一级数据
            // 设置 disableTownLevel 属性会去阻止城镇一级的选择，在county一级就去改变地址
            if (disableTownLevel || tag.type === TOWN) {
                this.changeAddress();
            } else {
                this.questList(tag.id, true);
            }
        },
        changeAddress() {
            const province = this.currentProvince;
            const city = this.currentCity;
            const county = this.currentCounty;
            const town = this.currentTown;
            const townName = town && town.name !== '暂不选择' ? town.name : '';

            /** changeAddress */
            this.$emit('changeAddress', {
                province: province && province.name,
                provinceId: province && province.id,
                city: city && city.name,
                cityId: city && city.id,
                county: county && county.name,
                countyId: county && county.id,
                district: county && county.name,
                districtId: county && county.id,
                town: townName,
                townId: (town && town.id) || ''
            });
        },
        /**
         * @description: 请求列表数据
         * @param {String} id 请求地址id
         * @param {Boolean} leafs 是否请求子节点信息
         * @return {*}
         */
        questList(id, leafs = true) {
            const url = `${this.host}${this.regionUrl}&id=${id}&leafs=${leafs}`;

            return request({
                // url: 'https://yapi.baidu-int.com/mock/200/region?id=111&leafs=true',
                url,
                method: 'GET',
                header: {
                    'content-type': 'application/x-www-form-urlencoded'
                }
            }).then(({data = {}}) => {
                // 热点城市点击只省市两级存在不差找子节点情况，赋值当前省市使用，超出省市两级范围不做判断
                const leafType = data.region && data.region.leafType;
                let list = data.leafs;
                list = this.filterData(list);

                this.$set(this, `${leafType}List`, list);
                if (leafType === TOWN) {
                    this.townList.unshift({
                        id: '',
                        name: '暂不选择',
                        name_py_init: '',
                        pid: this.townList[0]['pid'],
                        type: this.townList[0]['type']
                    });
                }
                if (!leafs) {
                    const region = data.region;
                    const type = region && region.type;
                    switch (type) {
                        case PROVINCE:
                            this.currentProvince = region;
                            break;
                        case CITY:
                            this.currentCity = region;
                            break;
                    }
                }
                // 赋值热门城市搜索
                if (id === this.id && data.hotlist) {
                    this.hotList = data.hotlist;
                }
            });
        },
        filterData(list) {
            this.showLetter = false;
            const cache = {};
            if (list) {
                list.forEach(item => {
                    if (item.name_py_init && cache[item.name_py_init]) {
                        item.name_py_init = '';
                    } else if (item.name_py_init) {
                        cache[item.name_py_init] = item.name_py_init;
                    }
                });
            }
            this.$set(this, 'letter', Object.keys(cache));
            this.showLetter = true;
            return list;
        },
        navTap(item) {
            this.scrollInToView = item;
        }
    }
};
</script>
<style lang="less" scoped>
.address-popup {
    &__header {
        height: 0.53rem;
        line-height: 0.53rem;
        border-bottom: 1px solid #e0e0e0;
        &__title {
            text-align: center;
            // font-size: 0.19rem;
            color: #858585;
        }
    }
    &__tab {
        // border-bottom: 1px solid #e0e0e0;
        height:0.46rem;
        line-height:0.46rem;
    }
    &__content {
        min-height: 101%;
        overflow-y: scroll;
    }
    &__hotarea {
        width: 100%;
        padding-top: 0.15rem;
        &__title {
            color: #858585;
        }
        &__tagbox {
            display: flex;
            width: 100%;
            flex-wrap: wrap;
            margin-top: 0.07rem;
        }
        &__tag {
            text-align: center;
            width: 0.57rem;
            height: 0.29rem;
            line-height: 0.29rem;
            background-color: #f6f6f6;
            border-radius: 45px;
            margin-right: 0.08rem;
            margin-top: 0.08rem;
            white-space: nowrap;
        }
    }
    &__areacontainer {
        margin-top: 0.2rem;
    }
    &__area__title {
        font-size: 0.14rem;
        line-height: 0.14rem;
        color: #858585;
    }
    &__area {
        font-size: 0.15rem;
        margin-top: 0.127rem;
        display: flex;
        &__pre {
            width: 0.16rem;
            color: #858585;
            margin-right: 0.07rem;
        }
        &__name {
            color: #1f1f1f;
        }
    }
    &__nav {
        position: fixed;
        right: 0.17rem;
        top: 1.4rem;
        width: 0.2rem;
        text-align: center;
        background-color: #f5f5f5;
        border-radius: 26px;
        &__item {
            margin: 0.05rem 0;
            color: #858585;
        }
    }
}
</style>
