import {useEffect, useState, useRef} from "react";
import {useRouter} from '@tarojs/taro'
import {Button, Loading, CellGroup, Cell, Input, TextArea, Form} from '@nutui/nutui-react-taro'
import {Scan, ArrowRight} from '@nutui/icons-react-taro'
import Taro from '@tarojs/taro'
import {View} from '@tarojs/components'
import {Address} from '@nutui/nutui-react-taro'
import {ShopUserAddress} from "@/api/shop/shopUserAddress/model";
import {getShopUserAddress, listShopUserAddress, updateShopUserAddress, addShopUserAddress} from "@/api/shop/shopUserAddress";
import RegionData from '@/api/json/regions-data.json';
import FixedButton from "@/components/FixedButton";
import { parseLngLatFromText } from "@/utils/geofence";

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

const isLocationDenied = (e: any) => {
  const msg = String(e?.errMsg || e?.message || e || '')
  return (
    msg.includes('auth deny') ||
    msg.includes('authorize') ||
    msg.includes('permission') ||
    msg.includes('denied') ||
    msg.includes('scope.userLocation')
  )
}

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
  // Treat "0,0" as missing in this app (typically used as placeholder by backends).
  if (p.lng === 0 && p.lat === 0) return false
  return true
}

const AddUserAddress = () => {
  const {params} = useRouter();
  const [loading, setLoading] = useState<boolean>(true)
  const [text, setText] = useState<string>('')
  const [optionsDemo1, setOptionsDemo1] = useState([])
  const [visible, setVisible] = useState(false)
  const [FormData, setFormData] = useState<ShopUserAddress>({})
  const [inputText, setInputText] = useState<string>('')
  const [selectedLocation, setSelectedLocation] = useState<SelectedLocation | null>(null)
  const formRef = useRef<any>(null)
  const wxDraftRef = useRef<Partial<ShopUserAddress> | null>(null)
  const wxDraftPatchedRef = useRef(false)

  // 判断是编辑还是新增模式
  const isEditMode = !!params.id
  const addressId = params.id ? Number(params.id) : undefined
  const fromWx = params.fromWx === '1' || params.fromWx === 'true'
  const skipDefaultCheck =
    fromWx || params.skipDefaultCheck === '1' || params.skipDefaultCheck === 'true'

  const reload = async () => {
    // 整理地区数据
    setRegionData()

    // 新增模式：若存在“默认地址”但缺少经纬度，则强制引导到编辑页完善定位
    // 目的：确保业务依赖默认地址坐标（选店/配送范围）时不会因为缺失坐标而失败
    if (!isEditMode && !skipDefaultCheck) {
      try {
        const defaultList = await listShopUserAddress({ isDefault: true })
        const defaultAddr = defaultList?.[0]
        if (defaultAddr && !hasValidLngLat(defaultAddr)) {
          await Taro.showModal({
            title: '需要完善定位',
            content: '默认收货地址缺少定位信息，请先进入编辑页面选择定位并保存后再继续。',
            confirmText: '去完善',
            showCancel: false
          })
          if (defaultAddr.id) {
            Taro.navigateTo({ url: `/user/address/add?id=${defaultAddr.id}` })
          } else {
            Taro.navigateTo({ url: '/user/address/index' })
          }
          return
        }
      } catch (_e) {
        // ignore: 新增页不阻塞渲染
      }
    }

    // 微信地址导入：先用微信返回的字段预填表单，让用户手动选择定位后再保存
    if (!isEditMode && fromWx && !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 regionText = [p, c, r].filter(Boolean).join(' ')
          if (regionText) setText(regionText)
        }
      } catch (_e) {
        // ignore
      }
    }

    // 如果是编辑模式，加载地址数据
    if (isEditMode && addressId) {
      try {
        const address = await getShopUserAddress(addressId)
        setFormData(address)
        // 设置所在地区
        setText(`${address.province} ${address.city} ${address.region}`)
        // 回显已保存的经纬度（编辑模式）
        if (hasValidLngLat(address)) setSelectedLocation({ lng: String(address.lng), lat: String(address.lat) })
      } catch (error) {
        console.error('加载地址失败:', error)
        Taro.showToast({
          title: '加载地址失败',
          icon: 'error'
        });
      }
    }
  }

  /**
   * 处理地区数据
   */
  function setRegionData() {
    // @ts-ignore
    setOptionsDemo1(RegionData?.map((a) => {
      return {
        value: a.label,
        text: a.label,
        children: a.children?.map((b) => {
          return {
            value: b.label,
            text: b.label,
            children: b.children?.map((c) => {
              return {
                value: c.label,
                text: c.label
              }
            })
          }
        })
      }
    }))
  }

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

    try {
      const result = parseAddressText(inputText);

      // 更新表单数据
      const newFormData = {
        ...FormData,
        name: result.name || FormData.name,
        phone: result.phone || FormData.phone,
        address: result.address || FormData.address,
        province: result.province || FormData.province,
        city: result.city || FormData.city,
        region: result.region || FormData.region
      };

      setFormData(newFormData);

      // 更新地区显示文本
      if (result.province && result.city && result.region) {
        setText(`${result.province} ${result.city} ${result.region}`);
      }

      // 更新表单字段值
      if (formRef.current) {
        formRef.current.setFieldsValue(newFormData);
      }

      Taro.showToast({
        title: '识别成功',
        icon: 'success'
      });

      // 清空输入框
      setInputText('');

    } catch (error) {
      Taro.showToast({
        title: '识别失败，请检查文本格式',
        icon: 'none'
      });
    }
  };

  /**
   * 解析地址文本
   */
  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 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, '');
    }
    if (result.province) {
      addressText = addressText.replace(result.province, '');
    }
    if (result.city) {
      addressText = addressText.replace(result.city, '');
    }
    if (result.region) {
      addressText = addressText.replace(result.region, '');
    }

    // 清理地址文本
    result.address = addressText.replace(/[，,。\s]+/g, '').trim();

    return result;
  };

  /**
   * 解析省市区
   */
  const parseRegion = (text: string) => {
    // @ts-ignore
    for (const province of RegionData) {
      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 chooseGeoLocation = async () => {
    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
      }
      setSelectedLocation(next)

      // 尝试从地图返回的 address 文本解析省市区（best-effort）
      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 nextDetailAddress = (() => {
        const rawAddr = String(res.address || '').trim()
        const name = String(res.name || '').trim()

        const province = String(regionResult?.province || '').trim()
        const city = String(regionResult?.city || '').trim()
        const region = String(regionResult?.region || '').trim()

        // 选择定位返回的 address 往往包含省市区，这里尽量剥离掉，避免和表单的省市区字段重复
        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
        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: regionResult?.province || prev.province,
        city: regionResult?.city || prev.city,
        region: regionResult?.region || prev.region
      }))

      if (regionResult?.province && regionResult?.city && regionResult?.region) {
        setText(`${regionResult.province} ${regionResult.city} ${regionResult.region}`)
      }

      // 更新表单展示值（Form initialValues 不会跟随 FormData 变化）
      if (formRef.current) {
        const patch: any = {}
        if (nextDetailAddress) patch.address = nextDetailAddress
        if (regionResult?.region) patch.region = regionResult.region
        formRef.current.setFieldsValue(patch)
      }
    }

    try {
      const initLat = selectedLocation?.lat ? Number(selectedLocation.lat) : undefined
      const initLng = selectedLocation?.lng ? Number(selectedLocation.lng) : undefined
      const latitude = typeof initLat === 'number' && Number.isFinite(initLat) ? initLat : undefined
      const longitude = typeof initLng === 'number' && Number.isFinite(initLng) ? initLng : undefined
      const res = await Taro.chooseLocation({
        latitude,
        longitude
      })
      applyChosenLocation(res)
    } catch (e: any) {
      console.warn('选择定位失败:', e)
      if (isUserCancel(e)) return
      if (isLocationDenied(e)) {
        try {
          const modal = await Taro.showModal({
            title: '需要定位权限',
            content: '选择定位需要开启定位权限，请在设置中开启后重试。',
            confirmText: '去设置'
          })
          if (modal.confirm) {
            await Taro.openSetting()
            // 权限可能刚被开启：重试一次
            const res = await Taro.chooseLocation({})
            applyChosenLocation(res)
          }
        } catch (_e) {
          // ignore
        }
        return
      }
      try {
        await Taro.showToast({ title: '打开地图失败，请重试', icon: 'none' })
      } catch (_e) {
        // ignore
      }
    }
  }

  // 提交表单
  const submitSucceed = async (values: any) => {
    const loc =
      selectedLocation ||
      (hasValidLngLat(FormData) ? { lng: String(FormData.lng), lat: String(FormData.lat) } : null)
    if (!loc) {
      Taro.showToast({ title: '请选择定位', icon: 'none' })
      return
    }

    try {
      // 准备提交的数据
      const submitData = {
        ...values,
        country: FormData.country,
        province: FormData.province,
        city: FormData.city,
        region: FormData.region,
        lng: loc.lng,
        lat: loc.lat,
        isDefault: true // 新增或编辑的地址都设为默认地址
      };

      // 如果是编辑模式，添加id
      if (isEditMode && addressId) {
        submitData.id = addressId;
      }

      // 先处理默认地址逻辑
      const defaultAddress = await listShopUserAddress({isDefault: true});
      if (defaultAddress && defaultAddress.length > 0) {
        // 如果当前编辑的不是默认地址，或者是新增地址，需要取消其他默认地址
        if (!isEditMode || (isEditMode && defaultAddress[0].id !== addressId)) {
          await updateShopUserAddress({
            ...defaultAddress[0],
            isDefault: false
          });
        }
      }

      // 执行新增或更新操作
      if (isEditMode) {
        await updateShopUserAddress(submitData);
      } else {
        await addShopUserAddress(submitData);
      }

      Taro.showToast({
        title: `${isEditMode ? '更新' : '保存'}成功`,
        icon: 'success'
      });

      setTimeout(() => {
        Taro.navigateBack();
      }, 1000);

    } catch (error) {
      console.error('保存失败:', error);
      Taro.showToast({
        title: `${isEditMode ? '更新' : '保存'}失败`,
        icon: 'error'
      });
    }
  }

  const submitFailed = (error: any) => {
    console.log(error, 'err...')
  }

  useEffect(() => {
    // 动态设置页面标题
    Taro.setNavigationBarTitle({
      title: isEditMode ? '编辑收货地址' : (fromWx ? '完善收货地址' : '新增收货地址')
    });

    reload().then(() => {
      setLoading(false)
    })
  }, [fromWx, isEditMode]);

  // NutUI Form 的 initialValues 在首次渲染后不再响应更新；微信导入时做一次 setFieldsValue 兜底回填。
  useEffect(() => {
    if (loading) return
    if (isEditMode) return
    const draft = wxDraftRef.current
    if (!draft) return
    if (!formRef.current?.setFieldsValue) return
    try {
      formRef.current.setFieldsValue({
        name: (draft as any)?.name,
        phone: (draft as any)?.phone,
        address: (draft as any)?.address,
        region: (draft as any)?.region
      })
    } catch (_e) {
      // ignore
    } finally {
      wxDraftRef.current = null
    }
  }, [fromWx, isEditMode, loading])

  if (loading) {
    return <Loading className={'px-2'}>加载中</Loading>
  }

  return (
    <>
      <Form
        ref={formRef}
        divider
        initialValues={FormData}
        labelPosition="left"
        onFinish={(values) => submitSucceed(values)}
        onFinishFailed={(errors) => submitFailed(errors)}
      >
        <CellGroup className={'px-3'}>
          <div
            style={{
              border: '1px dashed #22c55e',
              display: 'flex',
              alignItems: 'flex-end',
              justifyContent: 'space-between',
              padding: '4px',
              position: 'relative'
            }}>

            <TextArea
              style={{height: '100px'}}
              value={inputText}
              onChange={(value) => setInputText(value)}
              placeholder={'请粘贴或输入文本，点击"识别"自动识别收货人姓名、地址、电话'}
            />
            <Button
              icon={<Scan/>}
              style={{position: 'absolute', right: '10px', bottom: '10px'}}
              type="success"
              size={'small'}
              fill="dashed"
              onClick={recognizeAddress}
            >
              识别
            </Button>
          </div>
        </CellGroup>
        <View className={'bg-gray-100 h-3'}></View>
        <CellGroup style={{padding: '4px 0'}}>
          <Form.Item
            name="name"
            label="收货人"
            initialValue={FormData.name}
            rules={[{ required: true, message: '请输入收货人姓名' }]}
            required
          >
            <Input placeholder="请输入收货人姓名" maxLength={10}/>
          </Form.Item>
          <Form.Item
            name="phone"
            label="手机号"
            initialValue={FormData.phone}
            rules={[
              { required: true, message: '请输入手机号' },
              { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号' }
            ]}
            required
          >
            <Input placeholder="请输入手机号" maxLength={11}/>
          </Form.Item>
          <Form.Item
            label="所在地区"
            name="region"
            initialValue={FormData.region}
            rules={[{message: '请输入您的所在地区'}]}
            required
          >
            <div className={'flex justify-between items-center'} onClick={() => setVisible(true)}>
              <Input placeholder="选择所在地区" value={text} disabled/>
              <ArrowRight className={'text-gray-400'}/>
            </div>
          </Form.Item>
          <Form.Item name="address" label="收货地址" initialValue={FormData.address} required>
            <TextArea maxLength={50} placeholder="请输入详细收货地址"/>
          </Form.Item>
        </CellGroup>
        <CellGroup>
          <Cell
            title="选择定位"
            description={
              selectedLocation?.address ||
              (selectedLocation ? `经纬度：${selectedLocation.lng}, ${selectedLocation.lat}` : '用于计算是否超出配送范围')
            }
            extra={(
              <div className={'flex items-center gap-2'}>
                <div
                  className={'text-gray-900 text-sm'}
                  style={{maxWidth: '200px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'}}
                >
                  {selectedLocation?.name || (selectedLocation ? '已选择' : '请选择')}
                </div>
                <ArrowRight className={'text-gray-400'}/>
              </div>
            )}
            onClick={chooseGeoLocation}
          />
        </CellGroup>
      </Form>

      <Address
        visible={visible}
        options={optionsDemo1}
        title="选择地址"
        onChange={(value, _) => {
          setFormData({
            ...FormData,
            province: `${value[0]}`,
            city: `${value[1]}`,
            region: `${value[2]}`
          })
          setText(value.join(' '))
        }}
        onClose={() => setVisible(false)}
      />

      {/* 底部浮动按钮 */}
      <FixedButton
        text={isEditMode ? '更新地址' : '保存并使用'}
        onClick={() => {
          // 触发表单提交
          if (formRef.current) {
            formRef.current.submit();
          }
        }}
      />
    </>
  );
};

export default AddUserAddress;
