import { useCallback, useMemo, useRef, useState } from 'react'
import Taro, { useDidShow } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'
import {
  Address,
  Button,
  Cell,
  CellGroup,
  Checkbox,
  ConfigProvider,
  Empty,
  InfiniteLoading,
  Loading,
  Popup,
  PullToRefresh,
  SearchBar,
  Tag
} from '@nutui/nutui-react-taro'
import { Copy, Phone } from '@nutui/icons-react-taro'

import RegionData from '@/api/json/regions-data.json'
import { pageCreditCompany, updateCreditCompany } from '@/api/credit/creditCompany'
import type { CreditCompany } from '@/api/credit/creditCompany/model'
import { listUsers } from '@/api/system/user'
import type { User } from '@/api/system/user/model'
import { hasRole } from '@/utils/permission'

const PAGE_SIZE = 10

type FollowStatus = '全部' | '未联系' | '加微前沟通' | '跟进中' | '已成交' | '无意向'

const FOLLOW_STATUS_OPTIONS: FollowStatus[] = ['全部', '未联系', '加微前沟通', '跟进中', '已成交', '无意向']

const FOLLOW_MAP_STORAGE_KEY = 'credit_company_follow_status_map'

const safeParseJSON = <T,>(v: any): T | null => {
  try {
    if (!v) return null
    if (typeof v === 'object') return v as T
    if (typeof v === 'string') return JSON.parse(v) as T
    return null
  } catch (_e) {
    return null
  }
}

const getCompanyIdKey = (c: CreditCompany) => String(c?.id || '')

const splitPhones = (raw?: string) => {
  const text = String(raw || '').trim()
  if (!text) return []
  // 常见分隔符：逗号/顿号/分号/换行/空格
  return text
    .split(/[\s,，;；、\n\r]+/g)
    .map(s => s.trim())
    .filter(Boolean)
}

const getCompanyPhones = (c: CreditCompany) => {
  const arr = [...splitPhones(c.tel), ...splitPhones(c.moreTel)]
  return Array.from(new Set(arr))
}

const getCompanyIndustry = (c: CreditCompany) => {
  // 兼容：不同数据源字段可能不一致，优先取更具体的大类
  return String(
    c.nationalStandardIndustryCategories6 ||
      c.nationalStandardIndustryCategories2 ||
      c.nationalStandardIndustryCategories ||
      c.institutionType ||
      ''
  ).trim()
}

export default function CreditCompanyPage() {
  const serverPageRef = useRef(1)
  const [list, setList] = useState<CreditCompany[]>([])
  const [hasMore, setHasMore] = useState(true)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const [searchValue, setSearchValue] = useState('')

  const [cityVisible, setCityVisible] = useState(false)
  const [cityText, setCityText] = useState<string>('全部')

  const [followVisible, setFollowVisible] = useState(false)
  const [followStatus, setFollowStatus] = useState<FollowStatus>('全部')

  const [industryVisible, setIndustryVisible] = useState(false)
  const [industryText, setIndustryText] = useState<string>('全部')

  const [selectMode, setSelectMode] = useState(false)
  const [selectedIds, setSelectedIds] = useState<number[]>([])

  const [staffPopupVisible, setStaffPopupVisible] = useState(false)
  const [staffLoading, setStaffLoading] = useState(false)
  const [staffList, setStaffList] = useState<User[]>([])
  const [staffSelectedId, setStaffSelectedId] = useState<number | undefined>(undefined)
  const [assigning, setAssigning] = useState(false)

  const [followMap, setFollowMap] = useState<Record<string, FollowStatus>>(() => {
    const raw = Taro.getStorageSync(FOLLOW_MAP_STORAGE_KEY)
    return safeParseJSON<Record<string, FollowStatus>>(raw) || {}
  })

  const currentUser = useMemo(() => {
    return safeParseJSON<User>(Taro.getStorageSync('User')) || ({} as User)
  }, [])

  const canAssign = useMemo(() => {
    // 超级管理员：允许分配并更改客户归属（userId）
    if (currentUser?.isSuperAdmin) return true
    if (hasRole('superAdmin')) return true
    return false
  }, [currentUser?.isSuperAdmin])

  const cityOptions = useMemo(() => {
    // NutUI Address options: [{ text, value, children }]
    // @ts-ignore
    return (RegionData || []).map(a => ({
      value: a.label,
      text: a.label,
      children: (a.children || []).map(b => ({
        value: b.label,
        text: b.label,
        children: (b.children || []).map(c => ({
          value: c.label,
          text: c.label
        }))
      }))
    }))
  }, [])

  const staffNameMap = useMemo(() => {
    const map = new Map<number, string>()
    for (const u of staffList) {
      if (!u?.userId) continue
      const name = String(u.realName || u.nickname || u.username || `员工${u.userId}`)
      map.set(u.userId, name)
    }
    return map
  }, [staffList])

  const getFollowStatus = useCallback(
    (c: CreditCompany): FollowStatus => {
      const k = getCompanyIdKey(c)
      const stored = k ? followMap[k] : undefined
      if (stored) return stored
      return '未联系'
    },
    [followMap]
  )

  const setFollowStatusFor = async (c: CreditCompany) => {
    if (!c?.id) return
    try {
      const res = await Taro.showActionSheet({
        itemList: FOLLOW_STATUS_OPTIONS.filter(s => s !== '全部')
      })
      const next = FOLLOW_STATUS_OPTIONS.filter(s => s !== '全部')[res.tapIndex] as FollowStatus | undefined
      if (!next) return

      setFollowMap(prev => {
        const k = getCompanyIdKey(c)
        const merged = { ...prev, [k]: next }
        Taro.setStorageSync(FOLLOW_MAP_STORAGE_KEY, merged)
        return merged
      })

      // 若当前正在按状态筛选，则即时移除不匹配项，避免“改完状态但列表不变”的割裂感。
      if (followStatus !== '全部' && next !== followStatus && c.id) {
        const cid = Number(c.id)
        setList(prev => prev.filter(x => Number(x.id) !== cid))
        setSelectedIds(prev => prev.filter(id => id !== cid))
      }
    } catch (e) {
      const msg = String((e as any)?.errMsg || (e as any)?.message || e || '')
      if (msg.includes('cancel')) return
    }
  }

  const applyFilters = useCallback(
    (incoming: CreditCompany[]) => {
      const city = cityText === '全部' ? '' : cityText
      const industry = industryText === '全部' ? '' : industryText
      const follow = followStatus === '全部' ? '' : followStatus

      return incoming.filter(c => {
        if (c?.deleted === 1) return false

        if (city) {
          const full = [c.province, c.city, c.region].filter(Boolean).join(' ')
          if (!full.includes(city) && String(c.city || '') !== city) return false
        }

        if (industry) {
          const ind = getCompanyIndustry(c)
          if (!ind.includes(industry)) return false
        }

        if (follow) {
          if (getFollowStatus(c) !== follow) return false
        }

        return true
      })
    },
    [cityText, followStatus, getFollowStatus, industryText]
  )

  const reload = useCallback(
    async (resetPage = false) => {
      if (loading) return
      setLoading(true)
      setError(null)

      if (resetPage) {
        serverPageRef.current = 1
        setHasMore(true)
        setSelectedIds([])
        setSelectMode(false)
      }

      let nextList = resetPage ? [] : list
      let page = serverPageRef.current
      let serverHasMore = true

      // 当筛选条件较严格时，可能需要多拉几页才能拿到“至少一条匹配数据”
      const MAX_PAGE_TRIES = 8
      let tries = 0

      try {
        while (tries < MAX_PAGE_TRIES) {
          tries += 1
          const params: any = {
            page,
            limit: PAGE_SIZE,
            keywords: searchValue?.trim() || undefined
          }

          const res = await pageCreditCompany(params)
          const incoming = (res?.list || []) as CreditCompany[]
          const filtered = applyFilters(incoming)

          if (resetPage) {
            nextList = filtered
            resetPage = false
          } else {
            nextList = nextList.concat(filtered)
          }

          page += 1

          // 服务端无更多页：终止
          if (incoming.length < PAGE_SIZE) {
            serverHasMore = false
            break
          }

          // 已拿到可展示数据：先返回，让用户继续滚动触发下一次加载
          if (filtered.length > 0) break
        }

        serverPageRef.current = page
        setList(nextList)
        setHasMore(serverHasMore)
      } catch (e) {
        console.error('加载客户列表失败:', e)
        setError('加载失败，请重试')
        setHasMore(false)
      } finally {
        setLoading(false)
      }
    },
    [applyFilters, list, loading, searchValue]
  )

  const handleRefresh = useCallback(async () => {
    await reload(true)
  }, [reload])

  const loadMore = useCallback(async () => {
    if (loading || !hasMore) return
    await reload(false)
  }, [hasMore, loading, reload])

  useDidShow(() => {
    reload(true).then()
    // 预加载员工列表，保证“跟进人(realName)”可展示
    ensureStaffLoaded().then()
  })

  const visibleIndustryOptions = useMemo(() => {
    const uniq = new Set<string>()
    for (const m of list) {
      const ind = getCompanyIndustry(m)
      if (ind) uniq.add(ind)
    }
    const arr = Array.from(uniq)
    arr.sort()
    return ['全部'].concat(arr)
  }, [list])

  const toggleSelectId = (companyId?: number, checked?: boolean) => {
    if (!companyId) return
    setSelectedIds(prev => {
      if (checked) return prev.includes(companyId) ? prev : prev.concat(companyId)
      return prev.filter(id => id !== companyId)
    })
  }

  const copyPhones = async () => {
    const pool = selectMode && selectedIds.length ? list.filter(c => selectedIds.includes(Number(c.id))) : list
    const phones = pool.flatMap(c => getCompanyPhones(c))
    const unique = Array.from(new Set(phones)).filter(Boolean)
    if (!unique.length) {
      Taro.showToast({ title: '暂无可复制的电话', icon: 'none' })
      return
    }
    await Taro.setClipboardData({ data: unique.join('\n') })
    Taro.showToast({ title: `已复制${unique.length}个电话`, icon: 'success' })
  }

  const callPhone = async (phone?: string) => {
    const num = String(phone || '').trim()
    if (!num) {
      Taro.showToast({ title: '暂无电话', icon: 'none' })
      return
    }
    try {
      await Taro.makePhoneCall({ phoneNumber: num })
    } catch (e) {
      console.error('拨号失败:', e)
      Taro.showToast({ title: '拨号失败', icon: 'none' })
    }
  }

  const openAddCustomer = () => {
    Taro.navigateTo({ url: '/credit/company/add' })
  }

  const ensureStaffLoaded = async () => {
    if (staffLoading) return
    if (staffList.length) return
    setStaffLoading(true)
    try {
      const res = await listUsers({ isAdmin: true } as any)
      setStaffList((res || []) as User[])
    } catch (e) {
      console.error('加载员工列表失败:', e)
      Taro.showToast({ title: '加载员工失败', icon: 'none' })
    } finally {
      setStaffLoading(false)
    }
  }

  const openAssign = async () => {
    if (!canAssign) {
      Taro.showToast({ title: '当前角色无分配权限', icon: 'none' })
      return
    }
    if (!selectMode) {
      setSelectMode(true)
      setSelectedIds([])
      Taro.showToast({ title: '请选择要分配的客户', icon: 'none' })
      return
    }
    if (!selectedIds.length) {
      Taro.showToast({ title: '请先勾选客户', icon: 'none' })
      return
    }
    await ensureStaffLoaded()
    setStaffPopupVisible(true)
  }

  const submitAssign = async () => {
    if (!staffSelectedId) {
      Taro.showToast({ title: '请选择分配对象', icon: 'none' })
      return
    }
    if (!selectedIds.length) {
      Taro.showToast({ title: '请先勾选客户', icon: 'none' })
      return
    }

    setAssigning(true)
    try {
      for (const id of selectedIds) {
        await updateCreditCompany({ id, userId: staffSelectedId } as any)
      }
      Taro.showToast({ title: '分配成功', icon: 'success' })
      setStaffPopupVisible(false)
      setSelectMode(false)
      setSelectedIds([])
      await reload(true)
    } catch (e) {
      console.error('分配失败:', e)
      Taro.showToast({ title: '分配失败，请重试', icon: 'none' })
    } finally {
      setAssigning(false)
    }
  }

  return (
    <View className="bg-gray-50 min-h-screen">
      <ConfigProvider>
        <View className="py-2">
          <SearchBar
            placeholder="公司名称 / 统一代码"
            value={searchValue}
            onChange={setSearchValue}
            onSearch={() => reload(true)}
          />
        </View>

        <View className="px-3 pb-2 flex items-center gap-2">
          <Button size="small" fill="outline" onClick={() => setCityVisible(true)}>
            {cityText === '全部' ? '地区' : cityText}
          </Button>
          <Button size="small" fill="outline" onClick={() => setFollowVisible(true)}>
            {followStatus === '全部' ? '跟进状态' : followStatus}
          </Button>
          <Button size="small" fill="outline" onClick={() => setIndustryVisible(true)}>
            {industryText === '全部' ? '行业' : industryText}
          </Button>
          <View className="flex-1" />
          <Button size="small" fill="outline" icon={<Copy />} onClick={copyPhones}>
            复制电话
          </Button>
        </View>

        {!!error && (
          <View className="px-4 pb-2 text-sm text-red-500">
            {error}
          </View>
        )}

        <PullToRefresh onRefresh={handleRefresh} headHeight={60}>
          <View className="px-3" style={{ height: 'calc(100vh - 190px)', overflowY: 'auto' }} id="credit-company-scroll">
            {list.length === 0 && !loading ? (
              <View className="flex flex-col justify-center items-center" style={{ height: 'calc(100vh - 240px)' }}>
                <Empty description="暂无客户数据" style={{ backgroundColor: 'transparent' }} />
              </View>
            ) : (
              <InfiniteLoading
                target="credit-company-scroll"
                hasMore={hasMore}
                onLoadMore={loadMore}
                loadingText={
                  <View className="flex justify-center items-center py-4">
                    <Loading />
                    <View className="ml-2">加载中...</View>
                  </View>
                }
                loadMoreText={
                  <View className="text-center py-4 text-gray-500">
                    {list.length === 0 ? '暂无数据' : '没有更多了'}
                  </View>
                }
              >
                {list.map((c, idx) => {
                  const id = Number(c.id)
                  const selected = !!id && selectedIds.includes(id)
                  const follow = getFollowStatus(c)
                  const ownerName =
                    // 兼容后端可能直接下发跟进人字段
                    (c as any)?.realName ||
                    (c as any)?.userRealName ||
                    (c as any)?.followRealName ||
                    (c.userId ? staffNameMap.get(Number(c.userId)) : undefined)
                  const name = c.matchName || c.name || `企业${c.id || ''}`
                  const industry = getCompanyIndustry(c)
                  const phones = getCompanyPhones(c)
                  const primaryPhone = phones[0]
                  return (
                    <CellGroup key={c.id || idx} className="mb-3">
                      <Cell
                        onClick={() => {
                          if (selectMode) return
                          if (!c?.id) return
                          Taro.navigateTo({ url: `/credit/company/detail?id=${c.id}` })
                        }}
                      >
                        <View className="flex gap-3 items-start w-full">
                          {selectMode && (
                            <View
                              className="pt-1"
                              onClick={(e) => {
                                e.stopPropagation()
                              }}
                            >
                              <Checkbox
                                checked={selected}
                                onChange={(checked) => toggleSelectId(id, checked)}
                              />
                            </View>
                          )}

                          <View className="flex-1 min-w-0">
                            <View className="flex items-start justify-between gap-2">
                              <View className="min-w-0 flex-1">
                                <View className="text-base font-bold text-gray-900 truncate">
                                  {name}
                                </View>
                                {!!industry && (
                                  <View className="text-xs text-gray-500 truncate mt-1">
                                    {industry}
                                  </View>
                                )}
                              </View>
                              <Tag
                                type={follow === '无意向' ? 'danger' : follow === '已成交' ? 'success' : 'primary'}
                                onClick={(e: any) => {
                                  e?.stopPropagation?.()
                                  setFollowStatusFor(c)
                                }}
                              >
                                {follow}
                              </Tag>
                            </View>

                            <View className="mt-2 flex items-center justify-between gap-2">
                              <View className="text-xs text-gray-600 truncate">
                                <Text className="mr-2">
                                  {primaryPhone ? primaryPhone : '暂无电话'}
                                </Text>
                                <Text className="text-gray-500">
                                  跟进人：{ownerName || '未分配'}
                                </Text>
                              </View>

                              <View className="flex items-center gap-2">
                                <Button
                                  size="small"
                                  fill="outline"
                                  icon={<Phone />}
                                  onClick={(e) => {
                                    e.stopPropagation()
                                    callPhone(primaryPhone)
                                  }}
                                >
                                  拨打
                                </Button>
                              </View>
                            </View>

                            {!!(c.province || c.city || c.region) && (
                              <View className="mt-2 text-xs text-gray-500 truncate">
                                {[c.province, c.city, c.region].filter(Boolean).join(' ')}
                              </View>
                            )}
                          </View>
                        </View>
                      </Cell>
                    </CellGroup>
                  )
                })}
              </InfiniteLoading>
            )}
          </View>
        </PullToRefresh>

        <View className="h-20 w-full" />
        <View className="fixed z-50 bottom-0 left-0 right-0 bg-white border-t border-gray-200 px-3 py-3 safe-area-bottom">
          <View className="flex items-center gap-3">
            <Button
              type="primary"
              style={{ background: '#ef4444' }}
              className="flex-1"
              onClick={openAddCustomer}
            >
              添加客户
            </Button>
            <Button
              type="primary"
              style={{ background: canAssign ? '#3b82f6' : '#94a3b8' }}
              disabled={!canAssign || assigning}
              className="flex-1"
              onClick={openAssign}
            >
              {selectMode ? '分配所选' : '分配客户'}
            </Button>
          </View>
          {selectMode && (
            <View className="mt-2 flex items-center justify-between text-xs text-gray-500">
              <Text>已选 {selectedIds.length} 个</Text>
              <View className="flex items-center justify-end gap-3">
                <Text
                  className="text-blue-600"
                  onClick={() => copyPhones()}
                >
                  复制所选电话
                </Text>
                <Text
                  className="text-gray-500"
                  onClick={() => {
                    setSelectMode(false)
                    setSelectedIds([])
                  }}
                >
                  取消
                </Text>
              </View>
            </View>
          )}
        </View>

        <Address
          visible={cityVisible}
          options={cityOptions as any}
          title="选择地区（到城市）"
          onChange={(value: any[]) => {
            const txt = value.filter(Boolean).slice(0, 2).join(' ')
            setCityText(txt || '全部')
            setCityVisible(false)
            reload(true).then()
          }}
          onClose={() => setCityVisible(false)}
        />

        <Popup
          visible={followVisible}
          position="bottom"
          style={{ height: '45vh' }}
          onClose={() => setFollowVisible(false)}
        >
          <View className="p-4">
            <View className="flex items-center justify-between mb-3">
              <Text className="text-base font-medium">跟进状态</Text>
              <Text className="text-sm text-gray-500" onClick={() => setFollowVisible(false)}>
                关闭
              </Text>
            </View>
            <CellGroup>
              {FOLLOW_STATUS_OPTIONS.map(s => (
                <Cell
                  key={s}
                  title={<Text className={s === followStatus ? 'text-blue-600' : ''}>{s}</Text>}
                  onClick={() => {
                    setFollowStatus(s)
                    setFollowVisible(false)
                    reload(true).then()
                  }}
                />
              ))}
            </CellGroup>
          </View>
        </Popup>

        <Popup
          visible={industryVisible}
          position="bottom"
          style={{ height: '45vh' }}
          onClose={() => setIndustryVisible(false)}
        >
          <View className="p-4">
            <View className="flex items-center justify-between mb-3">
              <Text className="text-base font-medium">行业</Text>
              <Text className="text-sm text-gray-500" onClick={() => setIndustryVisible(false)}>
                关闭
              </Text>
            </View>
            <CellGroup>
              {visibleIndustryOptions.map(s => (
                <Cell
                  key={s}
                  title={<Text className={s === industryText ? 'text-blue-600' : ''}>{s}</Text>}
                  onClick={() => {
                    setIndustryText(s)
                    setIndustryVisible(false)
                    reload(true).then()
                  }}
                />
              ))}
            </CellGroup>
          </View>
        </Popup>

        <Popup
          visible={staffPopupVisible}
          position="bottom"
          style={{ height: '65vh' }}
          onClose={() => {
            if (assigning) return
            setStaffPopupVisible(false)
          }}
        >
          <View className="p-4 flex flex-col" style={{ height: '65vh' }}>
            <View className="flex items-center justify-between mb-3">
              <Text className="text-base font-medium">选择分配对象</Text>
              <Text className="text-sm text-gray-500" onClick={() => !assigning && setStaffPopupVisible(false)}>
                关闭
              </Text>
            </View>

            <View className="flex-1 overflow-y-auto">
              {staffLoading ? (
                <View className="py-10 flex justify-center items-center text-gray-500">
                  <Loading />
                  <Text className="ml-2">加载中...</Text>
                </View>
              ) : (
                <CellGroup>
                  {staffList.map(u => (
                    <Cell
                      key={u.userId}
                      title={
                        <Text className={u.userId === staffSelectedId ? 'text-blue-600' : ''}>
                          {u.realName || u.nickname || u.username || `员工${u.userId}`}
                        </Text>
                      }
                      description={u.phone || ''}
                      onClick={() => setStaffSelectedId(u.userId)}
                    />
                  ))}
                  {!staffList.length && (
                    <Cell title={<Text className="text-gray-500">暂无员工数据</Text>} />
                  )}
                </CellGroup>
              )}
            </View>

            <View className="pt-3">
              <Button
                type="primary"
                block
                disabled={assigning || !staffSelectedId}
                onClick={submitAssign}
              >
                {assigning ? '分配中...' : `确认分配（${selectedIds.length}个）`}
              </Button>
            </View>
          </View>
        </Popup>

      </ConfigProvider>
    </View>
  )
}
