import { createSignal } from "solid-js"
import { isElectronHost } from "./runtime-env"

// Storage key for active user
const ACTIVE_USER_KEY = "codenomad_active_user_id"

const [isLoggedIn, setLoggedIn] = createSignal(false)
const [isInitialized, setInitialized] = createSignal(false)

export { isLoggedIn, setLoggedIn, isInitialized }

/**
 * Set the active user ID
 */
export function setActiveUserId(userId: string | null): void {
    if (userId) {
        localStorage.setItem(ACTIVE_USER_KEY, userId)
        setLoggedIn(true)
        console.log(`[UserContext] Active user set to: ${userId}`)
    } else {
        localStorage.removeItem(ACTIVE_USER_KEY)
        setLoggedIn(false)
        console.log(`[UserContext] Active user cleared`)
    }
}

/**
 * Get the active user ID
 */
export function getActiveUserId(): string | null {
    return localStorage.getItem(ACTIVE_USER_KEY)
}

/**
 * Get headers with user ID for API requests
 */
export function getUserHeaders(): Record<string, string> {
    const userId = getActiveUserId()
    if (userId) {
        return { "X-User-Id": userId }
    }
    return {}
}

/**
 * Create fetch options with user headers
 */
export function withUserHeaders(options: RequestInit = {}): RequestInit {
    const userHeaders = getUserHeaders()
    if (Object.keys(userHeaders).length === 0) return options

    const headers = new Headers(options.headers || {})
    for (const [key, value] of Object.entries(userHeaders)) {
        headers.set(key, value)
    }

    return {
        ...options,
        headers,
    }
}

/**
 * Fetch wrapper that automatically includes user headers
 */
export async function userFetch(url: string | URL | Request, options: RequestInit = {}): Promise<Response> {
    return fetch(url, withUserHeaders(options))
}

/**
 * Globally patch fetch to include user headers for all internal /api/* requests
 * This ensures compatibility with legacy code and 3rd party libraries.
 */
export function patchFetch(): void {
    if ((window as any)._codenomad_fetch_patched) return
    (window as any)._codenomad_fetch_patched = true

    const originalFetch = window.fetch
    window.fetch = async function (input: RequestInfo | URL, init?: RequestInit) {
        let url = ""
        if (typeof input === "string") {
            url = input
        } else if (input instanceof URL) {
            url = input.toString()
        } else if (input instanceof Request) {
            url = input.url
        }

        // Only inject headers for internal API calls
        if (url.startsWith("/api/") || url.includes(window.location.origin + "/api/")) {
            return originalFetch(input, withUserHeaders(init))
        }

        return originalFetch(input, init)
    }
    console.log("[UserContext] Global fetch patched for /api/* requests")
}

/**
 * Initialize user context from Host (Electron/Tauri) or API
 * Call this on app startup
 */
export async function initializeUserContext(): Promise<void> {
    console.log(`[UserContext] Initializing... host=${isElectronHost()}`)
    try {
        if (isElectronHost()) {
            const api = (window as any).electronAPI
            if (api && api.getActiveUser) {
                console.log(`[UserContext] Requesting active user via api.getActiveUser()...`)
                const activeUser = await api.getActiveUser()
                console.log(`[UserContext] getActiveUser result:`, activeUser)

                if (activeUser?.id) {
                    console.log(`[UserContext] Host has active session: ${activeUser.id}`)
                    setActiveUserId(activeUser.id)
                } else {
                    console.log(`[UserContext] Host has no active session. Enforcing login.`)
                    setActiveUserId(null)
                }
            } else {
                console.warn(`[UserContext] electronAPI.getActiveUser not found. Falling back to web mode.`)
                await handleWebInit()
            }
        } else {
            await handleWebInit()
        }
    } catch (error) {
        console.error(`[UserContext] Critical initialization error:`, error)
        setActiveUserId(null)
    } finally {
        setInitialized(true)
    }
}

async function handleWebInit() {
    console.log(`[UserContext] Web init - checking local cache...`)
    const existingId = getActiveUserId()

    // In "Mandatory Login" mode, we might want to clear this on every fresh load
    // but for now let's see if the server validates it.
    if (existingId) {
        // We could verify this ID with the server here if we had a /api/users/me endpoint
        // For now, let's keep it but mark it as "unverified" or just let the first API fail
        console.log(`[UserContext] Found cached ID: ${existingId}. Validating session...`)

        // Strategy: We want mandatory login. If this is a fresh launch, we should probably clear it.
        // For Electron it's already cleared in main.ts. For Web it's tricky.
        // Let's lean towards SECURITY: if no one explicitly logged in THIS RUN, show login.

        // Actually, if we are in Electron and we hit this, it's because IPC failed.
        // If we are in Web, we trust it for now but we'll see.
        setLoggedIn(true)
    } else {
        console.log(`[UserContext] No cached ID found.`)
        setLoggedIn(false)
    }
}
