import React, { createContext, useContext, useState, useEffect, useCallback } from 'react'
import { useRouter } from 'next/router'
import { authApi, api } from '../services/chatApiService'
import { socketService } from '../services/socketService'

interface User {
  id: string
  email: string
  name?: string
  role: 'user' | 'admin'
  daysRemaining?: number | null
  planId?: string | null
}

interface AuthContextType {
  user: User | null
  token: string | null
  loading: boolean
  login: (token: string, userData: User, refreshToken?: string) => void
  logout: () => void
}

const AuthContext = createContext<AuthContextType>({
  user: null,
  token: null,
  loading: true,
  login: () => {},
  logout: () => {},
})

const PUBLIC_ROUTES = ['/login']

export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
  const [user, setUser] = useState<User | null>(null)
  const [token, setToken] = useState<string | null>(null)
  const [loading, setLoading] = useState(true)
  const router = useRouter()

  // ── Valida sessão ao montar ──────────────────────────────────────────────

  useEffect(() => {
    const init = async () => {
      try {
        const storedToken = localStorage.getItem('token')
        if (!storedToken) return

        if (typeof window !== 'undefined') {
          document.cookie = `accessToken=${storedToken}; path=/; SameSite=Lax; Secure`
        }

        setToken(storedToken)
        socketService.connect(storedToken)
        const me = await authApi.me()

        if (me?.id) {
          setUser({
            id: me.id,
            email: me.email,
            name: me.name,
            role: (me.role ?? 'USER').toLowerCase() as 'user' | 'admin',
            daysRemaining: me.daysRemaining ?? null,
            planId: me.planId ?? null,
          })
        } else {
          await tryRefresh()
        }
      } catch {
        await tryRefresh()
      } finally {
        setLoading(false)
      }
    }
    init()
  }, [])

  // ── Redirect guard ───────────────────────────────────────────────────────

  useEffect(() => {
    if (loading) return
    const isPublic = PUBLIC_ROUTES.some((r) => router.pathname.startsWith(r))
    if (!user && !isPublic) router.replace('/login')
  }, [loading, user, router.pathname])

  // ── Helpers ──────────────────────────────────────────────────────────────

  const tryRefresh = async () => {
    try {
      const refreshToken = localStorage.getItem('refreshToken')
      if (!refreshToken) { clearSession(); return }

      const { data } = await api.post('/api/auth/refresh', { refreshToken })
      localStorage.setItem('token', data.accessToken)
      if (typeof window !== 'undefined') {
        document.cookie = `accessToken=${data.accessToken}; path=/; SameSite=Lax; Secure`
      }
      localStorage.setItem('refreshToken', data.refreshToken)
      setToken(data.accessToken)
      setUser({
        id: data.user.id,
        email: data.user.email,
        name: data.user.name,
        role: (data.user.role ?? 'USER').toLowerCase() as 'user' | 'admin',
      })
    } catch {
      clearSession()
    }
  }

  const clearSession = () => {
    localStorage.removeItem('token')
    localStorage.removeItem('refreshToken')
    if (typeof window !== 'undefined') {
      document.cookie = 'accessToken=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'
    }
    setToken(null)
    setUser(null)
  }

  const login = useCallback((newToken: string, userData: User, refreshToken?: string) => {
    localStorage.setItem('token', newToken)
    if (typeof window !== 'undefined') {
      document.cookie = `accessToken=${newToken}; path=/; SameSite=Lax; Secure`
    }
    if (refreshToken) localStorage.setItem('refreshToken', refreshToken)
    setToken(newToken)
    setUser(userData)
    socketService.connect(newToken)
    router.push(userData.role === 'admin' ? '/admin/dashboard' : '/inbox')
  }, [router])

  const logout = useCallback(async () => {
    try {
      await authApi.logout().catch(() => {})
    } finally {
      socketService.disconnect()
      clearSession()
      router.replace('/login')
    }
  }, [router])

  return (
    <AuthContext.Provider value={{ user, token, loading, login, logout }}>
      {children}
    </AuthContext.Provider>
  )
}

export const useAuth = () => useContext(AuthContext)
