"use client"

import { useState, useCallback, useMemo } from "react"
import { useUser } from "@stackframe/stack"
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Input, Textarea } from "@/components/ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SelectGroup, SelectLabel } from "@/components/ui/select"
import { Badge } from "@/components/ui/badge"
import { extractVariables, generateSlug } from "@/lib/utils"
import { VariableSchema, PromptSchema, AI_MODELS, ModelId, DEFAULT_MODEL } from "@/types/prompt"
import { useOllama } from "@/contexts/ollama-context"
import { FrameworkSelector } from "@/components/create/framework-selector"
import { FrameworkScaffold } from "@/components/create/framework-scaffold"
import { PromptCoach } from "@/components/editor/prompt-coach"
import { getFramework, generateFromFramework, Framework } from "@/lib/frameworks"
import {
    Sparkles,
    Play,
    Save,
    Eye,
    Code,
    Plus,
    Trash2,
    GripVertical,
    ChevronDown,
    AlertCircle,
    Target
} from "lucide-react"
import { cn } from "@/lib/utils"

type VariableType = "text" | "textarea" | "dropdown" | "number" | "boolean"

const VARIABLE_TYPES: { value: VariableType; label: string }[] = [
    { value: "text", label: "Text Input" },
    { value: "textarea", label: "Text Area" },
    { value: "dropdown", label: "Dropdown" },
    { value: "number", label: "Number" },
    { value: "boolean", label: "Checkbox" },
]

const CATEGORIES = [
    "Content",
    "Development",
    "Marketing",
    "Business",
    "Education",
    "Creative",
    "Research",
    "Other",
]

interface EditorState {
    title: string
    description: string
    template: string
    category: string
    tags: string
    modelDefault: string
    visibility: "public" | "unlisted" | "private"
}

interface PromptEditorProps {
    initialData?: {
        title: string
        description: string | null
        template: string
        category: string | null
        tags: string[]
        modelDefault: string
        visibility: string
        schema: PromptSchema | null
    }
    promptSlug?: string // If provided, we're editing an existing prompt
}

export function PromptEditor({ initialData, promptSlug }: PromptEditorProps = {}) {
    const user = useUser()
    const { settings: ollamaSettings } = useOllama()
    const [state, setState] = useState<EditorState>({
        title: initialData?.title || "",
        description: initialData?.description || "",
        template: initialData?.template || "",
        category: initialData?.category || "",
        tags: initialData?.tags?.join(", ") || "",
        modelDefault: initialData?.modelDefault || DEFAULT_MODEL,
        visibility: (initialData?.visibility as EditorState["visibility"]) || "public",
    })

    // Initialize variables from initialData if editing
    const initialVariables = initialData?.schema?.variables || []

    const [variables, setVariables] = useState<VariableSchema[]>(initialVariables)
    const [isPreview, setIsPreview] = useState(false)
    const [isSaving, setIsSaving] = useState(false)
    const [error, setError] = useState<string | null>(null)

    // Framework Engine state
    const [selectedFramework, setSelectedFramework] = useState<string | null>(null)
    const [frameworkSections, setFrameworkSections] = useState<Record<string, string>>({})
    const [showFrameworkSelector, setShowFrameworkSelector] = useState(true)

    // Get the selected framework object
    const currentFramework = useMemo(() => {
        return selectedFramework ? getFramework(selectedFramework) : null
    }, [selectedFramework])

    // Handle framework selection
    const handleFrameworkSelect = (frameworkId: string | null) => {
        setSelectedFramework(frameworkId)
        setFrameworkSections({})
        if (!frameworkId) {
            // Clear template if deselecting framework
            setShowFrameworkSelector(false)
        } else {
            setShowFrameworkSelector(false)
        }
    }

    // Generate template from framework sections
    const handleGenerateFromFramework = useCallback(() => {
        if (currentFramework) {
            const generatedTemplate = generateFromFramework(currentFramework, frameworkSections)
            setState(s => ({ ...s, template: generatedTemplate }))
        }
    }, [currentFramework, frameworkSections])

    // Auto-detect variables from template
    const detectedVariables = useMemo(() => {
        return extractVariables(state.template)
    }, [state.template])

    // Sync detected variables with current variable configs
    const handleDetectVariables = useCallback(() => {
        const newVariables = detectedVariables.map((name) => {
            // Keep existing config if variable already exists
            const existing = variables.find((v) => v.name === name)
            if (existing) return existing

            return {
                name,
                type: "text" as const,
                label: name.charAt(0).toUpperCase() + name.slice(1).replace(/_/g, " "),
                placeholder: `Enter ${name.replace(/_/g, " ")}...`,
                required: true,
            }
        })
        setVariables(newVariables)
    }, [detectedVariables, variables])

    // Update a variable config
    const updateVariable = (index: number, updates: Partial<VariableSchema>) => {
        setVariables((prev) =>
            prev.map((v, i) => (i === index ? { ...v, ...updates } : v))
        )
    }

    // Handle form submission
    const handleSave = async (publish: boolean = false) => {
        setError(null)

        if (!state.title.trim()) {
            setError("Title is required")
            return
        }

        if (!state.template.trim()) {
            setError("Prompt template is required")
            return
        }

        setIsSaving(true)

        try {
            const schema: PromptSchema = {
                variables,
                output: {
                    format: "markdown",
                    streaming: true,
                },
            }

            const isEditing = !!promptSlug
            const url = isEditing ? `/api/prompts/${promptSlug}` : "/api/prompts"
            const method = isEditing ? "PUT" : "POST"

            const response = await fetch(url, {
                method,
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({
                    title: state.title,
                    description: state.description,
                    template: state.template,
                    schema,
                    category: state.category || null,
                    tags: state.tags.split(",").map((t) => t.trim()).filter(Boolean),
                    modelDefault: state.modelDefault,
                    visibility: publish ? state.visibility : "private",
                    ...(isEditing ? {} : {}), // creatorId is now handled server-side via auth
                }),
            })

            if (!response.ok) {
                throw new Error(isEditing ? "Failed to update prompt" : "Failed to save prompt")
            }

            const data = await response.json()

            // Redirect to the prompt page
            window.location.href = `/p/${data.slug || promptSlug}`

        } catch (err) {
            setError(err instanceof Error ? err.message : "Failed to save prompt")
        } finally {
            setIsSaving(false)
        }
    }

    return (
        <div className="grid lg:grid-cols-2 gap-6">
            {/* Left Pane - Template Editor */}
            <div className="space-y-4">
                {/* Framework Selector */}
                {showFrameworkSelector && (
                    <Card>
                        <CardContent className="pt-6">
                            <FrameworkSelector
                                selectedFramework={selectedFramework ?? undefined}
                                onSelect={handleFrameworkSelect}
                            />
                        </CardContent>
                    </Card>
                )}

                {/* Framework Scaffold - when a framework is selected */}
                {currentFramework && !showFrameworkSelector && (
                    <Card>
                        <CardHeader className="pb-3">
                            <div className="flex items-center justify-between">
                                <div className="flex items-center gap-2">
                                    <Target className="h-5 w-5 text-primary" />
                                    <CardTitle className="text-base">Using {currentFramework.name} Framework</CardTitle>
                                </div>
                                <div className="flex gap-2">
                                    <Button
                                        variant="ghost"
                                        size="sm"
                                        onClick={() => setShowFrameworkSelector(true)}
                                    >
                                        Change
                                    </Button>
                                    <Button
                                        variant="ghost"
                                        size="sm"
                                        onClick={() => {
                                            setSelectedFramework(null)
                                            setFrameworkSections({})
                                        }}
                                    >
                                        Clear
                                    </Button>
                                </div>
                            </div>
                        </CardHeader>
                        <CardContent className="space-y-4">
                            <FrameworkScaffold
                                framework={currentFramework}
                                sections={frameworkSections}
                                onSectionsChange={setFrameworkSections}
                            />
                            <Button
                                className="w-full gap-2"
                                onClick={handleGenerateFromFramework}
                                disabled={Object.keys(frameworkSections).length === 0}
                            >
                                <Sparkles className="h-4 w-4" />
                                Generate Template from Framework
                            </Button>
                        </CardContent>
                    </Card>
                )}

                {/* Button to show framework selector if hidden and no framework selected */}
                {!showFrameworkSelector && !currentFramework && (
                    <Button
                        variant="outline"
                        size="sm"
                        onClick={() => setShowFrameworkSelector(true)}
                        className="gap-2"
                    >
                        <Target className="h-4 w-4" />
                        Use a Framework
                    </Button>
                )}

                <Card>
                    <CardHeader>
                        <div className="flex items-center justify-between">
                            <CardTitle className="flex items-center gap-2">
                                <Code className="h-5 w-5" />
                                Prompt Template
                            </CardTitle>
                            {selectedFramework && (
                                <Badge variant="secondary" className="gap-1">
                                    <Target className="h-3 w-3" />
                                    {selectedFramework}
                                </Badge>
                            )}
                        </div>
                        <CardDescription>
                            Use {"{{variable_name}}"} syntax to create input fields
                        </CardDescription>
                    </CardHeader>
                    <CardContent className="space-y-4">
                        <Input
                            placeholder="Prompt Title"
                            value={state.title}
                            onChange={(e) => setState((s) => ({ ...s, title: e.target.value }))}
                            className="text-lg font-medium"
                        />

                        <Textarea
                            placeholder="Brief description of what this prompt does..."
                            value={state.description}
                            onChange={(e) => setState((s) => ({ ...s, description: e.target.value }))}
                            className="min-h-20"
                        />

                        <Textarea
                            placeholder={`Write your prompt here...

Example:
Write a blog post about {{topic}} in a {{tone}} tone.

The post should be {{length}} words and include:
- An engaging introduction
- 3 main points
- A compelling conclusion`}
                            value={state.template}
                            onChange={(e) => setState((s) => ({ ...s, template: e.target.value }))}
                            className="min-h-75 font-mono text-sm"
                        />

                        {/* AI Prompt Coach */}
                        <PromptCoach
                            prompt={state.template}
                            onApply={(improved) => setState((s) => ({ ...s, template: improved }))}
                        />

                        {detectedVariables.length > 0 && (
                            <div className="flex items-center justify-between p-3 bg-muted rounded-lg">
                                <span className="text-sm">
                                    Detected {detectedVariables.length} variable{detectedVariables.length !== 1 ? "s" : ""}:{" "}
                                    {detectedVariables.map((v, i) => (
                                        <span key={v}>
                                            <code className="prompt-variable">{`{{${v}}}`}</code>
                                            {i < detectedVariables.length - 1 ? ", " : ""}
                                        </span>
                                    ))}
                                </span>
                                <Button size="sm" variant="secondary" onClick={handleDetectVariables}>
                                    <Sparkles className="h-3.5 w-3.5 mr-1.5" />
                                    Configure
                                </Button>
                            </div>
                        )}
                    </CardContent>
                </Card>

                {/* Settings Card */}
                <Card>
                    <CardHeader>
                        <CardTitle className="text-base">Settings</CardTitle>
                    </CardHeader>
                    <CardContent className="space-y-4">
                        <div className="grid grid-cols-2 gap-4">
                            <div>
                                <label className="text-sm font-medium mb-1.5 block">Category</label>
                                <Select
                                    value={state.category}
                                    onValueChange={(val) => setState((s) => ({ ...s, category: val }))}
                                >
                                    <SelectTrigger>
                                        <SelectValue placeholder="Select category..." />
                                    </SelectTrigger>
                                    <SelectContent>
                                        {CATEGORIES.map((cat) => (
                                            <SelectItem key={cat} value={cat}>{cat}</SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                            </div>

                            <div>
                                <label className="text-sm font-medium mb-1.5 block">Default Model</label>
                                <Select
                                    value={state.modelDefault}
                                    onValueChange={(val) => setState((s) => ({ ...s, modelDefault: val }))}
                                >
                                    <SelectTrigger>
                                        <SelectValue placeholder="Select model..." />
                                    </SelectTrigger>
                                    <SelectContent>
                                        <SelectGroup>
                                            <SelectLabel className="flex items-center gap-1">☁️ Cloud Models</SelectLabel>
                                            {Object.entries(AI_MODELS).map(([id, model]) => (
                                                <SelectItem key={id} value={id}>{model.name}</SelectItem>
                                            ))}
                                        </SelectGroup>

                                        {ollamaSettings.enabled && ollamaSettings.availableModels.length > 0 && (
                                            <SelectGroup>
                                                <SelectLabel className="flex items-center gap-1 mt-2 border-t pt-2">🖥️ Ollama (Local)</SelectLabel>
                                                {ollamaSettings.availableModels.map((model) => (
                                                    <SelectItem key={model} value={model}>{model}</SelectItem>
                                                ))}
                                            </SelectGroup>
                                        )}
                                    </SelectContent>
                                </Select>
                            </div>
                        </div>

                        <div>
                            <label className="text-sm font-medium mb-1.5 block">Tags (comma-separated)</label>
                            <Input
                                placeholder="e.g., blog, writing, seo"
                                value={state.tags}
                                onChange={(e) => setState((s) => ({ ...s, tags: e.target.value }))}
                            />
                        </div>

                        <div>
                            <label className="text-sm font-medium mb-1.5 block">Visibility</label>
                            <div className="flex gap-2">
                                {(["public", "unlisted", "private"] as const).map((v) => (
                                    <Button
                                        key={v}
                                        variant={state.visibility === v ? "default" : "outline"}
                                        size="sm"
                                        onClick={() => setState((s) => ({ ...s, visibility: v }))}
                                        className="capitalize"
                                    >
                                        {v}
                                    </Button>
                                ))}
                            </div>
                        </div>
                    </CardContent>
                </Card>
            </div>

            {/* Right Pane - Variable Schema */}
            <div className="space-y-4">
                <Card>
                    <CardHeader>
                        <div className="flex items-center justify-between">
                            <CardTitle className="flex items-center gap-2">
                                <Sparkles className="h-5 w-5" />
                                Variable Configuration
                            </CardTitle>
                            <Button
                                variant="ghost"
                                size="sm"
                                onClick={() => setIsPreview(!isPreview)}
                                className="gap-1.5"
                            >
                                <Eye className="h-4 w-4" />
                                {isPreview ? "Edit" : "Preview"}
                            </Button>
                        </div>
                        <CardDescription>
                            Configure how each variable appears to users
                        </CardDescription>
                    </CardHeader>
                    <CardContent>
                        {variables.length === 0 ? (
                            <div className="text-center py-8 text-muted-foreground">
                                <Sparkles className="h-12 w-12 mx-auto mb-4 opacity-20" />
                                <p className="mb-2">No variables configured</p>
                                <p className="text-sm">
                                    Add {"{{variables}}"} to your template and click "Configure"
                                </p>
                            </div>
                        ) : (
                            <div className="space-y-4">
                                {variables.map((variable, index) => (
                                    <Card key={variable.name} className="border-dashed">
                                        <CardContent className="p-4 space-y-3">
                                            <div className="flex items-center gap-2">
                                                <GripVertical className="h-4 w-4 text-muted-foreground cursor-grab" />
                                                <code className="prompt-variable text-xs">
                                                    {`{{${variable.name}}}`}
                                                </code>
                                                <Badge variant="outline" className="capitalize text-xs ml-auto">
                                                    {variable.type}
                                                </Badge>
                                            </div>

                                            <div className="grid grid-cols-2 gap-3">
                                                <div>
                                                    <label className="text-xs font-medium mb-1 block">Label</label>
                                                    <Input
                                                        value={variable.label}
                                                        onChange={(e) => updateVariable(index, { label: e.target.value })}
                                                        placeholder="Field label"
                                                        className="h-8 text-sm"
                                                    />
                                                </div>
                                                <div>
                                                    <label className="text-xs font-medium mb-1 block">Type</label>
                                                    <select
                                                        value={variable.type}
                                                        onChange={(e) => updateVariable(index, {
                                                            type: e.target.value as VariableType
                                                        })}
                                                        className="flex h-8 w-full rounded-lg border border-border bg-background px-2 text-sm"
                                                    >
                                                        {VARIABLE_TYPES.map((t) => (
                                                            <option key={t.value} value={t.value}>{t.label}</option>
                                                        ))}
                                                    </select>
                                                </div>
                                            </div>

                                            <div>
                                                <label className="text-xs font-medium mb-1 block">Placeholder</label>
                                                <Input
                                                    value={variable.placeholder || ""}
                                                    onChange={(e) => updateVariable(index, { placeholder: e.target.value })}
                                                    placeholder="Placeholder text..."
                                                    className="h-8 text-sm"
                                                />
                                            </div>

                                            {variable.type === "dropdown" && (
                                                <div>
                                                    <label className="text-xs font-medium mb-1 block">
                                                        Options (comma-separated)
                                                    </label>
                                                    <Input
                                                        value={variable.options?.join(", ") || ""}
                                                        onChange={(e) => updateVariable(index, {
                                                            options: e.target.value.split(",").map((s) => s.trim())
                                                        })}
                                                        placeholder="Option 1, Option 2, Option 3"
                                                        className="h-8 text-sm"
                                                    />
                                                </div>
                                            )}

                                            <div className="flex items-center gap-4">
                                                <label className="flex items-center gap-2 cursor-pointer">
                                                    <input
                                                        type="checkbox"
                                                        checked={variable.required}
                                                        onChange={(e) => updateVariable(index, { required: e.target.checked })}
                                                        className="h-3.5 w-3.5 rounded"
                                                    />
                                                    <span className="text-xs">Required</span>
                                                </label>
                                            </div>
                                        </CardContent>
                                    </Card>
                                ))}
                            </div>
                        )}
                    </CardContent>
                </Card>

                {/* Error Display */}
                {error && (
                    <Card className="border-destructive">
                        <CardContent className="p-4 flex items-center gap-3">
                            <AlertCircle className="h-5 w-5 text-destructive" />
                            <p className="text-sm text-destructive">{error}</p>
                        </CardContent>
                    </Card>
                )}

                {/* Action Buttons */}
                <div className="flex gap-3">
                    <Button
                        variant="outline"
                        className="flex-1 gap-2"
                        onClick={() => handleSave(false)}
                        disabled={isSaving}
                    >
                        <Save className="h-4 w-4" />
                        Save Draft
                    </Button>
                    <Button
                        className="flex-1 gap-2"
                        onClick={() => handleSave(true)}
                        disabled={isSaving}
                    >
                        <Play className="h-4 w-4" />
                        {isSaving ? "Publishing..." : "Publish"}
                    </Button>
                </div>
            </div>
        </div>
    )
}
