<template>
	<view class="address-page">
		<scroll-view class="address-scroll" scroll-y="true">
			<view class="address-content">
				<view class="current-location-card">
					<text class="section-title">当前选择的位置</text>
					<text v-if="hasLocation()" class="current-location-name">{{ displayLocationTitle }}</text>
					<text v-if="hasLocation()" class="current-location-detail">{{ displayLocationDetail }}</text>
					<text v-else class="current-location-placeholder">请选择小区、医院、养老院或街道位置</text>
				</view>

				<view class="form-card">
					<view class="form-item">
						<text class="form-label">联系人</text>
						<input v-model="form.contactName" class="form-input" placeholder="请输入联系人姓名" />
					</view>
					<view class="form-item form-item-border">
						<text class="form-label">手机号</text>
						<input v-model="form.contactPhone" class="form-input" type="number" maxlength="11" placeholder="请输入联系电话" />
					</view>
					<view class="form-item form-item-border form-item-tappable" @click="chooseServiceLocation">
						<view class="form-item-main">
							<text class="form-label">所在位置</text>
							<view v-if="hasLocation()" class="location-block">
								<text class="location-title">{{ displayLocationTitle }}</text>
								<text class="location-detail">{{ displayLocationDetail }}</text>
							</view>
							<text v-else class="location-placeholder">请选择小区/医院/养老院/街道</text>
						</view>
						<text class="form-action">重新选择</text>
					</view>
					<view class="map-entry-row" @click="goToMapSelect">
						<text class="map-entry-text">自定义地图选点</text>
						<text class="map-entry-arrow">></text>
					</view>
					<view class="form-item form-item-border">
						<text class="form-label">详细门牌号</text>
						<input v-model="form.houseNumber" class="form-input" placeholder="例如 3栋2单元1201 / 住院部3楼" />
					</view>
					<view class="form-item form-item-vertical">
						<text class="form-label">服务备注</text>
						<textarea v-model="form.remark" class="form-textarea" placeholder="例如 老人行动不便，请提前电话联系" maxlength="120"></textarea>
					</view>
				</view>
			</view>
		</scroll-view>

		<view class="bottom-bar">
			<button class="save-btn" @click="saveAddress">保存服务地址</button>
		</view>
	</view>
</template>

<script setup lang="uts">
import { computed, reactive } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
import { HomeServiceSelectedAddressType } from '@/types/home-service.uts'

const SELECTED_KEY = 'hss_selected_service_address'
const LIST_KEY = 'hss_service_address_list'
const MAP_DRAFT_KEY = 'hss_service_address_map_draft'

type ServiceAddressFormType = {
	addressId: string
	userId: string
	isDefault: boolean
	contactName: string
	contactPhone: string
	phone: string
	addressName: string
	locationName: string
	addressDetail: string
	locationAddress: string
	houseNumber: string
	doorNo: string
	fullAddress: string
	latitude: number
	longitude: number
	remark: string
	coordinateType: string
	createdAt: number
	updatedAt: number
}

function createDefaultForm(): ServiceAddressFormType {
	const now = Date.now()
	const storedUserId = uni.getStorageSync('user_id') as string | null
	return {
		addressId: 'local-address-' + now,
		userId: storedUserId != null ? storedUserId : '',
		isDefault: true,
		contactName: '',
		contactPhone: '',
		phone: '',
		addressName: '',
		locationName: '',
		addressDetail: '',
		locationAddress: '',
		houseNumber: '',
		doorNo: '',
		fullAddress: '',
		latitude: 0,
		longitude: 0,
		remark: '',
		coordinateType: 'gcj02',
		createdAt: now,
		updatedAt: now
	}
}

const form = reactive(createDefaultForm())
let editingAddressId = ''

const displayLocationTitle = computed((): string => {
	if (form.locationName != '') {
		return form.locationName
	}
	if (form.addressName != '') {
		return form.addressName
	}
	if (form.locationAddress != '') {
		return form.locationAddress
	}
	return '未选择位置'
})

const displayLocationDetail = computed((): string => {
	if (form.locationAddress != '') {
		return form.locationAddress
	}
	if (form.addressDetail != '') {
		return form.addressDetail
	}
	return '请先通过地图选点获取位置'
})

function hasLocation(): boolean {
	return form.locationName != '' || form.addressName != '' || form.locationAddress != '' || form.addressDetail != ''
}

function normalizeAddress(raw: HomeServiceSelectedAddressType): HomeServiceSelectedAddressType {
	const phoneText = raw.phone != null && raw.phone != '' ? raw.phone : (raw.contactPhone != null ? raw.contactPhone : '')
	const locationName = raw.locationName != null && raw.locationName != '' ? raw.locationName : (raw.addressName != null ? raw.addressName : '')
	const locationAddress = raw.locationAddress != null && raw.locationAddress != '' ? raw.locationAddress : (raw.addressDetail != null ? raw.addressDetail : '')
	const doorNo = raw.doorNo != null && raw.doorNo != '' ? raw.doorNo : (raw.houseNumber != null ? raw.houseNumber : '')
	const fullAddressText = raw.fullAddress != null && raw.fullAddress != '' ? raw.fullAddress : locationAddress + ' ' + doorNo
	return {
		...raw,
		addressId: raw.addressId != null && raw.addressId != '' ? raw.addressId : 'local-address-' + Date.now(),
		userId: raw.userId != null ? raw.userId : '',
		isDefault: raw.isDefault === true,
		contactName: raw.contactName != null ? raw.contactName : '',
		phone: phoneText,
		contactPhone: phoneText,
		locationName: locationName,
		addressName: locationName,
		locationAddress: locationAddress,
		addressDetail: locationAddress,
		doorNo: doorNo,
		houseNumber: doorNo,
		remark: raw.remark != null ? raw.remark : '',
		coordinateType: raw.coordinateType != null && raw.coordinateType != '' ? raw.coordinateType : 'gcj02',
		latitude: raw.latitude != null ? raw.latitude : 0,
		longitude: raw.longitude != null ? raw.longitude : 0,
		createdAt: raw.createdAt != null ? raw.createdAt : Date.now(),
		updatedAt: raw.updatedAt != null ? raw.updatedAt : Date.now(),
		fullAddress: fullAddressText.trim()
	}
}

function applyAddress(address: HomeServiceSelectedAddressType): void {
	const normalized = normalizeAddress(address)
	form.addressId = normalized.addressId
	form.userId = normalized.userId
	form.isDefault = normalized.isDefault
	form.contactName = normalized.contactName
	form.contactPhone = normalized.contactPhone
	form.phone = normalized.phone != null ? normalized.phone : normalized.contactPhone
	form.addressName = normalized.addressName
	form.locationName = normalized.locationName != null ? normalized.locationName : normalized.addressName
	form.addressDetail = normalized.addressDetail
	form.locationAddress = normalized.locationAddress != null ? normalized.locationAddress : normalized.addressDetail
	form.houseNumber = normalized.houseNumber
	form.doorNo = normalized.doorNo != null ? normalized.doorNo : normalized.houseNumber
	form.fullAddress = normalized.fullAddress
	form.latitude = normalized.latitude
	form.longitude = normalized.longitude
	form.remark = normalized.remark
	form.coordinateType = normalized.coordinateType
	form.createdAt = normalized.createdAt
	form.updatedAt = normalized.updatedAt
	editingAddressId = normalized.addressId
}

function readAddressList(): Array<HomeServiceSelectedAddressType> {
	const stored = uni.getStorageSync(LIST_KEY)
	if (stored == null) {
		return []
	}
	try {
		if (typeof stored === 'string') {
			const storedText = (stored as string).trim()
			if (storedText == '') {
				return []
			}
			const parsed = JSON.parse(storedText) as Array<HomeServiceSelectedAddressType> | null
			return parsed != null ? parsed : []
		}
		return stored as Array<HomeServiceSelectedAddressType>
	} catch (error) {
		console.error('解析服务地址列表失败', error)
		uni.removeStorageSync(LIST_KEY)
		return []
	}
}

function writeAddressList(addresses: Array<HomeServiceSelectedAddressType>): void {
	uni.setStorageSync(LIST_KEY, JSON.stringify(addresses))
}

function parseStoredAddress(rawValue: unknown): HomeServiceSelectedAddressType | null {
	if (rawValue == null) {
		return null
	}
	try {
		if (typeof rawValue === 'string') {
			const rawText = (rawValue as string).trim()
			if (rawText == '') {
				return null
			}
			const parsed = JSON.parse(rawText) as HomeServiceSelectedAddressType | null
			return parsed
		}
		return rawValue as HomeServiceSelectedAddressType
	} catch (error) {
		console.error('解析服务地址对象失败', error)
		return null
	}
}

function ensureAddressListSeeded(): void {
	const addresses = readAddressList()
	if (addresses.length > 0) {
		return
	}
	const selected = uni.getStorageSync(SELECTED_KEY) as HomeServiceSelectedAddressType | null
	const normalizedSelected = parseStoredAddress(selected)
	if (normalizedSelected != null) {
		const seeded: Array<HomeServiceSelectedAddressType> = []
		seeded.push(normalizeAddress(normalizedSelected))
		writeAddressList(seeded)
	}
}

function loadFromAddressId(addressId: string): void {
	const addresses = readAddressList()
	for (let i = 0; i < addresses.length; i++) {
		if (addresses[i].addressId == addressId) {
			applyAddress(addresses[i])
			return
		}
	}
	const selected = parseStoredAddress(uni.getStorageSync(SELECTED_KEY))
	if (selected != null && selected.addressId == addressId) {
		applyAddress(selected)
	}
}

function loadCachedAddress(): void {
	if (editingAddressId != '') {
		loadFromAddressId(editingAddressId)
		return
	}
	const cachedAddress = parseStoredAddress(uni.getStorageSync(SELECTED_KEY))
	if (cachedAddress != null) {
		applyAddress(cachedAddress)
	}
}

function applyMapDraft(): void {
	const draft = parseStoredAddress(uni.getStorageSync(MAP_DRAFT_KEY))
	if (draft == null) {
		return
	}
	const normalized = normalizeAddress(draft)
	form.addressName = normalized.addressName
	form.locationName = normalized.locationName != null ? normalized.locationName : normalized.addressName
	form.addressDetail = normalized.addressDetail
	form.locationAddress = normalized.locationAddress != null ? normalized.locationAddress : normalized.addressDetail
	form.latitude = normalized.latitude
	form.longitude = normalized.longitude
	form.coordinateType = normalized.coordinateType
	uni.removeStorageSync(MAP_DRAFT_KEY)
	if (normalized.locationName != '' || normalized.locationAddress != '') {
		uni.showToast({
			title: '已回填地图位置',
			icon: 'none'
		})
	}
}

function mapChooseLocationResult(name: string, address: string, latitude: number, longitude: number): void {
	const title = name != '' ? name : address
	const detail = address != '' ? address : title
	form.addressName = title
	form.locationName = title
	form.addressDetail = detail
	form.locationAddress = detail
	form.latitude = latitude
	form.longitude = longitude
	form.coordinateType = 'gcj02'
}

function resolveLocationFailToast(error: unknown): string {
	const errorText = String(error)
	if (errorText.indexOf('cancel') >= 0) {
		return ''
	}
	if (errorText.indexOf('auth deny') >= 0 || errorText.indexOf('authorize') >= 0 || errorText.indexOf('permission') >= 0 || errorText.indexOf('auth denied') >= 0) {
		return '需要开启定位权限才能选择服务地址'
	}
	if (errorText.indexOf('location') >= 0 || errorText.indexOf('getLocation') >= 0) {
		return '定位失败，请手动搜索或重新选择'
	}
	if (errorText.indexOf('map') >= 0 || errorText.indexOf('service') >= 0) {
		return '地图服务暂不可用，请稍后重试'
	}
	return '位置选择失败，请重试'
}

function chooseServiceLocation(): void {
	uni.chooseLocation({
		success: (res) => {
			const locationName = res.name != null ? res.name : ''
			const locationAddress = res.address != null ? res.address : ''
			mapChooseLocationResult(locationName, locationAddress, res.latitude, res.longitude)
		},
		fail: (error) => {
			const toastText = resolveLocationFailToast(error)
			if (toastText == '') {
				return
			}
			uni.showToast({
				title: toastText,
				icon: 'none'
			})
		}
	})
}

function goToMapSelect(): void {
	uni.navigateTo({ url: '/pages/address/address-map-select' })
}

function isPhoneValid(phone: string): boolean {
	return /^\d{11}$/.test(phone)
}

function buildAddressPayload(): HomeServiceSelectedAddressType {
	const now = Date.now()
	const storedUserId = uni.getStorageSync('user_id') as string | null
	const phoneText = form.contactPhone != '' ? form.contactPhone : form.phone
	const locationName = form.locationName != '' ? form.locationName : form.addressName
	const locationAddress = form.locationAddress != '' ? form.locationAddress : form.addressDetail
	const doorNo = form.doorNo != '' ? form.doorNo : form.houseNumber
	return {
		addressId: form.addressId != '' ? form.addressId : 'local-address-' + now,
		userId: form.userId != '' ? form.userId : (storedUserId != null ? storedUserId : ''),
		isDefault: true,
		contactName: form.contactName,
		contactPhone: phoneText,
		phone: phoneText,
		addressName: locationName,
		locationName: locationName,
		addressDetail: locationAddress,
		locationAddress: locationAddress,
		houseNumber: doorNo,
		doorNo: doorNo,
		fullAddress: (locationAddress + ' ' + doorNo).trim(),
		latitude: form.latitude,
		longitude: form.longitude,
		remark: form.remark,
		coordinateType: 'gcj02',
		createdAt: form.createdAt > 0 ? form.createdAt : now,
		updatedAt: now
	}
}

function saveAddress(): void {
	if (form.contactName == '') {
		uni.showToast({ title: '请输入联系人姓名', icon: 'none' })
		return
	}
	if (form.contactPhone == '') {
		uni.showToast({ title: '请输入联系电话', icon: 'none' })
		return
	}
	if (!isPhoneValid(form.contactPhone)) {
		uni.showToast({ title: '请输入11位手机号', icon: 'none' })
		return
	}
	if (!hasLocation()) {
		uni.showToast({ title: '请选择所在位置', icon: 'none' })
		return
	}
	if (form.houseNumber == '') {
		uni.showToast({ title: '请输入详细门牌号', icon: 'none' })
		return
	}

	const savedAddress = buildAddressPayload()
	const addresses = readAddressList()
	let updated = false
	for (let i = 0; i < addresses.length; i++) {
		if (addresses[i].addressId == savedAddress.addressId) {
			addresses[i] = savedAddress
			updated = true
			break
		}
	}
	if (!updated) {
		addresses.unshift(savedAddress)
	}

	writeAddressList(addresses)
	uni.setStorageSync(SELECTED_KEY, savedAddress)
	uni.showToast({
		title: '地址已保存',
		icon: 'success'
	})
	setTimeout(() => {
		uni.navigateBack()
	}, 300)
}

onLoad((options) => {
	ensureAddressListSeeded()
	if (options == null) {
		loadCachedAddress()
		return
	}
	const addressId = options['id']
	if (addressId != null && String(addressId) != '') {
		editingAddressId = String(addressId)
		loadFromAddressId(editingAddressId)
		return
	}
	loadCachedAddress()
})

onShow(() => {
	applyMapDraft()
})
</script>

<style scoped>
.address-page {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: #f4f6f8;
	display: flex;
	flex-direction: column;
}

.address-scroll {
	flex: 1;
	min-height: 0;
}

.address-content {
	padding: 24rpx 24rpx 180rpx;
	gap: 24rpx;
	display: flex;
	flex-direction: column;
}

.current-location-card,
.form-card {
	background: #ffffff;
	border-radius: 28rpx;
	padding: 24rpx;
	box-shadow: 0 12rpx 28rpx rgba(15, 23, 42, 0.05);
}

.section-title,
.form-label,
.location-title,
.current-location-name,
.map-entry-text {
	color: #1f2937;
}

.section-title {
	font-size: 28rpx;
	font-weight: 600;
	margin-bottom: 12rpx;
}

.current-location-name,
.location-title {
	font-size: 26rpx;
	font-weight: 600;
	line-height: 1.5;
}

.current-location-detail,
.current-location-placeholder,
.location-detail,
.location-placeholder,
.form-action,
.form-input,
.form-textarea,
.map-entry-arrow {
	font-size: 24rpx;
	color: #4b5563;
	line-height: 1.6;
}

.current-location-placeholder,
.location-placeholder {
	color: #9ca3af;
}

.current-location-detail,
.location-detail {
	margin-top: 8rpx;
}

.form-item {
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
	padding: 18rpx 0;
	gap: 20rpx;
}

.form-item-border {
	border-top: 1rpx solid #eef2f7;
}

.form-item-vertical {
	align-items: flex-start;
	flex-direction: column;
	border-top: 1rpx solid #eef2f7;
}

.form-item-tappable {
	align-items: flex-start;
}

.form-item-main {
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 10rpx;
}

.form-label {
	width: 132rpx;
	font-size: 26rpx;
	font-weight: 600;
	flex-shrink: 0;
}

.form-input {
	flex: 1;
	text-align: right;
	min-height: 44rpx;
}

.form-textarea {
	width: 100%;
	min-height: 150rpx;
	margin-top: 12rpx;
	background: #f8fafc;
	border-radius: 20rpx;
	padding: 20rpx;
	box-sizing: border-box;
}

.location-block {
	display: flex;
	flex-direction: column;
	gap: 8rpx;
}

.form-action {
	color: #d97706;
	flex-shrink: 0;
}

.map-entry-row {
	display: flex;
	flex-direction: row;
	justify-content: space-between;
	align-items: center;
	padding: 18rpx 0 0;
	border-top: 1rpx dashed #eef2f7;
	margin-top: 8rpx;
}

.map-entry-text {
	font-size: 24rpx;
	font-weight: 600;
}

.map-entry-arrow {
	color: #f97316;
}

.bottom-bar {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 20rpx 24rpx 36rpx;
	background: rgba(244, 246, 248, 0.96);
	box-shadow: 0 -8rpx 24rpx rgba(15, 23, 42, 0.05);
}

.save-btn {
	width: 100%;
	height: 88rpx;
	line-height: 88rpx;
	border-radius: 999rpx;
	background: linear-gradient(135deg, #ff8a65 0%, #ff7043 100%);
	color: #ffffff;
	font-size: 30rpx;
	font-weight: 600;
	border: none;
}
</style>