"use client"

import { useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'
import { useUser } from '@stackframe/stack'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { Label } from '@/components/ui/label'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Badge } from '@/components/ui/badge'
import { Loader2, Copy, CheckCircle2, Cloud, Server, Share2 } from 'lucide-react'
import { ToolDefinition, ToolInput } from '@/lib/tools'
import { AI_MODELS, DEFAULT_MODEL, isOllamaModel } from '@/types/prompt'
import { useOllama } from '@/contexts/ollama-context'
import { SaveRunPanel } from '@/components/saved-runs/save-run-panel'
import { ShareMenu } from '@/components/share/share-menu'

interface ToolExecutorProps {
    tool: ToolDefinition
}

interface SavedRun {
    id: string
    name: string | null
    inputs: Record<string, string> | null
    output: string
    model: string
    createdAt: string
}

export function ToolExecutor({ tool }: ToolExecutorProps) {
    const router = useRouter()
    const user = useUser()
    const { settings: ollamaSettings } = useOllama()
    const [inputs, setInputs] = useState<Record<string, string>>({})
    const [output, setOutput] = useState<string>('')
    const [isLoading, setIsLoading] = useState(false)
    const [isCopied, setIsCopied] = useState(false)
    const [selectedModel, setSelectedModel] = useState<string>(DEFAULT_MODEL)

    // Saved runs state
    const [savedRuns, setSavedRuns] = useState<SavedRun[]>([])
    const [loadingRuns, setLoadingRuns] = useState(false)

    // Fetch saved runs
    useEffect(() => {
        const fetchRuns = async () => {
            if (!tool.slug || !user?.id) return
            setLoadingRuns(true)
            try {
                const res = await fetch(`/api/tools/${tool.slug}/saved-runs?userId=${user.id}`)
                if (res.ok) {
                    const data = await res.json()
                    setSavedRuns(data.runs || [])
                }
            } catch (err) {
                console.error("Failed to fetch runs:", err)
            } finally {
                setLoadingRuns(false)
            }
        }
        fetchRuns()
    }, [tool.slug, user?.id])

    const handleInputChange = (name: string, value: string) => {
        setInputs(prev => ({ ...prev, [name]: value }))
    }

    const handleExecute = async () => {
        setIsLoading(true)
        setOutput('')

        try {
            if (isOllamaModel(selectedModel)) {
                // Ollama: call directly from browser instead of through server
                const ollamaUrl = (ollamaSettings.apiUrl || "http://localhost:11434").replace(/\/+$/, "")

                // Build the prompt from tool's system prompt + inputs
                let finalPrompt = tool.systemPrompt
                for (const [key, value] of Object.entries(inputs)) {
                    finalPrompt = finalPrompt.replace(new RegExp(`{{${key}}}`, 'g'), value)
                }

                const res = await fetch(`${ollamaUrl}/api/generate`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        model: selectedModel,
                        prompt: finalPrompt,
                        stream: false,
                    }),
                })

                if (!res.ok) {
                    if (res.status === 0 || res.type === "opaque") {
                        throw new Error(
                            `Cannot reach Ollama. Make sure CORS is enabled:\n` +
                            `OLLAMA_ORIGINS=${window.location.origin} ollama serve`
                        )
                    }
                    throw new Error(`Ollama error: ${res.status}. Make sure Ollama is running.`)
                }

                const data = await res.json()
                setOutput(data.response)
            } else {
                // Cloud models: call server API
                const res = await fetch(`/api/tools/${tool.slug}/execute`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        inputs,
                        model: selectedModel,
                    }),
                })

                const data = await res.json()

                if (res.ok) {
                    setOutput(data.output)
                } else {
                    setOutput(`Error: ${data.error || 'Failed to execute tool'}`)
                }
            }
        } catch (error) {
            console.error('Execute error:', error)
            setOutput(
                error instanceof Error
                    ? `Error: ${error.message}`
                    : 'Error: Failed to execute tool. Please try again.'
            )
        } finally {
            setIsLoading(false)
        }
    }

    const handleCopy = async () => {
        if (output) {
            await navigator.clipboard.writeText(output)
            setIsCopied(true)
            setTimeout(() => setIsCopied(false), 2000)
        }
    }

    const handleSaveRun = async (name: string) => {
        if (!output) return

        const res = await fetch(`/api/tools/${tool.slug}/saved-runs`, {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
                userId: user?.id,
                name: name || null,
                inputs,
                output,
                model: selectedModel,
            }),
        })

        if (res.ok) {
            const newRun = await res.json()
            setSavedRuns(prev => [newRun, ...prev])
        } else {
            throw new Error("Failed to save")
        }
    }

    const getModelName = (modelId: string) => {
        if (isOllamaModel(modelId)) {
            return modelId.split(':')[0] || modelId
        }
        return AI_MODELS[modelId as keyof typeof AI_MODELS]?.name || modelId
    }

    const renderInput = (input: ToolInput) => {
        const value = inputs[input.name] || ''

        switch (input.type) {
            case 'textarea':
                return (
                    <Textarea
                        id={input.name}
                        placeholder={input.placeholder}
                        value={value}
                        onChange={(e) => handleInputChange(input.name, e.target.value)}
                        rows={4}
                        className="resize-none"
                    />
                )
            case 'select':
                return (
                    <Select
                        value={value}
                        onValueChange={(val) => handleInputChange(input.name, val)}
                    >
                        <SelectTrigger id={input.name}>
                            <SelectValue placeholder={input.placeholder || 'Select...'} />
                        </SelectTrigger>
                        <SelectContent>
                            {input.options?.map((option) => (
                                <SelectItem key={option} value={option}>
                                    {option}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                )
            case 'number':
                return (
                    <Input
                        id={input.name}
                        type="number"
                        placeholder={input.placeholder}
                        value={value}
                        onChange={(e) => handleInputChange(input.name, e.target.value)}
                    />
                )
            default:
                return (
                    <Input
                        id={input.name}
                        type="text"
                        placeholder={input.placeholder}
                        value={value}
                        onChange={(e) => handleInputChange(input.name, e.target.value)}
                    />
                )
        }
    }

    const isFormValid = tool.inputSchema.every(
        input => !input.required || (inputs[input.name] && inputs[input.name].trim() !== '')
    )

    // Check if selected model is Ollama
    const isOllama = isOllamaModel(selectedModel)

    return (
        <div className="grid lg:grid-cols-2 gap-8">
            {/* Input Form */}
            <Card className="glass">
                <CardHeader>
                    <div className="flex items-center justify-between">
                        <CardTitle>Inputs</CardTitle>
                        {tool.isPremium && (
                            <Badge className="bg-linear-to-r from-yellow-500 to-orange-500">
                                PRO
                            </Badge>
                        )}
                    </div>
                    <CardDescription>
                        Fill in the details below
                    </CardDescription>
                </CardHeader>
                <CardContent className="space-y-4">
                    {/* Model Selector */}
                    <div className="space-y-2">
                        <Label>AI Model</Label>
                        <Select value={selectedModel} onValueChange={setSelectedModel}>
                            <SelectTrigger>
                                <SelectValue>
                                    <div className="flex items-center gap-2">
                                        {isOllama ? (
                                            <Server className="h-4 w-4 text-green-500" />
                                        ) : (
                                            <Cloud className="h-4 w-4 text-blue-500" />
                                        )}
                                        <span>
                                            {isOllama
                                                ? selectedModel
                                                : AI_MODELS[selectedModel as keyof typeof AI_MODELS]?.name || selectedModel
                                            }
                                        </span>
                                    </div>
                                </SelectValue>
                            </SelectTrigger>
                            <SelectContent>
                                {/* Cloud Models */}
                                <div className="px-2 py-1 text-xs font-medium text-muted-foreground flex items-center gap-1">
                                    <Cloud className="h-3 w-3" /> Cloud Models
                                </div>
                                {Object.entries(AI_MODELS).map(([id, model]) => (
                                    <SelectItem key={id} value={id}>
                                        <div className="flex items-center gap-2">
                                            <span>{model.name}</span>
                                            <Badge variant="outline" className="text-xs">
                                                {model.provider}
                                            </Badge>
                                        </div>
                                    </SelectItem>
                                ))}

                                {/* Ollama Models */}
                                {ollamaSettings.enabled && ollamaSettings.availableModels.length > 0 && (
                                    <>
                                        <div className="px-2 py-1 text-xs font-medium text-muted-foreground flex items-center gap-1 border-t mt-1 pt-2">
                                            <Server className="h-3 w-3" /> Ollama (Local)
                                        </div>
                                        {ollamaSettings.availableModels.map((model) => (
                                            <SelectItem key={model} value={model}>
                                                <div className="flex items-center gap-2">
                                                    <span>{model}</span>
                                                    <Badge variant="outline" className="text-xs border-green-500/50">
                                                        Local
                                                    </Badge>
                                                </div>
                                            </SelectItem>
                                        ))}
                                    </>
                                )}

                                {/* Ollama not connected hint */}
                                {!ollamaSettings.enabled && (
                                    <div className="px-2 py-1 text-xs text-muted-foreground border-t mt-1 pt-2">
                                        <Server className="h-3 w-3 inline mr-1" />
                                        Connect Ollama in header for local models
                                    </div>
                                )}
                            </SelectContent>
                        </Select>
                    </div>

                    {tool.inputSchema.map((input) => (
                        <div key={input.name} className="space-y-2">
                            <Label htmlFor={input.name}>
                                {input.label}
                                {input.required && <span className="text-destructive ml-1">*</span>}
                            </Label>
                            {renderInput(input)}
                        </div>
                    ))}

                    <Button
                        onClick={handleExecute}
                        disabled={!isFormValid || isLoading}
                        className="w-full gap-2 btn-glow"
                        variant="gradient"
                        size="lg"
                    >
                        {isLoading ? (
                            <>
                                <Loader2 className="h-4 w-4 animate-spin" />
                                Generating...
                            </>
                        ) : (
                            <>
                                {tool.icon} Generate
                            </>
                        )}
                    </Button>
                </CardContent>
            </Card>

            {/* Output */}
            <Card className="glass">
                <CardHeader>
                    <div className="flex items-center justify-between">
                        <CardTitle>Output</CardTitle>
                        <div className="flex gap-2">
                            {output && (
                                <Button
                                    variant="ghost"
                                    size="sm"
                                    onClick={handleCopy}
                                    className="gap-2"
                                >
                                    {isCopied ? (
                                        <>
                                            <CheckCircle2 className="h-4 w-4" />
                                            Copied!
                                        </>
                                    ) : (
                                        <>
                                            <Copy className="h-4 w-4" />
                                            Copy
                                        </>
                                    )}
                                </Button>
                            )}
                            <ShareMenu
                                title={tool.name}
                                description={tool.description}
                            />
                        </div>
                    </div>
                    <CardDescription>
                        AI-generated result will appear here
                    </CardDescription>
                </CardHeader>
                <CardContent>
                    {output ? (
                        <div className="whitespace-pre-wrap bg-muted p-4 rounded-lg font-mono text-sm">
                            {output}
                        </div>
                    ) : (
                        <div className="text-center py-12 text-muted-foreground">
                            <span className="text-4xl mb-2 block">{tool.icon}</span>
                            <p>Fill in the inputs and click Generate</p>
                        </div>
                    )}
                </CardContent>
            </Card>

            {/* Save Run Panel */}
            <div className="lg:col-span-2">
                <SaveRunPanel
                    hasOutput={!!output && !output.startsWith('Error:')}
                    isRunning={isLoading}
                    onSave={handleSaveRun}
                    savedRuns={savedRuns}
                    loadingRuns={loadingRuns}
                    type="tool"
                    getModelName={getModelName}
                />
            </div>
        </div>
    )
}
