<template>
	<view>
		<view class="region-trigger" :class="{ 'region-trigger--locked': disabled }" @tap="open">
			<text class="region-trigger__flag">{{ flag }}</text>
			<text class="region-trigger__code">+{{ cleanDial }}</text>
			<text class="region-trigger__caret">▾</text>
		</view>

		<view v-if="visible" class="region-overlay">
			<view class="region-overlay__mask" @tap="close" />
			<view
				class="region-sheet"
				:style="{ paddingBottom: bottomGap + 'px' }"
				@tap.stop
			>
				<view class="region-sheet__top">
					<view class="region-sheet__handle" />
					<view class="region-sheet__head">
						<text class="region-sheet__title">{{ title }}</text>
						<text class="region-sheet__close" @tap="close">×</text>
					</view>

					<view class="region-sheet__search">
						<text class="region-sheet__search-icon">🔎</text>
						<input
							v-model="keyword"
							class="region-sheet__search-input"
							:placeholder="searchPlaceholder"
							placeholder-class="region-sheet__placeholder"
							confirm-type="search"
							@tap.stop
						/>
						<text
							v-if="keyword"
							class="region-sheet__search-clear"
							@tap.stop="keyword = ''"
						>×</text>
					</view>
				</view>

				<scroll-view
					scroll-y
					class="region-sheet__list"
					:style="{ height: listHeight + 'px' }"
					:show-scrollbar="false"
				>
					<view v-if="loading" class="region-sheet__empty">
						<text class="region-sheet__empty-text">{{ resolvedLoadingText }}</text>
					</view>
					<block v-else-if="!keyword">
						<view v-for="bucket in clusters" :key="bucket.id" class="region-sheet__cluster">
							<text class="region-sheet__cluster-label">{{ bucket.label }}</text>
							<view
								v-for="entry in bucket.rows"
								:key="entry.slug"
								class="region-row"
								:class="{ 'region-row--on': isPicked(entry) }"
								@tap="pick(entry)"
							>
								<text class="region-row__flag">{{ entry.flag }}</text>
								<text class="region-row__name">{{ rowName(entry) }}</text>
								<text class="region-row__code">+{{ entry.dial }}</text>
								<text v-if="isPicked(entry)" class="region-row__on">✓</text>
							</view>
						</view>
					</block>

					<block v-else>
						<view v-if="matches.length === 0" class="region-sheet__empty">
							<text class="region-sheet__empty-text">{{ emptyText }}</text>
						</view>
						<view
							v-for="entry in matches"
							:key="entry.slug"
							class="region-row"
							:class="{ 'region-row--on': isPicked(entry) }"
							@tap="pick(entry)"
						>
							<text class="region-row__flag">{{ entry.flag }}</text>
							<text class="region-row__name">{{ rowName(entry) }}</text>
							<text class="region-row__code">+{{ entry.dial }}</text>
							<text v-if="isPicked(entry)" class="region-row__on">✓</text>
						</view>
					</block>
				</scroll-view>
			</view>
		</view>
	</view>
</template>

<script>
import {
	REGION_ROSTER,
	clusterRegions,
	filterRegions,
	localizeRegion,
	findRegion,
	DEFAULT_REGION
} from '@/features/passport/region-dialcodes'
import { fetchDialRegions } from '@/features/passport/region-gateway'

export default {
	name: 'RegionPicker',
	props: {
		value: { type: [String, Number], default: DEFAULT_REGION },
		disabled: { type: Boolean, default: false },
		title: { type: String, default: 'Select region' },
		searchPlaceholder: { type: String, default: 'Code, country or area' },
		emptyText: { type: String, default: 'No matching region found' },
		loadingText: { type: String, default: '' }
	},
	data() {
		return {
			visible: false,
			keyword: '',
			bottomGap: 0,
			roster: REGION_ROSTER,
			loading: false,
			listHeight: 360
		}
	},
	created() {
		this.preloadRoster()
	},
	computed: {
		cleanDial() {
			return String(this.value || '').replace(/^\+/, '') || DEFAULT_REGION
		},
		current() {
			const id = String(this.value || '')
			const bySlug = this.roster.find((row) => row.slug === id)
			if (bySlug) return bySlug
			return findRegion(this.cleanDial, this.roster)
		},
		flag() {
			return this.current ? this.current.flag : '🏳️'
		},
		clusters() {
			return clusterRegions(uni.getLocale(), this.roster)
		},
		matches() {
			return filterRegions(this.keyword, uni.getLocale(), this.roster)
		},
		resolvedLoadingText() {
			if (this.loadingText) return this.loadingText
			return this.$t('passport.region-loading')
		}
	},
	methods: {
		preloadRoster() {
			fetchDialRegions().then((rows) => {
				if (rows && rows.length) this.roster = rows
			})
		},
		loadRoster() {
			if (this.loading) return
			this.loading = true
			fetchDialRegions()
				.then((rows) => {
					if (rows && rows.length) this.roster = rows
				})
				.finally(() => {
					this.loading = false
				})
		},
		open() {
			if (this.disabled) return
			this.keyword = ''
			this.visible = true
			this.loadRoster()
			const sys = uni.getSystemInfoSync()
			const insetBottom = (sys.safeAreaInsets && sys.safeAreaInsets.bottom) || 0
			this.bottomGap = insetBottom
			const sheetMax = Math.floor(sys.windowHeight * 0.82)
			const topReserved = uni.upx2px(320) + insetBottom
			this.listHeight = Math.max(240, sheetMax - topReserved)
		},
		close() {
			this.visible = false
		},
		pick(entry) {
			this.$emit('input', entry.dial)
			this.$emit('change', entry)
			this.close()
		},
		isPicked(entry) {
			return entry && this.current && entry.slug === this.current.slug
		},
		rowName(entry) {
			return localizeRegion(entry, uni.getLocale())
		}
	}
}
</script>

<style lang="scss">
.region-trigger {
	display: flex;
	align-items: center;
	padding: 0 18rpx;
	height: 96rpx;
	border-radius: 24rpx 0 0 24rpx;
	background: rgba(255, 255, 255, 0.08);
	border: 1rpx solid rgba(255, 255, 255, 0.16);
	border-right: none;
}

.region-trigger--locked {
	opacity: 0.4;
}

.region-trigger__flag {
	font-size: 36rpx;
	margin-right: 8rpx;
}

.region-trigger__code {
	font-size: 30rpx;
	color: #fff;
	font-weight: 600;
}

.region-trigger__caret {
	color: rgba(255, 255, 255, 0.7);
	font-size: 20rpx;
	margin-left: 6rpx;
}

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

.region-overlay__mask {
	position: absolute;
	left: 0;
	right: 0;
	top: 0;
	bottom: 0;
	background: rgba(2, 4, 24, 0.7);
}

.region-sheet {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	max-height: 82vh;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	background: linear-gradient(180deg, #1a1f3b 0%, #0c0f24 100%);
	border-top-left-radius: 40rpx;
	border-top-right-radius: 40rpx;
	padding: 12rpx 24rpx 24rpx;
	box-shadow: 0 -20rpx 60rpx rgba(0, 0, 0, 0.4);
}

.region-sheet__top {
	flex-shrink: 0;
}

.region-sheet__handle {
	width: 80rpx;
	height: 6rpx;
	border-radius: 6rpx;
	margin: 12rpx auto 18rpx;
	background: rgba(255, 255, 255, 0.25);
}

.region-sheet__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 0 8rpx 16rpx;
}

.region-sheet__title {
	font-size: 32rpx;
	color: #fff;
	font-weight: 700;
}

.region-sheet__close {
	color: rgba(255, 255, 255, 0.7);
	font-size: 44rpx;
	line-height: 1;
	padding: 0 12rpx;
}

.region-sheet__search {
	display: flex;
	align-items: center;
	box-sizing: border-box;
	background: rgba(255, 255, 255, 0.08);
	border: 1rpx solid rgba(255, 255, 255, 0.14);
	border-radius: 28rpx;
	padding: 16rpx 22rpx;
	min-height: 88rpx;
	margin-bottom: 20rpx;
}

.region-sheet__search-icon {
	flex-shrink: 0;
	color: rgba(255, 255, 255, 0.55);
	font-size: 28rpx;
	line-height: 1;
	margin-right: 12rpx;
}

.region-sheet__search-input {
	flex: 1;
	min-width: 0;
	width: 100%;
	height: 56rpx;
	line-height: 56rpx;
	color: #fff;
	font-size: 28rpx;
	box-sizing: border-box;
}

.region-sheet__placeholder {
	color: rgba(255, 255, 255, 0.4);
}

.region-sheet__search-clear {
	flex-shrink: 0;
	color: rgba(255, 255, 255, 0.55);
	font-size: 36rpx;
	line-height: 1;
	padding: 0 8rpx 0 12rpx;
}

.region-sheet__list {
	width: 100%;
}

.region-sheet__cluster {
	margin-bottom: 18rpx;
}

.region-sheet__cluster-label {
	display: block;
	font-size: 22rpx;
	color: rgba(255, 255, 255, 0.4);
	letter-spacing: 4rpx;
	padding: 12rpx 16rpx 8rpx;
	text-transform: uppercase;
}

.region-row {
	display: flex;
	align-items: center;
	padding: 22rpx 16rpx;
	border-radius: 20rpx;
}

.region-row--on {
	background: rgba(61, 90, 254, 0.22);
}

.region-row__flag {
	font-size: 36rpx;
	margin-right: 18rpx;
}

.region-row__name {
	flex: 1;
	font-size: 28rpx;
	color: #fff;
}

.region-row__code {
	font-size: 26rpx;
	color: rgba(255, 255, 255, 0.7);
	margin-right: 18rpx;
}

.region-row__on {
	color: #ffb547;
	font-size: 28rpx;
	font-weight: 700;
}

.region-sheet__empty {
	padding: 80rpx 40rpx;
	text-align: center;
}

.region-sheet__empty-text {
	color: rgba(255, 255, 255, 0.6);
	font-size: 26rpx;
}
</style>
