import { Component, createSignal, onMount, For, Show } from 'solid-js'
import { Rocket, CheckCircle, XCircle, Loader, Sparkles, Key, LogOut, Shield, Terminal, Copy, ExternalLink } from 'lucide-solid'
import { getUserScopedKey } from '../../lib/user-storage'

interface AntigravityModel {
    id: string
    name: string
    family?: string
    reasoning?: boolean
    tool_call?: boolean
    limit?: {
        context: number
        output: number
    }
}

interface AntigravityToken {
    access_token: string
    refresh_token?: string
    expires_in: number
    created_at: number
}

const ANTIGRAVITY_TOKEN_KEY = "antigravity_oauth_token"

const AntigravitySettings: Component = () => {
    const [models, setModels] = createSignal<AntigravityModel[]>([])
    const [isLoading, setIsLoading] = createSignal(true)
    const [connectionStatus, setConnectionStatus] = createSignal<'idle' | 'testing' | 'connected' | 'failed'>('idle')
    const [authStatus, setAuthStatus] = createSignal<'unknown' | 'authenticated' | 'unauthenticated'>('unknown')
    const [error, setError] = createSignal<string | null>(null)
    const [showTokenInput, setShowTokenInput] = createSignal(false)
    const [tokenInput, setTokenInput] = createSignal('')
    const [copied, setCopied] = createSignal(false)

    // Check stored token on mount
    onMount(async () => {
        checkAuthStatus()
        await loadModels()
        await testConnection()
    })

    const getStoredToken = (): AntigravityToken | null => {
        if (typeof window === "undefined") return null
        try {
            const raw = window.localStorage.getItem(getUserScopedKey(ANTIGRAVITY_TOKEN_KEY))
            if (!raw) return null
            return JSON.parse(raw)
        } catch {
            return null
        }
    }

    const isTokenValid = (token: AntigravityToken | null): boolean => {
        if (!token) return false
        const createdAt = token.created_at > 1e12 ? Math.floor(token.created_at / 1000) : token.created_at
        const expiresAt = (createdAt + token.expires_in) * 1000 - 300000 // 5 min buffer
        return Date.now() < expiresAt
    }

    const checkAuthStatus = () => {
        const token = getStoredToken()
        if (isTokenValid(token)) {
            setAuthStatus('authenticated')
        } else {
            setAuthStatus('unauthenticated')
        }
    }

    const loadModels = async () => {
        setIsLoading(true)
        try {
            const response = await fetch('/api/antigravity/models')
            if (response.ok) {
                const data = await response.json()
                setModels(data.models || [])
                setError(null)
            } else {
                throw new Error('Failed to load models')
            }
        } catch (err) {
            console.error('Failed to load Antigravity models:', err)
            setError('Failed to load models')
        } finally {
            setIsLoading(false)
        }
    }

    const testConnection = async () => {
        setConnectionStatus('testing')
        try {
            const response = await fetch('/api/antigravity/test')
            if (response.ok) {
                const data = await response.json()
                setConnectionStatus(data.connected ? 'connected' : 'failed')
            } else {
                setConnectionStatus('failed')
            }
        } catch (err) {
            setConnectionStatus('failed')
        }
    }

    const handleTokenSubmit = () => {
        const token = tokenInput().trim()
        if (!token) {
            setError('Please enter a valid token')
            return
        }

        try {
            const tokenData: AntigravityToken = {
                access_token: token,
                expires_in: 3600, // 1 hour default
                created_at: Date.now()
            }

            window.localStorage.setItem(
                getUserScopedKey(ANTIGRAVITY_TOKEN_KEY),
                JSON.stringify(tokenData)
            )

            setAuthStatus('authenticated')
            setShowTokenInput(false)
            setTokenInput('')
            setError(null)
            loadModels()
        } catch (err) {
            setError('Failed to save token')
        }
    }

    const signOut = () => {
        window.localStorage.removeItem(getUserScopedKey(ANTIGRAVITY_TOKEN_KEY))
        setAuthStatus('unauthenticated')
    }

    const copyCommand = async () => {
        const command = 'npx opencode-antigravity-auth login'
        await navigator.clipboard.writeText(command)
        setCopied(true)
        setTimeout(() => setCopied(false), 2000)
    }

    const formatNumber = (num: number): string => {
        if (num >= 1000000) return `${(num / 1000000).toFixed(1)}M`
        if (num >= 1000) return `${(num / 1000).toFixed(0)}K`
        return num.toString()
    }

    const getModelFamily = (model: AntigravityModel): { label: string; color: string } => {
        if (model.id.startsWith('gemini')) return { label: 'Gemini', color: 'bg-blue-500/20 text-blue-400' }
        if (model.id.startsWith('claude')) return { label: 'Claude', color: 'bg-orange-500/20 text-orange-400' }
        if (model.id.startsWith('gpt')) return { label: 'GPT', color: 'bg-green-500/20 text-green-400' }
        return { label: model.family || 'Other', color: 'bg-zinc-700 text-zinc-400' }
    }

    return (
        <div class="space-y-6 p-6">
            {/* Header */}
            <div class="flex items-center justify-between">
                <div class="flex items-center gap-3">
                    <div class="p-2 bg-gradient-to-br from-purple-500/20 to-blue-500/20 rounded-lg">
                        <Rocket class="w-6 h-6 text-purple-400" />
                    </div>
                    <div>
                        <h2 class="text-xl font-semibold text-white">Antigravity</h2>
                        <p class="text-sm text-zinc-400">Premium models via Google authentication</p>
                    </div>
                </div>

                <div class="flex items-center gap-2">
                    {connectionStatus() === 'testing' && (
                        <span class="flex items-center gap-2 text-sm text-zinc-400">
                            <Loader class="w-4 h-4 animate-spin" />
                            Testing...
                        </span>
                    )}
                    {connectionStatus() === 'connected' && (
                        <span class="flex items-center gap-2 text-sm text-emerald-400">
                            <CheckCircle class="w-4 h-4" />
                            Connected
                        </span>
                    )}
                    {connectionStatus() === 'failed' && (
                        <span class="flex items-center gap-2 text-sm text-red-400">
                            <XCircle class="w-4 h-4" />
                            Offline
                        </span>
                    )}
                </div>
            </div>

            {/* Info Banner */}
            <div class="bg-gradient-to-r from-purple-500/10 via-blue-500/10 to-purple-500/10 border border-purple-500/20 rounded-xl p-4">
                <div class="flex items-start gap-3">
                    <Sparkles class="w-5 h-5 text-purple-400 mt-0.5" />
                    <div>
                        <h3 class="font-semibold text-purple-300 mb-1">Premium AI Models</h3>
                        <p class="text-sm text-zinc-300">
                            Antigravity provides access to Gemini 3 Pro/Flash, Claude Sonnet 4.5, Claude Opus 4.5,
                            and GPT-OSS 120B through Google's infrastructure.
                        </p>
                    </div>
                </div>
            </div>

            {/* Authentication Section */}
            <div class="bg-zinc-900/50 border border-zinc-800 rounded-xl p-4 space-y-4">
                <div class="flex items-center justify-between">
                    <div class="flex items-center gap-3">
                        <Shield class="w-5 h-5 text-zinc-400" />
                        <div>
                            <h4 class="font-medium text-white">Authentication</h4>
                            <p class="text-xs text-zinc-500">
                                {authStatus() === 'authenticated'
                                    ? 'Token configured - you can use Antigravity models'
                                    : 'Configure authentication to access premium models'}
                            </p>
                        </div>
                    </div>

                    <Show when={authStatus() === 'authenticated'}>
                        <div class="flex items-center gap-3">
                            <span class="flex items-center gap-2 px-3 py-1.5 bg-emerald-500/20 text-emerald-400 rounded-lg text-sm">
                                <CheckCircle class="w-4 h-4" />
                                Configured
                            </span>
                            <button
                                onClick={signOut}
                                class="flex items-center gap-2 px-3 py-1.5 text-sm text-zinc-400 hover:text-white bg-zinc-800 hover:bg-zinc-700 rounded-lg transition-colors"
                            >
                                <LogOut class="w-4 h-4" />
                                Clear
                            </button>
                        </div>
                    </Show>
                </div>

                <Show when={authStatus() === 'unauthenticated'}>
                    {/* SDK Mode Instructions */}
                    <div class="bg-blue-500/5 border border-blue-500/20 rounded-lg p-4 space-y-3">
                        <div class="flex items-center gap-2 text-blue-400">
                            <Terminal class="w-4 h-4" />
                            <span class="font-medium text-sm">Recommended: Use OpenCode SDK Mode</span>
                        </div>
                        <p class="text-xs text-zinc-400">
                            For the best experience, switch to OpenCode SDK mode in General settings.
                            The Antigravity plugin handles authentication automatically via Google OAuth.
                        </p>
                        <div class="flex items-center gap-2">
                            <code class="flex-1 px-3 py-2 bg-zinc-900 rounded text-xs font-mono text-zinc-300">
                                npx opencode-antigravity-auth login
                            </code>
                            <button
                                onClick={copyCommand}
                                class="p-2 text-zinc-400 hover:text-white bg-zinc-800 hover:bg-zinc-700 rounded transition-colors"
                                title="Copy command"
                            >
                                {copied() ? <CheckCircle class="w-4 h-4 text-emerald-400" /> : <Copy class="w-4 h-4" />}
                            </button>
                        </div>
                    </div>

                    {/* Manual Token Entry */}
                    <div class="border-t border-zinc-800 pt-4">
                        <Show when={!showTokenInput()}>
                            <button
                                onClick={() => setShowTokenInput(true)}
                                class="flex items-center gap-2 text-sm text-zinc-400 hover:text-white transition-colors"
                            >
                                <Key class="w-4 h-4" />
                                Or enter access token manually...
                            </button>
                        </Show>

                        <Show when={showTokenInput()}>
                            <div class="space-y-3">
                                <label class="block text-sm font-medium text-zinc-300">
                                    Access Token
                                </label>
                                <div class="flex gap-2">
                                    <input
                                        type="password"
                                        value={tokenInput()}
                                        onInput={(e) => setTokenInput(e.currentTarget.value)}
                                        placeholder="Paste your Google OAuth access token..."
                                        class="flex-1 px-3 py-2 bg-zinc-900 border border-zinc-700 rounded-lg text-sm text-white placeholder-zinc-500 focus:outline-none focus:border-purple-500"
                                    />
                                    <button
                                        onClick={handleTokenSubmit}
                                        class="px-4 py-2 bg-purple-600 hover:bg-purple-500 text-white rounded-lg text-sm transition-colors"
                                    >
                                        Save
                                    </button>
                                    <button
                                        onClick={() => { setShowTokenInput(false); setTokenInput(''); }}
                                        class="px-4 py-2 bg-zinc-800 hover:bg-zinc-700 text-zinc-400 rounded-lg text-sm transition-colors"
                                    >
                                        Cancel
                                    </button>
                                </div>
                                <p class="text-xs text-zinc-500">
                                    You can get an access token by running the Antigravity auth plugin in a terminal,
                                    or by extracting it from an authenticated Google Cloud session.
                                </p>
                            </div>
                        </Show>
                    </div>
                </Show>
            </div>

            {/* Error Display */}
            <Show when={error()}>
                <div class="p-4 bg-red-500/10 border border-red-500/30 rounded-lg text-red-400 text-sm">
                    {error()}
                </div>
            </Show>

            {/* Models Grid */}
            <div class="space-y-4">
                <div class="flex items-center justify-between">
                    <h3 class="text-lg font-medium text-white">Available Models</h3>
                    <button
                        onClick={loadModels}
                        disabled={isLoading()}
                        class="flex items-center gap-2 px-3 py-1.5 text-sm bg-zinc-800 hover:bg-zinc-700 rounded-lg transition-colors"
                    >
                        {isLoading() ? <Loader class="w-4 h-4 animate-spin" /> : null}
                        Refresh
                    </button>
                </div>

                <Show when={isLoading()}>
                    <div class="flex items-center justify-center py-12">
                        <div class="flex items-center gap-3 text-zinc-400">
                            <Loader class="w-6 h-6 animate-spin" />
                            <span>Loading models...</span>
                        </div>
                    </div>
                </Show>

                <Show when={!isLoading() && models().length > 0}>
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <For each={models()}>
                            {(model) => {
                                const family = getModelFamily(model)
                                return (
                                    <div class="group bg-zinc-900/50 border border-zinc-800 hover:border-purple-500/50 rounded-xl p-4 transition-all">
                                        <div class="flex items-start justify-between mb-3">
                                            <div>
                                                <h4 class="font-semibold text-white group-hover:text-purple-300 transition-colors">
                                                    {model.name}
                                                </h4>
                                                <p class="text-xs text-zinc-500 font-mono">{model.id}</p>
                                            </div>
                                            <span class={`px-2 py-0.5 text-[10px] font-bold uppercase rounded ${family.color}`}>
                                                {family.label}
                                            </span>
                                        </div>

                                        <div class="flex flex-wrap gap-2 mb-3">
                                            {model.reasoning && (
                                                <span class="px-2 py-0.5 text-[10px] bg-purple-500/20 text-purple-400 rounded">
                                                    Thinking
                                                </span>
                                            )}
                                            {model.tool_call && (
                                                <span class="px-2 py-0.5 text-[10px] bg-blue-500/20 text-blue-400 rounded">
                                                    Tool Use
                                                </span>
                                            )}
                                        </div>

                                        {model.limit && (
                                            <div class="flex items-center gap-4 text-xs text-zinc-500">
                                                <span>Context: {formatNumber(model.limit.context)}</span>
                                                <span>Output: {formatNumber(model.limit.output)}</span>
                                            </div>
                                        )}
                                    </div>
                                )
                            }}
                        </For>
                    </div>
                </Show>

                <Show when={!isLoading() && models().length === 0}>
                    <div class="text-center py-12 text-zinc-500">
                        <p>Models will be available after configuration.</p>
                    </div>
                </Show>
            </div>

            {/* Usage Info */}
            <div class="bg-zinc-900/50 border border-zinc-800 rounded-xl p-4">
                <h4 class="font-medium text-white mb-2">How to Use</h4>
                <ul class="text-sm text-zinc-400 space-y-1">
                    <li>• <strong>SDK Mode (Recommended):</strong> Switch to OpenCode binary mode and install the antigravity auth plugin</li>
                    <li>• <strong>Native Mode:</strong> Enter your access token manually above</li>
                    <li>• Select any Antigravity model from the model picker in chat</li>
                    <li>• Models include Gemini 3, Claude Sonnet/Opus 4.5, and GPT-OSS</li>
                    <li>• Thinking-enabled models show step-by-step reasoning</li>
                </ul>
            </div>

            {/* Plugin Link */}
            <div class="flex justify-center">
                <a
                    href="https://github.com/NoeFabris/opencode-antigravity-auth"
                    target="_blank"
                    rel="noopener noreferrer"
                    class="flex items-center gap-2 text-sm text-purple-400 hover:text-purple-300 transition-colors"
                >
                    <ExternalLink class="w-4 h-4" />
                    View Antigravity Auth Plugin on GitHub
                </a>
            </div>
        </div>
    )
}

export default AntigravitySettings
