<template>
	<u-popup :show="modelValue" mode="bottom" :popup="false" :mask="true" :closeable="true"
		:safe-area-inset-bottom="true" close-icon-color="#ffffff" :z-index="uZIndex" :maskCloseAble="maskCloseAble"
		@close="close">
		<u-tabs v-if="modelValue" :list="genTabsList" :scrollable="true" :current="tabsIndex" @change="tabsChange"
			ref="tabs" />
		<view class="area-box">
			<view class="u-flex" :class="{ 'change': isChange }">
				<view class="area-item">
					<view class="u-padding-10 u-bg-gray" style="height: 100%;">
						<scroll-view :scroll-y="true" style="height: 100%">
							<u-cell-group>
								<u-cell v-for="(item, index) in provinces" :title="item.label" :arrow="false"
									:index="index" :key="index" @click="provinceChange(index)">
									<template v-slot:right-icon>
										<u-icon v-if="isChooseP && province === index" size="17"
											name="checkbox-mark"></u-icon>
									</template>
								</u-cell>
							</u-cell-group>
						</scroll-view>
					</view>
				</view>
				<view class="area-item">
					<view class="u-padding-10 u-bg-gray" style="height: 100%;">
						<scroll-view :scroll-y="true" style="height: 100%">
							<u-cell-group v-if="isChooseP">
								<u-cell v-for="(item, index) in citys" :title="item.label" :arrow="false" :index="index"
									:key="index" @click="cityChange(index)">
									<template v-slot:right-icon>
										<u-icon v-if="isChooseC && city === index" size="17"
											name="checkbox-mark"></u-icon>
									</template>
								</u-cell>
							</u-cell-group>
						</scroll-view>
					</view>
				</view>
				<view class="area-item">
					<view class="u-padding-10 u-bg-gray" style="height: 100%;">
						<scroll-view :scroll-y="true" style="height: 100%">
							<u-cell-group v-if="isChooseC">
								<u-cell v-for="(item, index) in areas" :title="item.label" :arrow="false" :index="index"
									:key="index" @click="areaChange(index)">
									<template v-slot:right-icon>
										<u-icon v-if="isChooseA && area === index" size="17"
											name="checkbox-mark"></u-icon>
									</template>
								</u-cell>
							</u-cell-group>
						</scroll-view>
					</view>
				</view>
			</view>
		</view>
	</u-popup>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, PropType } from 'vue';
import provincesSource from "./province.js";
import citysSource from "./city.js";
import areasSource from "./area.js";

// 定义接口
interface Region {
	label: string;
	value: string;
}

interface CitySelectResult {
	province: Region;
	city: Region;
	area: Region;
}

interface TabItem {
	name: string;
}

// Props 定义
const props = defineProps({
	// 通过双向绑定控制组件的弹出与收起
	modelValue: {
		type: Boolean,
		default: false
	},
	// 默认显示的地区，可传类似["河北省", "秦皇岛市", "北戴河区"]
	defaultRegion: {
		type: Array as PropType<string[]>,
		default: () => []
	},
	// 默认显示地区的编码，defaultRegion和areaCode同时存在，areaCode优先，可传类似["13", "1303", "130304"]
	areaCode: {
		type: Array as PropType<string[]>,
		default: () => []
	},
	// 是否允许通过点击遮罩关闭Picker
	maskCloseAble: {
		type: Boolean,
		default: true
	},
	// 弹出的z-index值
	zIndex: {
		type: [String, Number],
		default: 0
	}
});

// 事件定义
const emit = defineEmits<{
	(e: 'update:modelValue', value: boolean): void;
	(e: 'close'): void;
	(e: 'city-change', result: CitySelectResult): void;
}>();

const cityValue = ref("");
const isChooseP = ref(false); // 是否已经选择了省
const province = ref(0); // 省级下标
const provinces = ref<Region[]>(provincesSource);
const isChooseC = ref(false); // 是否已经选择了市
const city = ref(0); // 市级下标
const citys = ref<Region[]>(citysSource[0]);
const isChooseA = ref(false); // 是否已经选择了区
const area = ref(0); // 区级下标
const areas = ref<Region[]>(areasSource[0][0]);
const tabsIndex = ref(0);
const tabs = ref();

// 计算属性
const isChange = computed(() => {
	return tabsIndex.value > 1;
});

const genTabsList = computed((): TabItem[] => {
	let tabsList: TabItem[] = [{
		name: "请选择"
	}];

	if (isChooseP.value) {
		tabsList[0].name = provinces.value[province.value].label;
		tabsList[1] = {
			name: "请选择"
		};
	}

	if (isChooseC.value) {
		tabsList[1].name = citys.value[city.value].label;
		tabsList[2] = {
			name: "请选择"
		};
	}

	if (isChooseA.value) {
		tabsList[2].name = areas.value[area.value].label;
	}

	return tabsList;
});

const uZIndex = computed(() => {
	// 如果用户有传递z-index值，优先使用
	return props.zIndex ? props.zIndex : 1075; // 假设$u.zIndex.popup为1075
});

// 方法
const setProvince = (label = "", value = "") => {
	provinces.value.map((v, k) => {
		if (value ? v.value == value : v.label == label) {
			provinceChange(k);
		}
	});
};

const setCity = (label = "", value = "") => {
	citys.value.map((v, k) => {
		if (value ? v.value == value : v.label == label) {
			cityChange(k);
		}
	});
};

const setArea = (label = "", value = "") => {
	areas.value.map((v, k) => {
		if (value ? v.value == value : v.label == label) {
			isChooseA.value = true;
			area.value = k;
		}
	});
};

const close = () => {
	emit('update:modelValue', false);
	emit('close');
};

const tabsChange = (value: { index: number }) => {
	tabsIndex.value = value.index;
};

const provinceChange = (index: number) => {
	isChooseP.value = true;
	isChooseC.value = false;
	isChooseA.value = false;
	province.value = index;
	citys.value = citysSource[index];
	tabsIndex.value = 1;
};

const cityChange = (index: number) => {
	isChooseC.value = true;
	isChooseA.value = false;
	city.value = index;
	areas.value = areasSource[province.value][index];
	tabsIndex.value = 2;
};

const areaChange = (index: number) => {
	isChooseA.value = true;
	area.value = index;
	const result: CitySelectResult = {
		province: provinces.value[province.value],
		city: citys.value[city.value],
		area: areas.value[area.value]
	};
	emit('city-change', result);
	close();
};

// 生命周期钩子
onMounted(() => {
	if (props.areaCode.length == 3) {
		setProvince("", props.areaCode[0]);
		setCity("", props.areaCode[1]);
		setArea("", props.areaCode[2]);
	} else if (props.defaultRegion.length == 3) {
		setProvince(props.defaultRegion[0], "");
		setCity(props.defaultRegion[1], "");
		setArea(props.defaultRegion[2], "");
	}
});
</script>

<style lang="scss">
.area-box {
	width: 100%;
	overflow: hidden;
	height: 800rpx;

	>view {
		width: 150%;
		transition: transform 0.3s ease-in-out 0s;
		transform: translateX(0);

		&.change {
			transform: translateX(-33.3333333%);
		}
	}

	.area-item {
		width: 33.3333333%;
		height: 800rpx;
	}
}
</style>