<template>
	<view>
		<view class="city-trigger" @tap="open">
			<slot>
				<view class="city-trigger__default">
					<text class="city-trigger__icon">📍</text>
					<text class="city-trigger__text">{{ displayCity || placeholder }}</text>
					<text class="city-trigger__arrow">▾</text>
				</view>
			</slot>
		</view>

		<view v-if="visible" class="city-overlay">
			<view class="city-overlay__mask" @tap="close" />
			<view class="city-sheet" :style="{ paddingBottom: bottomGap + 'px' }" @tap.stop>
				<view class="city-sheet__header">
					<view class="city-sheet__title-bar">
						<text class="city-sheet__title">{{ title }}</text>
						<text class="city-sheet__close" @tap="close">×</text>
					</view>
					<view class="city-sheet__search">
						<text class="city-sheet__search-icon">🔎</text>
						<input
							v-model="keyword"
							class="city-sheet__search-input"
							:placeholder="searchPlaceholder"
							placeholder-class="city-sheet__placeholder"
							confirm-type="search"
							@confirm="onSearch"
							@tap.stop
						/>
						<text v-if="keyword" class="city-sheet__search-clear" @tap.stop="clearSearch">×</text>
					</view>
				</view>

				<scroll-view scroll-y class="city-sheet__list" :style="{ height: listHeight + 'px' }" :show-scrollbar="false">
					<view v-if="loading" class="city-sheet__loading">
						<text class="city-sheet__loading-text">加载中...</text>
					</view>

					<block v-else-if="keyword">
						<view v-if="searchResults.length === 0" class="city-sheet__empty">
							<text class="city-sheet__empty-text">未找到相关城市</text>
						</view>
						<view v-else class="city-list">
							<view v-for="(city, index) in searchResults" :key="city.code || index" class="city-list__item" :class="{ 'city-list__item--active': isCitySelected(city) }" @tap="selectCity(city)">
								<text class="city-list__name">{{ city.name }}</text>
								<text v-if="city.code" class="city-list__code">{{ city.code }}</text>
								<text v-if="isCitySelected(city)" class="city-list__check">✓</text>
							</view>
						</view>
					</block>

					<block v-else>
						<view v-if="historyList.length > 0" class="city-section">
							<view class="city-section__header">
								<text class="city-section__title">历史搜索</text>
								<text class="city-section__clear" @tap="clearHistory">清除</text>
							</view>
							<view class="city-tags">
								<view v-for="(item, index) in historyList" :key="'h-' + index" class="city-tag" @tap="selectCityByName(item)">
									<text class="city-tag__text">{{ item }}</text>
								</view>
							</view>
						</view>

						<view class="city-section">
							<view class="city-section__header">
								<text class="city-section__title">热门城市</text>
							</view>
							<view class="city-tags">
								<view v-for="(city, index) in hotCities" :key="'hot-' + index" class="city-tag" @tap="selectCity(city)">
									<text class="city-tag__text">{{ city.name }}</text>
								</view>
							</view>
						</view>

						<view class="city-list">
							<view v-for="group in cityGroups" :key="group.letter" class="city-group">
								<view class="city-group__letter">{{ group.letter }}</view>
								<view v-for="(city, index) in group.cities" :key="city.code || index" class="city-list__item" :class="{ 'city-list__item--active': isCitySelected(city) }" @tap="selectCity(city)">
									<text class="city-list__name">{{ city.name }}</text>
									<text v-if="city.code" class="city-list__code">{{ city.code }}</text>
									<text v-if="isCitySelected(city)" class="city-list__check">✓</text>
								</view>
							</view>
						</view>
					</block>
				</scroll-view>
			</view>
		</view>
	</view>
</template>

<script>
export default {
	name: 'CityPicker',
	props: {
		value: { type: [String, Object], default: '' },
		placeholder: { type: String, default: '选择城市' },
		title: { type: String, default: '选择城市' },
		searchPlaceholder: { type: String, default: '搜索城市名称或代码' },
		hotCities: {
			type: Array,
			default: () => [
				{ name: '北京', code: '010' },
				{ name: '上海', code: '021' },
				{ name: '广州', code: '020' },
				{ name: '深圳', code: '0755' },
				{ name: '成都', code: '028' },
				{ name: '杭州', code: '0571' },
				{ name: '重庆', code: '023' },
				{ name: '西安', code: '029' }
			]
		},
		cityList: { type: Array, default: () => [] }
	},
	data() {
		return {
			visible: false,
			keyword: '',
			bottomGap: 0,
			listHeight: 400,
			loading: false,
			searchResults: [],
			historyList: []
		}
	},
	computed: {
		displayCity() {
			if (!this.value) return ''
			return typeof this.value === 'string' ? this.value : this.value.name || ''
		},
		cityGroups() {
			const groups = {}
			const list = this.cityList.length > 0 ? this.cityList : this.defaultCityList
			list.forEach(city => {
				const firstChar = city.name.charAt(0).toUpperCase()
				const letter = /[A-Z]/.test(firstChar) ? firstChar : '#'
				if (!groups[letter]) {
					groups[letter] = { letter, cities: [] }
				}
				groups[letter].cities.push(city)
			})
			return Object.keys(groups)
				.sort()
				.map(key => groups[key])
		},
		defaultCityList() {
			return [
				{ name: '北京', code: '010' },
				{ name: '上海', code: '021' },
				{ name: '广州', code: '020' },
				{ name: '深圳', code: '0755' },
				{ name: '成都', code: '028' },
				{ name: '杭州', code: '0571' },
				{ name: '重庆', code: '023' },
				{ name: '西安', code: '029' },
				{ name: '南京', code: '025' },
				{ name: '武汉', code: '027' },
				{ name: '天津', code: '022' },
				{ name: '苏州', code: '0512' },
				{ name: '长沙', code: '0731' },
				{ name: '郑州', code: '0371' },
				{ name: '青岛', code: '0532' },
				{ name: '大连', code: '0411' },
				{ name: '厦门', code: '0592' },
				{ name: '昆明', code: '0871' },
				{ name: '三亚', code: '0898' },
				{ name: '丽江', code: '0888' }
			]
		}
	},
	created() {
		this.loadHistory()
	},
	methods: {
		open() {
			this.keyword = ''
			this.visible = true
			this.searchResults = []
			const sys = uni.getSystemInfoSync()
			const insetBottom = (sys.safeAreaInsets && sys.safeAreaInsets.bottom) || 0
			this.bottomGap = insetBottom
			const sheetMax = Math.floor(sys.windowHeight * 0.85)
			const topReserved = uni.upx2px(360) + insetBottom
			this.listHeight = Math.max(280, sheetMax - topReserved)
		},
		close() {
			this.visible = false
			this.keyword = ''
			this.searchResults = []
		},
		onSearch() {
			if (!this.keyword.trim()) {
				this.searchResults = []
				return
			}
			const kw = this.keyword.trim().toLowerCase()
			const list = this.cityList.length > 0 ? this.cityList : this.defaultCityList
			this.searchResults = list.filter(city => city.name.toLowerCase().includes(kw) || (city.code && city.code.includes(kw)))
			if (this.searchResults.length > 0) {
				this.saveHistory(this.keyword.trim())
			}
		},
		clearSearch() {
			this.keyword = ''
			this.searchResults = []
		},
		selectCity(city) {
			this.$emit('input', city)
			this.$emit('change', city)
			this.saveHistory(city.name)
			this.close()
		},
		selectCityByName(name) {
			const list = this.cityList.length > 0 ? this.cityList : this.defaultCityList
			const city = list.find(c => c.name === name)
			if (city) {
				this.selectCity(city)
			}
		},
		isCitySelected(city) {
			if (!this.value) return false
			if (typeof this.value === 'string') {
				return this.value === city.name
			}
			return this.value.code === city.code || this.value.name === city.name
		},
		saveHistory(name) {
			if (!name) return
			let history = uni.getStorageSync('city_search_history') || []
			history = history.filter(item => item !== name)
			history.unshift(name)
			if (history.length > 10) {
				history = history.slice(0, 10)
			}
			uni.setStorageSync('city_search_history', history)
			this.historyList = history
		},
		loadHistory() {
			this.historyList = uni.getStorageSync('city_search_history') || []
		},
		clearHistory() {
			uni.removeStorageSync('city_search_history')
			this.historyList = []
		}
	}
}
</script>

<style lang="scss" scoped>
.city-trigger {
	display: inline-flex;
	align-items: center;
}

.city-trigger__default {
	display: flex;
	align-items: center;
	padding: 12rpx 20rpx;
	background-color: #f5f5f5;
	border-radius: 30rpx;
}

.city-trigger__icon {
	font-size: 28rpx;
	margin-right: 8rpx;
}

.city-trigger__text {
	font-size: 28rpx;
	color: #333;
	margin-right: 8rpx;
}

.city-trigger__arrow {
	font-size: 20rpx;
	color: #999;
}

.city-overlay {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 9990;
}

.city-overlay__mask {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background-color: rgba(0, 0, 0, 0.5);
}

.city-sheet {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	background-color: #fff;
	border-top-left-radius: 24rpx;
	border-top-right-radius: 24rpx;
	max-height: 85vh;
	display: flex;
	flex-direction: column;
}

.city-sheet__header {
	padding: 24rpx 30rpx 20rpx;
	border-bottom: 1rpx solid #eee;
}

.city-sheet__title-bar {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 20rpx;
}

.city-sheet__title {
	font-size: 32rpx;
	font-weight: 600;
	color: #333;
}

.city-sheet__close {
	font-size: 40rpx;
	color: #999;
	padding: 10rpx;
}

.city-sheet__search {
	display: flex;
	align-items: center;
	background-color: #f5f5f5;
	border-radius: 30rpx;
	padding: 0 20rpx;
	height: 64rpx;
}

.city-sheet__search-icon {
	font-size: 28rpx;
	margin-right: 12rpx;
}

.city-sheet__search-input {
	flex: 1;
	font-size: 28rpx;
	color: #333;
}

.city-sheet__placeholder {
	color: #999;
}

.city-sheet__search-clear {
	font-size: 32rpx;
	color: #999;
	padding: 10rpx;
}

.city-sheet__list {
	flex: 1;
}

.city-sheet__loading,
.city-sheet__empty {
	display: flex;
	justify-content: center;
	align-items: center;
	padding: 60rpx 0;
}

.city-sheet__loading-text,
.city-sheet__empty-text {
	font-size: 28rpx;
	color: #999;
}

.city-section {
	padding: 24rpx 30rpx;
}

.city-section__header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 20rpx;
}

.city-section__title {
	font-size: 28rpx;
	font-weight: 600;
	color: #333;
}

.city-section__clear {
	font-size: 24rpx;
	color: #666;
}

.city-tags {
	display: flex;
	flex-wrap: wrap;
	gap: 16rpx;
}

.city-tag {
	padding: 12rpx 24rpx;
	background-color: #f5f5f5;
	border-radius: 30rpx;
}

.city-tag__text {
	font-size: 26rpx;
	color: #333;
}

.city-group {
	margin-bottom: 20rpx;
}

.city-group__letter {
	padding: 12rpx 30rpx;
	font-size: 24rpx;
	color: #999;
	background-color: #fafafa;
	position: sticky;
	top: 0;
	z-index: 1;
}

.city-list__item {
	display: flex;
	align-items: center;
	padding: 24rpx 30rpx;
	border-bottom: 1rpx solid #f5f5f5;
}

.city-list__item--active {
	background-color: #f0f7ff;
}

.city-list__name {
	flex: 1;
	font-size: 28rpx;
	color: #333;
}

.city-list__code {
	font-size: 24rpx;
	color: #999;
	margin-right: 16rpx;
}

.city-list__check {
	font-size: 28rpx;
	color: #007aff;
}
</style>