import { createContext, useContext, useState, useEffect } from 'react'
import {
  account,
  databases,
  DATABASE_ID,
  COLLECTIONS,
  ID,
  Query,
  hasAppwriteSession,
  isDemoMode,
  projectId as PROJECT_ID,
} from '../lib/appwrite'

const AuthContext = createContext()

const DEMO_MODE = isDemoMode

// #region agent log
if (typeof window !== 'undefined') {
  fetch('http://127.0.0.1:7284/ingest/0747da40-b90b-4354-9b84-c9b550a81ec9', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'X-Debug-Session-Id': '252827' },
    body: JSON.stringify({
      sessionId: '252827',
      runId: 'pre-fix',
      hypothesisId: 'B',
      location: 'AuthContext.jsx:init',
      message: 'Auth DEMO_MODE resolved',
      data: { DEMO_MODE, PROJECT_ID: PROJECT_ID ? PROJECT_ID.slice(0, 8) : '' },
      timestamp: Date.now(),
    }),
  }).catch(() => {})
}
// #endregion

function clearStaleAppwriteSessions() {
  if (typeof window === 'undefined' || !window.localStorage) return
  try {
    const raw = window.localStorage.getItem('cookieFallback')
    if (!raw) return
    const parsed = JSON.parse(raw)
    if (typeof parsed !== 'object' || parsed === null) return
    for (const key of Object.keys(parsed)) {
      if (key.startsWith('a_session_') && key !== `a_session_${PROJECT_ID}`) {
        delete parsed[key]
      }
    }
    window.localStorage.setItem('cookieFallback', JSON.stringify(parsed))
  } catch {
    window.localStorage.removeItem('cookieFallback')
  }
}

function clearAllLocalAppwriteSessions() {
  if (typeof window === 'undefined') return
  try {
    window.localStorage.removeItem('cookieFallback')
  } catch { /* ignore */ }
}

async function createSessionWithCleanup(email, password) {
  try {
    await account.deleteSessions()
  } catch { /* alte Sitzung ggf. nur serverseitig */ }
  clearAllLocalAppwriteSessions()
  if (account.createEmailPasswordSession) {
    await account.createEmailPasswordSession(email, password)
  } else {
    await account.createEmailSession(email, password)
  }
}

// Hilfsfunktion: Fügt User automatisch zur employees Collection hinzu
async function ensureEmployeeExists(user) {
  if (!user || DEMO_MODE) return

  try {
    const response = await databases.listDocuments(
      DATABASE_ID,
      COLLECTIONS.EMPLOYEES,
      [Query.equal('userId', user.$id)]
    )

    if (response.documents.length === 0) {
      await databases.createDocument(
        DATABASE_ID,
        COLLECTIONS.EMPLOYEES,
        ID.unique(),
        {
          userId: user.$id,
          displayName: user.name || user.email,
          email: user.email,
          shortcode: ''
        }
      )
      console.log('✅ User automatisch zur Mitarbeiter-Liste hinzugefügt')
    }
  } catch (error) {
    if (error.code !== 404) {
      console.warn('Could not add user to employees collection:', error.message)
    }
  }
}

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    checkUser()
  }, [])

  async function checkUser() {
    if (DEMO_MODE) {
      const demoUser = localStorage.getItem('demo_user')
      if (demoUser) {
        setUser(JSON.parse(demoUser))
      }
      setLoading(false)
      return
    }

    if (!hasAppwriteSession()) {
      setUser(null)
      setLoading(false)
      return
    }

    try {
      const session = await account.get()
      setUser(session)
      await ensureEmployeeExists(session)
    } catch (error) {
      if (error.code !== 401 && error.code !== 404) {
        console.error('Unexpected error checking user:', error)
      }
      if (error.code === 401) {
        clearAllLocalAppwriteSessions()
      }
      setUser(null)
    } finally {
      setLoading(false)
    }
  }

  async function login(email, password) {
    if (DEMO_MODE) {
      const demoUser = { $id: 'demo', email, name: email.split('@')[0] }
      localStorage.setItem('demo_user', JSON.stringify(demoUser))
      setUser(demoUser)
      return { success: true }
    }

    try {
      const normalizedEmail = email.trim()
      const normalizedPassword = password.trim()
      clearStaleAppwriteSessions()

      await createSessionWithCleanup(normalizedEmail, normalizedPassword)

      const session = await account.get()
      setUser(session)
      await ensureEmployeeExists(session)

      return { success: true }
    } catch (error) {
      console.error('Login error:', error)
      let errorMessage = error.message || 'Login fehlgeschlagen'

      if (error.code === 429 || errorMessage.includes('Rate limit')) {
        errorMessage = 'Zu viele Login-Versuche. Bitte 15–30 Minuten warten und es erneut versuchen.'
      } else if (errorMessage.includes('missing scopes') && errorMessage.includes('account')) {
        errorMessage = 'Session konnte nicht gespeichert werden. Bitte Seite neu laden und erneut versuchen.'
      } else if (
        error?.type === 'user_session_already_exists' ||
        errorMessage.includes('session is active')
      ) {
        errorMessage = 'Es gibt noch eine alte Sitzung. Bitte Seite neu laden und erneut anmelden.'
      } else if (error.code === 401 || errorMessage.includes('Invalid credentials')) {
        errorMessage = 'Ungültige Email oder Passwort'
      } else if (errorMessage.includes('User not found')) {
        errorMessage = 'Benutzer nicht gefunden. Bitte registriere dich zuerst.'
      } else if (errorMessage.includes('Email/Password')) {
        errorMessage = 'Email/Password Authentifizierung ist nicht aktiviert. Bitte aktiviere sie in deinem Appwrite Dashboard unter Auth → Providers.'
      }

      return { success: false, error: errorMessage }
    }
  }

  async function logout() {
    if (DEMO_MODE) {
      localStorage.removeItem('demo_user')
      setUser(null)
      return
    }

    try {
      await account.deleteSessions()
    } catch (error) {
      console.error('Logout error:', error)
    } finally {
      clearAllLocalAppwriteSessions()
      setUser(null)
    }
  }

  const isAdmin = Boolean(user?.labels?.includes('admin'))

  const value = {
    user,
    loading,
    login,
    logout,
    isAdmin
  }

  return (
    <AuthContext.Provider value={value}>
      {children}
    </AuthContext.Provider>
  )
}

export function useAuth() {
  return useContext(AuthContext)
}
