import { createContext, useContext, useEffect, useState, useCallback } from 'react'
import { syncUser } from '../services/api.js'

const AuthContext = createContext(null)
const STORAGE_KEY = 'aipro_auth_user_v1'

/** 校验邮箱格式 */
export function validateEmail(email) {
  if (!email) return '请填写邮箱'
  const re = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/
  if (!re.test(email)) return '邮箱格式不正确'
  if (email.length > 120) return '邮箱过长'
  return ''
}

/** 校验中国大陆手机号 */
export function validatePhone(phone) {
  if (!phone) return '请填写手机号'
  const re = /^1[3-9]\d{9}$/
  if (!re.test(phone)) return '请输入 11 位中国大陆手机号'
  return ''
}

function loadUser() {
  try {
    const raw = localStorage.getItem(STORAGE_KEY)
    if (!raw) return null
    const u = JSON.parse(raw)
    if (!u || !u.email || !u.phone) return null
    return u
  } catch { return null }
}

/** 从 sync 响应中提取 role 字段（兼容 { data: {...} } 与裸对象） */
function pickRole(resp) {
  const d = resp?.data || resp
  const role = d && typeof d.role === 'string' ? d.role : null
  return role || null
}

function saveUser(user) {
  try { localStorage.setItem(STORAGE_KEY, JSON.stringify(user)) } catch {}
}

function clearUser() {
  try { localStorage.removeItem(STORAGE_KEY) } catch {}
}

// 模块加载时即同步将 localStorage 恢复的用户写入 window，
// 避免首次渲染前的请求（例如 SkillsContext 初始化拉列表）错过身份头
if (typeof window !== 'undefined') {
  window.__AIPRO_USER__ = loadUser()
}

export function AuthProvider({ children }) {
  const [user, setUser] = useState(() => {
    const u = loadUser()
    // 保障：双重写入，防止模块加载顺序异常
    if (typeof window !== 'undefined') window.__AIPRO_USER__ = u
    return u
  })

  // 同步到 window 全局，axios 拦截器读取
  useEffect(() => {
    if (typeof window !== 'undefined') {
      window.__AIPRO_USER__ = user
    }
  }, [user])

  // 已登录但本地未带 role：拉一次 sync 补全（兼容旧版本 localStorage 数据）
  useEffect(() => {
    if (!user || user.role) return
    syncUser()
      .then(resp => {
        const role = pickRole(resp)
        if (!role) return
        setUser(prev => {
          if (!prev) return prev
          const next = { ...prev, role }
          saveUser(next)
          return next
        })
      })
      .catch(() => {})
    // 只关心 user 从无到有 / 从无 role 到需要补 role 的情况
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [user?.email, user?.phone])

  // 多标签页同步：监听其他标签页对 localStorage 的修改
  useEffect(() => {
    const handleStorage = (e) => {
      if (e.key !== STORAGE_KEY) return
      if (e.newValue === null) {
        // 其他标签页执行了 logout
        setUser(null)
      } else {
        try {
          const u = JSON.parse(e.newValue)
          if (u && u.email && u.phone) {
            setUser(u)
          } else {
            setUser(null)
          }
        } catch {
          setUser(null)
        }
      }
    }
    window.addEventListener('storage', handleStorage)
    return () => window.removeEventListener('storage', handleStorage)
  }, [])

  const login = useCallback((email, phone) => {
    const cleanEmail = String(email || '').trim().toLowerCase()
    const cleanPhone = String(phone || '').trim()
    const emailErr = validateEmail(cleanEmail)
    if (emailErr) throw new Error(emailErr)
    const phoneErr = validatePhone(cleanPhone)
    if (phoneErr) throw new Error(phoneErr)

    const existed = loadUser()
    const isReturning = existed && existed.email === cleanEmail && existed.phone === cleanPhone
    const u = {
      email: cleanEmail,
      phone: cleanPhone,
      name: cleanEmail.split('@')[0],
      registered_at: existed?.registered_at || new Date().toISOString(),
      last_login_at: new Date().toISOString(),
      is_returning: !!isReturning,
    }
    saveUser(u)
    if (typeof window !== 'undefined') window.__AIPRO_USER__ = u
    setUser(u)

    // 广播登录事件，让依赖分类数据的 Provider 重新拉取（CategoryContext 监听该事件）
    try { window.dispatchEvent(new Event('aipro:auth-changed')) } catch {}

    // 同步用户信息到后端：完成后把 role 写回用户对象，供权限判断使用
    syncUser()
      .then(resp => {
        const role = pickRole(resp)
        if (!role) return
        const merged = { ...u, role }
        saveUser(merged)
        setUser(merged)
      })
      .catch(() => {})

    return u
  }, [])

  const logout = useCallback(() => {
    clearUser()
    setUser(null)
  }, [])

  const value = { user, isAuthed: !!user, login, logout }
  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>
}

export function useAuth() {
  const ctx = useContext(AuthContext)
  if (!ctx) throw new Error('useAuth must be used within AuthProvider')
  return ctx
}
