<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.py"
                                    :id="area.py"
                                    class="address-popup__area__pretext"
                                >{{
                                    area.py
                                }}</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 = 'district';
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: '',
                    district: '',
                    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', // 首次请求是CHN，后续请求根据用户选择的区域来
            currentRegion: {},
            pageLoading: true,
            hotList: [],
            title: '请选择所在地区',
            tabItemStyle: {
                width: 'auto',
                'margin-right': '.2rem',
                'font-size': '.15rem',
                'line-height': '0.46rem'
            },

            currentTab: PROVINCE,
            currentProvince: '',
            provinceList: [],
            currentCity: '',
            cityList: [],
            currentDistrict: '',
            districtList: [],
            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.initFrom(PROVINCE);
                } else if (this.areaInfos.city
                    && (!this.currentCity || this.currentCity.name !== this.areaInfos.city)) {
                    this.initFrom(CITY);
                } else if (this.areaInfos.district
                    && (!this.currentDistrict || this.currentDistrict.name !== this.areaInfos.district)) {
                    this.initFrom(COUNTY);
                } else if (this.areaInfos.town
                    && (!this.currentTown || (this.currentTown.name !== this.areaInfos.town))) {
                    this.initFrom(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', 'currentDistrict', 'currentTown'];
            const tabList = [];
            const tagList = [TOWN];
            let lastTag = null;

            // 对于直辖市，只有 province-district-town 三级  那么最后生成的tabList里也只有这三项
            tabMap.forEach(name => {
                if (this[name]) {
                    tabList.push({
                        text: this[name].name,
                        tag: this[name]
                    });
                    lastTag = this[name];
                }
            });

            // this.disableTownLevel && tagList.push(COUNTY);
            this.whetherDisableTownLevel(lastTag) && tagList.push(COUNTY);
            if (lastTag && !tagList.includes(lastTag.type)) {
                tabList.push({
                    text: '请选择',
                    tag: {
                        type: lastTag.leafType,
                        name: '请选择',
                        useless: true
                    }
                });
            }
            // todo 增加街道默认不选择按钮
            return tabList;
        },
        selectedIndex() {
            let startIndex = 0;
            const map = {
                province: this.currentProvince ? startIndex++ : startIndex,
                city: this.currentCity ? startIndex++ : startIndex,
                district: this.currentDistrict ? startIndex++ : startIndex,
                town: this.currentTown ? startIndex++ : startIndex
            };
            return map[this.currentTab];
        },
        host() {
            return this.apiHost === '56' ? conf.apiHost : conf.goApiHost;
        }
    },
    methods: {
        // 获取首屏数据
        getFirstview() {
            this.questList(this.id, true);
        },
        async initFrom(type) {
            let currentTab;
            this.reset(type);
            switch (type) {
                case PROVINCE: // 从省开始向下更新，要兼容直辖市的情况（省下面直接是县区，没有市）
                    const id = 'CHN';
                    await this.changeListAndCur(type, id); // 这个执行完之后，才有currentProvince 的信息
                    // 如果上一步的结果列表中没有查找到对应的省，就不再继续往下查了，直接显示第一层级
                    if (!this.currentProvince || !this.currentProvince.id) {
                        currentTab = PROVINCE;
                        break;
                    }

                    // 然后拿着currentProvince.id 去查询下一级，一般来说下一级查询回来时cityList，但是直辖市查询回来是districtList
                    await this.changeListAndCur(CITY, this.currentProvince.id);
                    currentTab = CITY;
                    if (this.areaInfos.city) {
                        await this.changeListAndCur(COUNTY, this.currentCity.id);
                        currentTab = COUNTY;
                    }
                    if (this.areaInfos.district) {
                        await this.changeListAndCur(TOWN, this.currentDistrict.id);
                        currentTab = TOWN;
                    }
                    break;
                case CITY:
                    await this.changeListAndCur(type, this.currentProvince.id);
                    await this.changeListAndCur(COUNTY, this.currentCity.id);
                    currentTab = COUNTY;
                    if (this.areaInfos.district) {
                        await this.changeListAndCur(TOWN, this.currentDistrict.id);
                        currentTab = TOWN;
                    }
                    break;
                case COUNTY:
                    // 直辖市是province不是city，所以对于没有cityId的情况，就取上一级的provinceId用来查询district区列表
                    await this.changeListAndCur(type, this.currentCity.id || this.currentProvince.id);
                    await this.changeListAndCur(TOWN, this.currentDistrict.id);
                    currentTab = TOWN;
                    break;
                case TOWN:
                    await this.changeListAndCur(type, this.currentDistrict.id);
                    currentTab = TOWN;
                    break;
            }
            this.$set(this, 'currentTab', currentTab);
        },
        changeListAndCur(type, id) {
            return new Promise((res, rej) => {
                let cur;
                this.questList(id, true).then(() => {
                    if (type === CITY && (!this.cityList || this.cityList.length <= 0) && this.districtList) {
                        // 这个代表直辖市查询下级列表的情况，本来是想查询市一级列表，但是直辖市下面是区，所以查回来的是区列表
                        type = COUNTY;
                    }


                    cur = this[`${type}List`].find(item =>
                        item.name === this.areaInfos[type]
                    ) || '';

                    // 对于type=city的情况，已经查询到的cityList里可能会包含县级市（district）
                    // 如果当前地址是县级市，areaInfos里的city字段就是空的，这时候要去匹配areaInfos里的district字段
                    if (type === CITY && !this.areaInfos.city && this.areaInfos.district) {
                        cur = this[`${type}List`].find(item =>
                            item.type === 'district' && item.name === this.areaInfos[COUNTY]
                        ) || ''; // 为县级市的name匹配city的下一级：district 县区
                        type = COUNTY;
                    }

                    const name = type.slice(0, 1).toUpperCase() + type.slice(1).toLowerCase();
                    this.$set(this, `current${name}`, cur);
                    res();
                });
            });
        },
        /**
         * @description: 是否阻止城镇一级的显示
         * @param {*} tag 地址信息
         * @return {*} 是否阻止显示
         */
        whetherDisableTownLevel(tag) {
            return (tag && tag.type === COUNTY && this.disableTownLevel) || (tag && tag.leafType === null);
        },
        /**
         * @description: 切换tab类型
         * @param {*} tag 地址信息
         * @param {*} type 切换类型  点击的tag触发的切换，或者 点击的 tab 进行的切换
         * @return {*}
         */
        switchCurrentTab(tag, type) {
            const disableTownLevel = this.whetherDisableTownLevel(tag);
            switch (tag.type) {
                case PROVINCE:
                    tag.useless ? '' : (this.currentProvince = tag);
                    // 省下面，不一定是city，有可能是district （四个直辖市）
                    type === TAB ? (this.currentTab = PROVINCE) : (this.currentTab = tag.leafType);
                    break;
                case CITY:
                    tag.useless ? '' : (this.currentCity = tag);
                    // city下面，不一定是district，有可能是town （东莞）
                    type === TAB ? (this.currentTab = CITY) : (this.currentTab = tag.leafType);
                    break;
                case COUNTY: // 正常是切换县区一级，但是对于县级市来说，虽然是district但要显示cityList列表
                    tag.useless ? '' : (this.currentDistrict = tag);
                    if (type === TAB) {
                        if (!this.areaInfos.city && this.areaInfos.district) {
                            this.currentTab = CITY;
                        } else {
                            this.currentTab = COUNTY;
                        }

                    } else {
                        // 正常来说是点击的县区district，但是对于一些本身在cityList里，但是自身type=district的县级市，也会归到这个case，需要特殊处理。
                        // 判断一个县区是否是县级市的逻辑  查询pid是否在provinceList中
                        if (this.provinceList.find(province =>
                            province.id === tag.pid
                        )) {
                            this.currentCity = '';
                        }
                        // 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, selfCountIn = true) {
            if (type === PROVINCE) {
                if (selfCountIn) {
                    this.currentProvince = '';
                    this.provinceList = [];
                }
                this.currentCity = '';
                this.cityList = [];
                this.currentDistrict = '';
                this.districtList = [];
                this.currentTown = '';
                this.townList = [];
            }
            if (type === CITY) {
                if (selfCountIn) {
                    this.currentCity = '';
                    this.cityList = [];
                }
                this.currentDistrict = '';
                this.districtList = [];
                this.currentTown = '';
                this.townList = [];
            }
            if (type === COUNTY) {
                if (selfCountIn) {
                    this.currentDistrict = '';
                    this.districtList = [];
                }
                this.currentTown = '';
                this.townList = [];
            }
        },
        handlePopupClose() {
            if (this.currentProvince && this.currentCity && this.currentDistrict) {
                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) {
            // 如果要切换tab，要把当前tab之后的所有已有值都清空，然后再切换
            this.reset(this.currentTab, false);
            this.switchCurrentTab(tag, TAG);
            // 最后一级点击，修改数据，否则请求下一级数据
            // 设置 disableTownLevel 属性会去阻止城镇一级的选择，在district一级就去改变地址
            const disableTownLevel = this.whetherDisableTownLevel(tag);
            if (disableTownLevel || tag.type === TOWN) {
                this.changeAddress();
            } else {
                this.questList(tag.id, true);
            }
        },
        /**
         * 只有点击地区的最后一级后，才认为是有效选择
         */
        changeAddress() {
            const province = this.currentProvince;
            const city = this.currentCity;
            const district = this.currentDistrict;
            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,
                district: district && district.name,
                districtId: district && district.id,
                town: townName,
                townId: (town && town.id) || ''
            });
        },
        /**
         * @description: 请求列表数据
         * @param {String} id 选择省/市/区对应的id
         * @param {Boolean} hasLeafs 是否含有叶子节点
         * @return {*}
         */
        questList(id, hasLeafs = true, city_limit = true) {
            // 需要从外部导入
            // const url = `${this.host}${this.regionUrl}&id=${id}&hasLeafs=${hasLeafs}`;
            // const url = `http://dev-huruixiang.bcc-bdbl.baidu.com:8730${this.regionUrl}?id=${id}&leafs=${hasLeafs}`;
            // const url = `http://dev-huruixiang.bcc-bdbl.baidu.com:8730/${this.regionUrl}`;
            return request({
                url: this.regionUrl,
                method: 'GET',
                data: {
                    id,
                    leafs: hasLeafs
                },
                header: {
                    'content-type': 'application/x-www-form-urlencoded'
                }
            }).then(({data = {}}) => {
                // 处理查询直辖市的leafs的情况
                /**
                if (data.region.type === 'province' && data.region.leafType === 'district' ) {
                    // 为了和已有的线上逻辑统一，直辖市和其下辖的县区之间，增加一个city层级
                    data.region.leafType = 'city';
                    data.leafs = [{
                        id: '500100',  // 理论上不应该和直辖市的id相同，但是这个值其实没什么用，服务端本来就没有这一层级，所以不重要。
                        pid: data.region.id,
                        name: data.region.name,
                        type: "city",
                        py: data.region.py,
                        hasLeaf: true,
                        leafType: 'district'
                    }];
                }
                */

                // 热点城市点击只省市两级存在不差找子节点情况，赋值当前省市使用，超出省市两级范围不做判断
                const leafType = 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: '暂不选择',
                        py: '',
                        pid: this.townList[0].pid,
                        type: this.townList[0].type
                    });
                }
                if (!hasLeafs) {
                    switch (data.region.type) {
                        case PROVINCE:
                            this.currentProvince = data.region;
                            break;
                        case CITY:
                            this.currentCity = data.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.py && cache[item.py]) {
                        item.py = '';
                    } else if (item.py) {
                        cache[item.py] = item.py;
                    }
                });
            }
            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>
