import React, {useState, useEffect, useRef} from 'react'
import {View, Text, Input, Textarea, ScrollView, Picker} from '@tarojs/components'
import Taro, {useRouter} from '@tarojs/taro'
import {getShopUserAddress, addShopUserAddress, updateShopUserAddress, setDefaultAddress} from '@/api/shop/shopUserAddress'
import type {ShopUserAddress} from '@/api/shop/shopUserAddress/model'
import {parseLngLatFromText} from '@/utils/geofence'
import RegionData from '@/api/json/regions-data.json'

definePageConfig({
    navigationBarTitleText: '新增收货地址',
})

type SelectedLocation = { lng: string; lat: string; name?: string; address?: string }

const isUserCancel = (e: any) => {
    const msg = String(e?.errMsg || e?.message || e || '')
    return msg.includes('cancel')
}

/** 检查经纬度是否有效 */
const hasValidLngLat = (addr?: Partial<ShopUserAddress> | null) => {
    if (!addr) return false
    const p = parseLngLatFromText(`${(addr as any)?.lng ?? ''},${(addr as any)?.lat ?? ''}`)
    if (!p) return false
    if (p.lng === 0 && p.lat === 0) return false
    return true
}

/** 确保已通过微信隐私授权（定位类接口前置要求）；旧基础库无该接口时直接放行 */
const ensurePrivacyAuthorized = (): Promise<void> => {
    return new Promise((resolve) => {
        const wxAny: any = Taro
        if (typeof wxAny.requirePrivacyAuthorize !== 'function') {
            resolve()
            return
        }
        if (typeof wxAny.getPrivacySetting === 'function') {
            wxAny.getPrivacySetting({
                success: (res: any) => {
                    if (res && res.needAuthorization) {
                        wxAny.requirePrivacyAuthorize({success: () => resolve(), fail: () => resolve()})
                    } else {
                        resolve()
                    }
                },
                fail: () => resolve(),
            })
        } else {
            wxAny.requirePrivacyAuthorize({success: () => resolve(), fail: () => resolve()})
        }
    })
}

/** 预检并申请定位权限；已拒绝则引导去设置，返回最终是否拥有权限 */
const ensureLocationPermission = async (): Promise<boolean> => {
    try {
        const setting: any = await Taro.getSetting()
        const auth = setting?.authSetting?.['scope.userLocation']
        if (auth === true) return true
        if (auth === false) {
            const modal = await Taro.showModal({
                title: '需要定位权限',
                content: '选择定位需要开启定位权限，请在设置中开启后重试。',
                confirmText: '去设置',
            })
            if (modal.confirm) {
                await Taro.openSetting()
                const setting2: any = await Taro.getSetting()
                return setting2?.authSetting?.['scope.userLocation'] === true
            }
            return false
        }
        try {
            await Taro.authorize({scope: 'scope.userLocation'})
            return true
        } catch {
            const modal = await Taro.showModal({
                title: '需要定位权限',
                content: '选择定位需要开启定位权限，请在设置中开启后重试。',
                confirmText: '去设置',
            })
            if (modal.confirm) {
                await Taro.openSetting()
                const setting2: any = await Taro.getSetting()
                return setting2?.authSetting?.['scope.userLocation'] === true
            }
            return false
        }
    } catch {
        return false
    }
}

const AddressEditPage: React.FC = () => {
    const {id, fromWx} = useRouter().params
    const isEditMode = !!id
    const addressId = id ? Number(id) : undefined
    const fromWxMode = fromWx === '1' || fromWx === 'true'

    const [loading, setLoading] = useState(true)
    const [formData, setFormData] = useState<Partial<ShopUserAddress>>({
        name: '',
        phone: '',
        country: '',
        province: '',
        city: '',
        region: '',
        address: '',
        isDefault: false,
    })
    const [regionText, setRegionText] = useState('')

    /** 所在地区微信原生 Picker 的 value（由 formData 派生） */
    const regionValue = [formData.province, formData.city, formData.region].map(v => String(v || ''))
    const [inputText, setInputText] = useState('')
    const [selectedLocation, setSelectedLocation] = useState<SelectedLocation | null>(null)
    const [regionLocked, setRegionLocked] = useState(false)
    const wxDraftRef = useRef<Partial<ShopUserAddress> | null>(null)
    const wxDraftPatchedRef = useRef(false)

    /** 解析省市区 */
    const parseRegion = (text: string) => {
        for (const province of RegionData as any[]) {
            if (text.includes(province.label)) {
                const result: any = {province: province.label}
                if (province.children) {
                    for (const city of province.children) {
                        if (text.includes(city.label)) {
                            result.city = city.label
                            if (city.children) {
                                for (const region of city.children) {
                                    if (text.includes(region.label)) {
                                        result.region = region.label
                                        return result
                                    }
                                }
                            }
                            return result
                        }
                    }
                }
                return result
            }
        }
        return null
    }

    /** 解析地址文本（智能识别） */
    const parseAddressText = (text: string) => {
        const result: any = {}

        // 手机号正则（11 位国内手机号）
        const phoneRegex = /1[3-9]\d{9}/
        const phoneMatch = text.match(phoneRegex)
        if (phoneMatch) result.phone = phoneMatch[0]

        // 姓名正则：优先匹配“收件人/收货人/姓名/联系人：”后面的 2-4 个中文字符
        const nameWithPrefixRegex = /(?:收件人|收货人|姓名|联系人)[:：]\s*([\u4e00-\u9fa5]{2,4})/
        const nameWithPrefixMatch = text.match(nameWithPrefixRegex)
        if (nameWithPrefixMatch) {
            result.name = nameWithPrefixMatch[1]
        } else {
            // 兜底：文本开头 2-4 个中文字符
            const nameRegex = /^[\u4e00-\u9fa5]{2,4}/
            const nameMatch = text.match(nameRegex)
            if (nameMatch) result.name = nameMatch[0]
        }

        // 省市区识别
        const regionResult = parseRegion(text)
        if (regionResult) {
            result.province = regionResult.province
            result.city = regionResult.city
            result.region = regionResult.region
        }

        // 详细地址提取：先把常见的标签字段和已知字段去掉，再清洗标点
        let addressText = text

        // 去除已提取的姓名、手机号
        if (result.name) addressText = addressText.replace(result.name, '')
        if (result.phone) addressText = addressText.replace(result.phone, '')

        // 去除常见标签文案（如“收件人:”、“手机号码:”、“所在地区:”、“详细地址:”）
        addressText = addressText
            .replace(/(?:收件人|收货人|姓名|联系人)[:：]\s*/g, '')
            .replace(/(?:手机号码|手机号|电话|联系电话)[:：]\s*/g, '')
            .replace(/(?:所在地区|地区|省市区)[:：]\s*/g, '')
            .replace(/(?:详细地址|地址|街道)[:：]\s*/g, '')

        // 去除已识别出的省市区
        if (result.province) addressText = addressText.replace(result.province, '')
        if (result.city) addressText = addressText.replace(result.city, '')
        if (result.region) addressText = addressText.replace(result.region, '')

        // 去除零散的标签关键字（如“手机号码”、“所在地区”、“详细地址”本身）
        addressText = addressText
            .replace(/(?:收件人|收货人|手机号码|手机号|所在地区|详细地址)/g, '')

        result.address = addressText.replace(/[，,。\s]+/g, '').trim()

        return result
    }

    /** 地址智能识别 */
    const recognizeAddress = () => {
        if (!inputText.trim()) {
            Taro.showToast({title: '请输入要识别的文本', icon: 'none'})
            return
        }

        try {
            const result = parseAddressText(inputText)
            const newFormData: any = {
                ...formData,
                name: result.name || formData.name,
                phone: result.phone || formData.phone,
                address: result.address || formData.address,
            }

            if (!regionLocked) {
                newFormData.province = result.province || formData.province
                newFormData.city = result.city || formData.city
                newFormData.region = result.region || formData.region
            }

            setFormData(newFormData)

            if (!regionLocked && result.province && result.city && result.region) {
                setRegionText(`${result.province} ${result.city} ${result.region}`)
            }

            Taro.showToast({title: regionLocked ? '识别成功（所在地区以定位为准）' : '识别成功', icon: 'success'})
            setInputText('')
        } catch {
            Taro.showToast({title: '识别失败，请检查文本格式', icon: 'none'})
        }
    }

    /** 将地图选点结果应用到表单 */
    const applyChosenLocation = (res: any) => {
        if (!res) return
        if (res.latitude === undefined || res.longitude === undefined) {
            Taro.showToast({title: '定位信息获取失败', icon: 'none'})
            return
        }

        const next: SelectedLocation = {
            lng: String(res.longitude),
            lat: String(res.latitude),
            name: res.name,
            address: res.address,
        }

        // 尝试从地图返回的地址文本解析省市区
        const regionResult = res?.provinceName || res?.cityName || res?.adName
            ? {
                province: String(res.provinceName || ''),
                city: String(res.cityName || ''),
                region: String(res.adName || '')
            }
            : parseRegion(String(res.address || ''))

        const province = String(regionResult?.province || '').trim()
        const city = String(regionResult?.city || '').trim()
        const region = String(regionResult?.region || '').trim()
        if (!province || !city || !region) {
            Taro.showToast({title: '定位未识别到所在地区，请重新选择定位', icon: 'none'})
            return
        }

        setSelectedLocation(next)
        setRegionLocked(true)

        // 将地图选点的地址同步到"收货地址"（剥离省市区，避免重复）
        const rawAddr = String(res.address || '').trim()
        const name = String(res.name || '').trim()
        let detail = rawAddr
        for (const part of [province, city, region]) {
            if (part) detail = detail.replace(part, '')
        }
        detail = detail.replace(/[，,]+/g, ' ').replace(/\s+/g, ' ').trim()
        const base = detail || rawAddr
        const nextDetailAddress = (() => {
            if (!base && !name) return ''
            if (!base) return name
            if (!name) return base
            return base.includes(name) ? base : `${base} ${name}`
        })()

        setFormData(prev => ({
            ...prev,
            lng: next.lng,
            lat: next.lat,
            address: nextDetailAddress || prev.address,
            province,
            city,
            region,
        }))
        setRegionText(`${province} ${city} ${region}`)
    }

    /** 选择定位 */
    const chooseGeoLocation = async () => {
        try {
            // 1. 微信隐私授权（新版基础库强制，未同意会直接拒绝定位接口）
            await ensurePrivacyAuthorized()

            // 2. 定位权限预检 / 申请
            const granted = await ensureLocationPermission()
            if (!granted) {
                Taro.showToast({title: '未获得定位权限，请在下方手动选择所在地区', icon: 'none'})
                return
            }

            // 3. 优先使用已有经纬度；没有则先调 getLocation 获取当前位置
            //    解决鸿蒙等机型首次打开地图时 POI 列表不显示的问题
            let latitude: number | undefined
            let longitude: number | undefined

            if (selectedLocation?.lat && selectedLocation?.lng) {
                const initLat = Number(selectedLocation.lat)
                const initLng = Number(selectedLocation.lng)
                if (Number.isFinite(initLat) && Number.isFinite(initLng)) {
                    latitude = initLat
                    longitude = initLng
                }
            }

            // 没有已有定位时，主动获取当前位置传给地图，确保地图打开就在用户位置附近
            // 这样地图的 POI 列表能立即加载，不需要用户手动拖动
            if (latitude === undefined || longitude === undefined) {
                try {
                    const loc: any = await Taro.getLocation({ type: 'gcj02' })
                    if (loc && Number.isFinite(loc.latitude) && Number.isFinite(loc.longitude)) {
                        latitude = loc.latitude
                        longitude = loc.longitude
                    }
                } catch (locErr) {
                    // getLocation 失败不阻断流程，chooseLocation 仍可打开（只是默认定位到北京）
                    console.warn('getLocation 失败，地图将以默认位置打开:', locErr)
                }
            }

            const params: any = {}
            if (typeof latitude === 'number') params.latitude = latitude
            if (typeof longitude === 'number') params.longitude = longitude

            const res = await Taro.chooseLocation(params)
            applyChosenLocation(res)
        } catch (e: any) {
            if (isUserCancel(e)) return
            // 4. 地图失败兜底：原生 Picker 无法用代码调起，提示用户去下方手动选择所在地区；
            //    同时提供"重试"可再次尝试地图定位
            Taro.showModal({
                title: '地图打开失败',
                content: '无法调起地图定位，您可以在下方手动选择所在地区并填写详细地址，或稍后重试。',
                confirmText: '重试',
                cancelText: '手动填写',
            }).then((modal) => {
                if (modal.confirm) {
                    Taro.chooseLocation({})
                        .then((res: any) => applyChosenLocation(res))
                        .catch(() => {
                            Taro.showToast({title: '仍无法打开地图，请手动选择所在地区', icon: 'none'})
                        })
                } else {
                    Taro.showToast({title: '请在下方手动选择所在地区', icon: 'none'})
                }
            }).catch(() => {
                Taro.showToast({title: '请在下方手动选择所在地区', icon: 'none'})
            })
        }
    }

    /** 地区选择器确认（微信原生 Picker mode=region） */
    const handleRegionChange = (e: any) => {
        const val = e?.detail?.value as string[]
        if (!val || val.length < 3) return
        const [province, city, region] = val
        setFormData(prev => ({...prev, province, city, region}))
        setRegionText(`${province} ${city} ${region}`)
        // 用户手动修改了所在地区，解除"由地图定位锁定"状态，后续可继续手动调整
        setRegionLocked(false)
    }

    /** 保存地址 */
    const handleSave = async () => {
        // 表单校验
        if (!formData.name?.trim()) {
            Taro.showToast({title: '请输入收货人姓名', icon: 'none'})
            return
        }
        if (!formData.phone?.trim()) {
            Taro.showToast({title: '请输入手机号', icon: 'none'})
            return
        }
        if (!/^1[3-9]\d{9}$/.test(formData.phone)) {
            Taro.showToast({title: '手机号格式不正确', icon: 'none'})
            return
        }
        if (!formData.province || !formData.city || !formData.region) {
            Taro.showToast({title: '请选择所在地区', icon: 'none'})
            return
        }
        if (!formData.address?.trim()) {
            Taro.showToast({title: '请输入详细地址', icon: 'none'})
            return
        }

        // 经纬度检查（可选，不阻断保存流程）
        const loc = selectedLocation || (hasValidLngLat(formData) ? {
            lng: String(formData.lng),
            lat: String(formData.lat)
        } : null)

        try {
            const submitData: any = {
                name: formData.name,
                phone: formData.phone,
                country: formData.country || '中国',
                province: formData.province,
                city: formData.city,
                region: formData.region,
                address: formData.address,
                isDefault: formData.isDefault ?? true,
                ...(loc ? {lng: loc.lng, lat: loc.lat} : {}),
            }

            if (isEditMode && addressId) {
                submitData.id = addressId
            }

            // 执行新增或更新
            let savedId: number | undefined = addressId
            if (isEditMode) {
                await updateShopUserAddress(submitData)
            } else {
                const res: any = await addShopUserAddress(submitData)
                // 后端新增返回可能带有 id 字段
                savedId = (res && (res.data?.id || res.id)) || addressId
            }

            // 兜底：勾选默认时主动调用 set-default，让后端走统一的"取消其他默认"逻辑
            // 这样即使 save/update 在某些老版本后端上漏处理，前端也能保证唯一默认
            if (submitData.isDefault && savedId) {
                try {
                    await setDefaultAddress(savedId)
                } catch (e) {
                    console.warn('setDefaultAddress fallback failed:', e)
                }
            }

            Taro.showToast({title: `${isEditMode ? '更新' : '保存'}成功`, icon: 'success'})
            setTimeout(() => Taro.navigateBack(), 1000)
        } catch (error) {
            console.error('保存失败:', error)
            Taro.showToast({title: `${isEditMode ? '更新' : '保存'}失败`, icon: 'none'})
        }
    }

    const updateField = (field: string, value: any) => {
        setFormData(prev => ({...prev, [field]: value}))
    }

    /** 初始化加载 */
    useEffect(() => {
        const init = async () => {
            // 动态设置页面标题
            Taro.setNavigationBarTitle({
                title: isEditMode ? '编辑收货地址' : (fromWxMode ? '完善收货地址' : '新增收货地址'),
            })

            // 微信地址导入
            if (!isEditMode && fromWxMode && !wxDraftPatchedRef.current) {
                try {
                    const draft = Taro.getStorageSync('WxAddressDraft')
                    if (draft) {
                        wxDraftPatchedRef.current = true
                        wxDraftRef.current = draft as any
                        Taro.removeStorageSync('WxAddressDraft')
                        setFormData(prev => ({...prev, ...(draft as any)}))
                        const p = String((draft as any)?.province || '').trim()
                        const c = String((draft as any)?.city || '').trim()
                        const r = String((draft as any)?.region || '').trim()
                        const rText = [p, c, r].filter(Boolean).join(' ')
                        if (rText) setRegionText(rText)
                    }
                } catch (_e) { /* ignore */
                }
            }

            // 编辑模式：加载已有地址数据
            if (isEditMode && addressId) {
                try {
                    const addr = (await getShopUserAddress(addressId)) as ShopUserAddress
                    if (addr) {
                        // 合并到 formData，保证初始字段不被 null 覆盖为 undefined
                        setFormData(prev => ({
                            ...prev,
                            ...addr,
                            name: addr.name || prev.name || '',
                            phone: addr.phone || prev.phone || '',
                            address: addr.address || prev.address || '',
                            province: addr.province || prev.province || '',
                            city: addr.city || prev.city || '',
                            region: addr.region || prev.region || '',
                            country: addr.country || prev.country || '中国',
                            isDefault: addr.isDefault ?? false,
                        }))
                        const p = String(addr?.province || '').trim()
                        const c = String(addr?.city || '').trim()
                        const r = String(addr?.region || '').trim()
                        setRegionText([p, c, r].filter(Boolean).join(' '))
                        if (hasValidLngLat(addr)) {
                            setSelectedLocation({lng: String((addr as any).lng), lat: String((addr as any).lat)})
                            setRegionLocked(true)
                        }
                    }
                } catch (error) {
                    console.error('加载地址失败:', error)
                    Taro.showToast({title: '加载地址失败', icon: 'none'})
                }
            }

            setLoading(false)
        }

        init()
    }, [])

    if (loading) {
        return (
            <View className="flex items-center justify-center min-h-screen">
                <Text className="text-gray-400 text-sm">加载中...</Text>
            </View>
        )
    }

    return (
        <View className="min-h-screen bg-gray-50 flex flex-col">
            <ScrollView scrollY className="flex-1">
                {/* 地址智能识别区 */}
                <View className="bg-white px-3 pt-3 pb-2">
                    <View
                        className="rounded-lg p-2"
                        style={{border: '1px dashed #0e932e'}}
                    >
                        <Textarea
                            style={{height: '80px', width: '100%', fontSize: '13px'}}
                            value={inputText}
                            onInput={e => setInputText(e.detail.value)}
                            placeholder="粘贴文本，点击「识别」自动识别收货人、地址、电话"
                            maxlength={200}
                        />
                        <View className="flex justify-end mt-2">
                            <View
                                style={{
                                    backgroundColor: '#0e932e',
                                    borderRadius: '12px',
                                    paddingLeft: '12px',
                                    paddingRight: '12px',
                                    paddingTop: '4px',
                                    paddingBottom: '4px'
                                }}
                                onClick={recognizeAddress}
                            >
                                <Text className="text-white text-xs">识别</Text>
                            </View>
                        </View>
                    </View>
                </View>

                <View className="bg-gray-100" style={{height: '8px'}}/>

                {/* 选择定位 */}
                <View className="bg-white px-4 mb-2">
                    <View className="flex items-center py-3" onClick={chooseGeoLocation}>
                        <View className="flex-1">
                            <View className="flex items-center gap-1 mb-1">
                                <Text className="text-sm text-gray-700">选择定位</Text>
                                <Text className="text-gray-300" style={{fontSize: '10px'}}>（推荐）</Text>
                            </View>
                            <Text className="text-xs text-gray-400">
                                {selectedLocation?.address || (selectedLocation ? `经度：${selectedLocation.lng}, 纬度：${selectedLocation.lat}` : '用于判断是否超出配送范围')}
                            </Text>
                            {selectedLocation?.name && (
                                <Text className="text-xs text-green-600 mt-1">{selectedLocation.name}</Text>
                            )}
                        </View>
                        <Text className="text-gray-300 text-xs">▶</Text>
                    </View>
                </View>

                {/* 表单区 */}
                <View className="bg-white px-4 py-2">

                    {/* 所在地区（微信原生地区选择器，地图不可用时也可手动选择） */}
                    <Picker mode='region' value={regionValue} onChange={handleRegionChange}>
                        <View className="flex items-center py-3 border-b border-gray-50">
                            <Text className="text-sm text-gray-700" style={{minWidth: '60px'}}>所在地区</Text>
                            <View className="flex-1 flex items-center justify-between">
                                <Text className={`text-sm ${regionText ? 'text-gray-800' : 'text-gray-400'}`}>
                                    {regionText || '请选择省市区'}
                                </Text>
                                <Text className="text-gray-300 text-xs">▶</Text>
                            </View>
                        </View>
                    </Picker>

                    {/* 详细地址 */}
                    <View className="flex items-center py-3 border-b border-gray-50">
                        <Text className="text-sm text-gray-700" style={{minWidth: '60px'}}>详细地址</Text>
                        <Input
                            className="flex-1 text-sm"
                            placeholder="请输入详细收货地址"
                            maxLength={50}
                            value={formData.address || ''}
                            onInput={e => updateField('address', e.detail.value)}
                        />
                    </View>

                    {/* 收货人 */}
                    <View className="flex items-center py-3 border-b border-gray-50">
                        <Text className="text-sm text-gray-700" style={{minWidth: '60px'}}>收货人</Text>
                        <Input
                            className="flex-1 text-sm"
                            placeholder="请输入收货人姓名"
                            maxLength={10}
                            value={formData.name || ''}
                            onInput={e => updateField('name', e.detail.value)}
                        />
                    </View>

                    {/* 手机号 */}
                    <View className="flex items-center py-3 border-b border-gray-50">
                        <Text className="text-sm text-gray-700" style={{minWidth: '60px'}}>手机号</Text>
                        <Input
                            className="flex-1 text-sm"
                            placeholder="请输入手机号"
                            type="number"
                            maxlength={11}
                            value={formData.phone || ''}
                            onInput={e => updateField('phone', e.detail.value)}
                        />
                    </View>

                </View>

                {/* 默认地址开关 */}
                <View className="bg-white px-4 mt-2">
                    <View className="flex items-center justify-between py-3">
                        <Text className="text-sm text-gray-700">设为默认地址</Text>
                        <View
                            className={`rounded-full relative ${formData.isDefault ? 'bg-green-500' : 'bg-gray-300'}`}
                            style={{width: '40px', height: '22px'}}
                            onClick={() => updateField('isDefault', !formData.isDefault)}
                        >
                            <View
                                className={`absolute top-1 rounded-full bg-white ${formData.isDefault ? 'right-1' : 'left-1'}`}
                                style={{width: '16px', height: '16px'}}
                            />
                        </View>
                    </View>
                </View>

                {/* 底部占位 */}
                <View style={{height: '100px'}}/>
            </ScrollView>

            {/* 底部保存按钮 - 使用 flex 布局而非 fixed */}
            <View className="bg-white border-t border-gray-200 px-4 py-3" style={{paddingBottom: '20px'}}>
                <View
                    className="py-3 rounded-full text-center"
                    style={{backgroundColor: '#0e932e'}}
                    onClick={handleSave}
                >
                    <Text className="text-white font-medium text-sm">{isEditMode ? '更新地址' : '保存并使用'}</Text>
                </View>
            </View>
        </View>
    )
}

export default AddressEditPage
