import { useState, useEffect, useRef } from 'react'
import { useSearchParams } from 'react-router-dom'
import { Terminal } from 'lucide-react'
import { cn } from '@/lib/utils'
import { scriptBuilderApi } from '@/api'
import { ScriptBuilderChat } from '@/components/script-builder/ScriptBuilderChat'
import { ScriptBuilderInput } from '@/components/script-builder/ScriptBuilderInput'
import { ScriptPreviewModal } from '@/components/script-builder/ScriptPreviewModal'
import { ParameterizeAndSavePanel } from '@/components/scripts/ParameterizeAndSavePanel'
import type { ScriptBuilderSessionDetail, ScriptBuilderMessage } from '@/types'

const LANGUAGES = [
  { value: 'powershell', label: 'PowerShell' },
  { value: 'bash', label: 'Bash' },
  { value: 'python', label: 'Python' },
] as const

export default function ScriptBuilderPage() {
  const [searchParams] = useSearchParams()
  const [session, setSession] = useState<ScriptBuilderSessionDetail | null>(null)
  const [messages, setMessages] = useState<ScriptBuilderMessage[]>([])
  const [language, setLanguage] = useState('powershell')
  const [isLoading, setIsLoading] = useState(false)
  // Ref-based lock: prevents two concurrent handleSend calls (e.g. FlowPilot
  // handoff useEffect + user keystroke) from each calling createSession() and
  // creating two orphaned sessions. React state updates are async so isLoading
  // alone can't guard across two calls in the same render cycle.
  const creatingSessionRef = useRef(false)
  const [previewScript, setPreviewScript] = useState<{ script: string; filename: string | null } | null>(null)
  const [showSaveDialog, setShowSaveDialog] = useState(false)
  const [handoffProcessed, setHandoffProcessed] = useState(false)

  const hasMessages = messages.length > 0

  // Handle FlowPilot handoff on mount
  useEffect(() => {
    if (handoffProcessed) return
    setHandoffProcessed(true)

    const contextRaw = sessionStorage.getItem('scriptBuilderContext')
    if (!contextRaw) return

    try {
      const context = JSON.parse(contextRaw) as {
        from_session?: string
        prompt?: string
        language?: string
      }
      sessionStorage.removeItem('scriptBuilderContext')

      if (context.language) {
        setLanguage(context.language)
      }
      if (context.prompt) {
        // Auto-send the prompt
        handleSend(context.prompt, context.language || 'powershell')
      }
    } catch {
      sessionStorage.removeItem('scriptBuilderContext')
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  // Suppress unused searchParams warning — used to detect ?from=flowpilot context
  void searchParams

  const handleSend = async (content: string, langOverride?: string) => {
    const effectiveLanguage = langOverride || language

    // Optimistically add user message
    const userMessage: ScriptBuilderMessage = {
      role: 'user',
      content,
      created_at: new Date().toISOString(),
    }
    setMessages((prev) => [...prev, userMessage])
    setIsLoading(true)

    try {
      // Create session if needed
      let currentSession = session
      if (!currentSession) {
        if (creatingSessionRef.current) {
          // Another concurrent call is already creating the session; drop this send.
          setIsLoading(false)
          setMessages((prev) => prev.slice(0, -1))
          return
        }
        creatingSessionRef.current = true
        try {
          currentSession = await scriptBuilderApi.createSession(effectiveLanguage)
          setSession(currentSession)
        } finally {
          creatingSessionRef.current = false
        }
      }

      // Send message
      const response = await scriptBuilderApi.sendMessage(currentSession.id, content)

      const assistantMessage: ScriptBuilderMessage = {
        role: 'assistant',
        content: response.content,
        script: response.script,
        script_filename: response.script_filename,
        line_count: response.line_count,
        created_at: response.timestamp,
      }
      setMessages((prev) => [...prev, assistantMessage])
    } catch (err) {
      // Add error message
      const errorMessage: ScriptBuilderMessage = {
        role: 'assistant',
        content: `An error occurred: ${err instanceof Error ? err.message : 'Failed to generate response. Please try again.'}`,
        created_at: new Date().toISOString(),
      }
      setMessages((prev) => [...prev, errorMessage])
    } finally {
      setIsLoading(false)
    }
  }

  const handleViewScript = (script: string, filename: string | null) => {
    setPreviewScript({ script, filename })
  }

  const handleSaveScript = () => {
    setShowSaveDialog(true)
  }

  const handleSaved = async (payload: {
    name: string
    description: string | undefined
    category_id: string | undefined
    share_with_team: boolean
    script_body: string
    parameters_schema: { parameters: import('@/types').ScriptParameter[] }
  }) => {
    if (!session) return
    await scriptBuilderApi.saveToLibrary(session.id, {
      name: payload.name,
      description: payload.description,
      category_id: payload.category_id,
      share_with_team: payload.share_with_team,
      script_body: payload.script_body,
      parameters_schema: payload.parameters_schema,
    })
    setShowSaveDialog(false)
  }

  // Derive default name from session title or filename
  const defaultSaveName = session?.title
    || session?.latest_script_filename
    || 'Untitled Script'

  return (
    <div className="flex flex-col h-full min-h-0">
      {/* Header with language selector */}
      <div className="shrink-0 px-6 py-4 border-b" style={{ borderColor: 'var(--color-border-default)' }}>
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            <span className="flex items-center justify-center w-9 h-9 rounded-xl bg-[rgba(232,121,249,0.1)]">
              <Terminal size={18} className="text-fuchsia-400" />
            </span>
            <div>
              <h1 className="text-base font-heading font-bold text-foreground">Script Builder</h1>
              <p className="text-xs text-muted-foreground">Describe what you need, AI generates the script</p>
            </div>
          </div>

          {/* Language pills */}
          <div className="flex items-center gap-1 p-0.5 rounded-lg bg-[rgba(255,255,255,0.03)] border border-[rgba(255,255,255,0.06)]">
            {LANGUAGES.map((lang) => (
              <button
                key={lang.value}
                onClick={() => !hasMessages && setLanguage(lang.value)}
                disabled={hasMessages}
                className={cn(
                  "px-3 py-1.5 rounded-md text-xs font-sans text-xs font-medium transition-all",
                  language === lang.value
                    ? "bg-primary text-white"
                    : hasMessages
                      ? "text-text-muted cursor-not-allowed"
                      : "text-muted-foreground hover:text-foreground hover:bg-[rgba(255,255,255,0.04)]"
                )}
              >
                {lang.label}
              </button>
            ))}
          </div>
        </div>
      </div>

      {/* Chat area */}
      <ScriptBuilderChat
        messages={messages}
        language={language}
        onViewScript={handleViewScript}
        onSaveScript={handleSaveScript}
        isLoading={isLoading}
      />

      {/* Input */}
      <div className="shrink-0">
        <ScriptBuilderInput
          onSend={(content) => handleSend(content)}
          disabled={isLoading}
          showSuggestions={messages.length === 0}
        />
      </div>

      {/* Preview modal */}
      {previewScript && (
        <ScriptPreviewModal
          script={previewScript.script}
          filename={previewScript.filename}
          language={language}
          onClose={() => setPreviewScript(null)}
          onSave={() => {
            setPreviewScript(null)
            setShowSaveDialog(true)
          }}
        />
      )}

      {/* Save panel */}
      {showSaveDialog && session && session.latest_script && (
        <ParameterizeAndSavePanel
          scriptBody={session.latest_script}
          language={session.language}
          defaultName={defaultSaveName}
          onSave={handleSaved}
          onClose={() => setShowSaveDialog(false)}
        />
      )}
    </div>
  )
}
