import { randomUUID } from "crypto"

export type UserStatus = "活跃" | "沉睡" | "流失风险"

export interface User {
  id: string
  name: string
  email: string
  phone: string
  avatar: string
  tags: string[]
  status: UserStatus
  rfmScore: number
  createdAt: string
  lastActiveAt: string
  // 画像扩展
  city: string
  store: string
  privateDomain: string
  project: string
  team: string
  persona: string[]
  source: "douyin" | "cunkebao_form_submit" | "touchkebao_call_in" | "pos_api" | "manual"
}

const cities = ["北京", "上海", "广州", "深圳", "成都", "杭州", "苏州", "武汉", "西安", "长沙"]
const stores = ["门店A1", "门店A2", "门店B1", "门店C3", "门店D2"]
const privateDomains = ["企业微信私域1", "社群A", "社群B", "公众号粉丝池"]
const projects = ["项目X", "项目Y", "项目Z", "活动618"]
const teams = ["团队一组", "团队二组", "团队增长", "客户成功"]
const personas = ["技术爱好者", "夜猫子", "内容创作者", "效率提升", "价格敏感", "品牌忠诚"]
const tagPool = [
  "高价值",
  "近7日活跃",
  "新客",
  "回流",
  "社群达人",
  "潜在复购",
  "高互动",
  "低客单",
  "私域粉",
  "公众号粉",
]
const statusPool: UserStatus[] = ["活跃", "沉睡", "流失风险"]
const avatars = [
  "/user-avatar-zhangsan.png",
  "/user-avatar-lisi.png",
  "/avatar-wanglei.png",
  "/generic-user-avatar.png",
  "/wechat-avatar-1.png",
  "/wechat-avatar-2.png",
  "/wechat-avatar-3.png",
]

const rand = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min
const pick = <T,>(arr: T[]) => arr[rand(0, arr.length - 1)]

function toPinyinLike(name: string) {
  const map: Record<string, string> = {
    张: "zhang",
    李: "li",
    王: "wang",
    赵: "zhao",
    刘: "liu",
    陈: "chen",
    杨: "yang",
    黄: "huang",
    周: "zhou",
    吴: "wu",
    徐: "xu",
    孙: "sun",
    胡: "hu",
    朱: "zhu",
    高: "gao",
    林: "lin",
    何: "he",
    郭: "guo",
    马: "ma",
    罗: "luo",
  }
  return name
    .split("")
    .map((c) => map[c] ?? "u")
    .join("")
}

function randomPhone() {
  const prefixes = [
    "139",
    "138",
    "137",
    "136",
    "135",
    "188",
    "187",
    "186",
    "185",
    "183",
    "182",
    "159",
    "158",
    "157",
    "156",
    "155",
  ]
  return `${pick(prefixes)}${rand(1000, 9999)}${rand(1000, 9999)}`
}

function randomTags() {
  const count = rand(2, 4)
  const s = new Set<string>()
  while (s.size < count) s.add(pick(tagPool))
  return Array.from(s)
}

function timeNearNow(daysSpan = 90) {
  const now = Date.now()
  const offset = rand(0, daysSpan * 86400000)
  return new Date(now - offset).toISOString()
}

let cache: User[] | null = null

function seed(n = 240) {
  const familyNames = [
    "张",
    "李",
    "王",
    "赵",
    "刘",
    "陈",
    "杨",
    "黄",
    "周",
    "吴",
    "徐",
    "孙",
    "胡",
    "朱",
    "高",
    "林",
    "何",
    "郭",
    "马",
    "罗",
  ]
  const givenNames = [
    "伟",
    "芳",
    "娜",
    "敏",
    "静",
    "秀英",
    "丽",
    "强",
    "磊",
    "军",
    "洋",
    "艳",
    "勇",
    "杰",
    "娟",
    "涛",
    "明",
    "超",
    "霞",
    "平",
    "俊",
    "凯",
    "佳",
    "鑫",
    "鹏",
    "晨",
    "倩",
    "颖",
    "梅",
    "慧",
    "雪",
    "宇",
    "涵",
    "宁",
    "璐",
    "龙",
    "震",
    "航",
    "璟",
    "钰",
  ]
  const list: User[] = []

  for (let i = 0; i < n; i++) {
    const name = `${pick(familyNames)}${pick(givenNames)}${Math.random() < 0.2 ? pick(givenNames) : ""}`
    const email = `${toPinyinLike(name)}${rand(1, 99)}@example.com`
    const u: User = {
      id: randomUUID(),
      name,
      email,
      phone: randomPhone(),
      avatar: avatars[i % avatars.length],
      tags: randomTags(),
      status: pick(statusPool),
      rfmScore: rand(20, 95),
      createdAt: timeNearNow(180),
      lastActiveAt: timeNearNow(15),
      city: pick(cities),
      store: pick(stores),
      privateDomain: pick(privateDomains),
      project: pick(projects),
      team: pick(teams),
      persona: [pick(personas), Math.random() > 0.6 ? pick(personas) : undefined].filter(Boolean) as string[],
      source: pick(["douyin", "cunkebao_form_submit", "touchkebao_call_in", "pos_api", "manual"]),
    }
    list.push(u)
  }
  return list
}

export function getUsersStore() {
  if (!cache) cache = seed()
  return cache
}

export interface QueryParams {
  q?: string
  tags?: string[]
  status?: UserStatus[]
  rfmMin?: number
  rfmMax?: number
  city?: string[]
  persona?: string[]
  source?: string[]
  page?: number
  pageSize?: number
}

export function queryUsers(params: QueryParams) {
  const { q, tags, status, rfmMin = 0, rfmMax = 100, city, persona, source, page = 1, pageSize = 20 } = params
  let list = getUsersStore()

  if (q && q.trim()) {
    const s = q.trim().toLowerCase()
    list = list.filter(
      (u) =>
        u.name.toLowerCase().includes(s) ||
        u.email.toLowerCase().includes(s) ||
        u.phone.includes(s) ||
        u.tags.some((t) => t.toLowerCase().includes(s)) ||
        u.persona.some((p) => p.toLowerCase().includes(s)),
    )
  }

  if (tags?.length) list = list.filter((u) => tags.every((t) => u.tags.includes(t)))
  if (status?.length) list = list.filter((u) => status.includes(u.status))
  list = list.filter((u) => u.rfmScore >= rfmMin && u.rfmScore <= rfmMax)
  if (city?.length) list = list.filter((u) => city.includes(u.city))
  if (persona?.length) list = list.filter((u) => u.persona.some((p) => persona.includes(p)))
  if (source?.length) list = list.filter((u) => source.includes(u.source))

  const total = list.length
  const start = (page - 1) * pageSize
  const data = list.slice(start, start + pageSize)

  return {
    data,
    pagination: { page, pageSize, total, totalPages: Math.max(1, Math.ceil(total / pageSize)) },
  }
}

export function addUser(input: Partial<User>) {
  const list = getUsersStore()
  const now = new Date().toISOString()
  const u: User = {
    id: randomUUID(),
    name: input.name ?? "新用户",
    email: input.email ?? "user@example.com",
    phone: input.phone ?? "13900000000",
    avatar: input.avatar ?? avatars[0],
    tags: input.tags ?? ["新客"],
    status: input.status ?? "活跃",
    rfmScore: input.rfmScore ?? 60,
    createdAt: now,
    lastActiveAt: now,
    city: input.city ?? pick(cities),
    store: input.store ?? pick(stores),
    privateDomain: input.privateDomain ?? pick(privateDomains),
    project: input.project ?? pick(projects),
    team: input.team ?? pick(teams),
    persona: input.persona ?? [pick(personas)],
    source: input.source ?? "manual",
  }
  list.unshift(u)
  return u
}
