import { useState, useEffect, useRef, useCallback } from 'react'
import { cn, safeGetItem, safeSetItem } from '@/lib/utils'
import { MarkdownContent } from '@/components/ui/MarkdownContent'
import { StickyNote, X, Eye, Pencil, Loader2 } from 'lucide-react'

interface ScratchpadSidebarProps {
  sessionId: string
  initialContent: string
  onSave: (content: string) => Promise<void>
  onOpenChange?: (isOpen: boolean) => void
}

export function ScratchpadSidebar({ sessionId, initialContent, onSave, onOpenChange }: ScratchpadSidebarProps) {
  const [content, setContent] = useState(initialContent)
  const [lastSaved, setLastSaved] = useState(initialContent)
  const [isCollapsed, setIsCollapsed] = useState(() => {
    return safeGetItem('scratchpad-collapsed') !== 'false'
  })
  const [isSaving, setIsSaving] = useState(false)
  const [showPreview, setShowPreview] = useState(false)
  const [saveStatus, setSaveStatus] = useState<'idle' | 'unsaved' | 'saving' | 'saved' | 'error'>('idle')

  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)
  const fadeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  const hasUnsavedChanges = content !== lastSaved

  // Reset content when session changes
  useEffect(() => {
    setContent(initialContent)
    setLastSaved(initialContent)
    setSaveStatus('idle')
  }, [sessionId]) // eslint-disable-line react-hooks/exhaustive-deps

  // Update save status based on state
  useEffect(() => {
    if (isSaving) {
      setSaveStatus('saving')
    } else if (hasUnsavedChanges) {
      setSaveStatus('unsaved')
    }
  }, [isSaving, hasUnsavedChanges])

  // Persist collapse state and notify parent
  useEffect(() => {
    safeSetItem('scratchpad-collapsed', String(isCollapsed))
    onOpenChange?.(!isCollapsed)
  }, [isCollapsed, onOpenChange])

  // Keyboard shortcut: Ctrl+/ to toggle
  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if (e.ctrlKey && e.key === '/') {
        e.preventDefault()
        setIsCollapsed(prev => !prev)
      }
    }
    window.addEventListener('keydown', handler)
    return () => window.removeEventListener('keydown', handler)
  }, [])

  // beforeunload warning
  useEffect(() => {
    if (!hasUnsavedChanges) return

    const handler = (e: BeforeUnloadEvent) => {
      e.preventDefault()
    }
    window.addEventListener('beforeunload', handler)
    return () => window.removeEventListener('beforeunload', handler)
  }, [hasUnsavedChanges])

  const doSave = useCallback(async (text: string) => {
    setIsSaving(true)
    try {
      await onSave(text)
      setLastSaved(text)
      setSaveStatus('saved')

      // Clear "Saved" indicator after 2 seconds
      if (fadeTimerRef.current) clearTimeout(fadeTimerRef.current)
      fadeTimerRef.current = setTimeout(() => setSaveStatus('idle'), 2000)
    } catch {
      setSaveStatus('error')
    } finally {
      setIsSaving(false)
    }
  }, [onSave])

  const handleChange = (value: string) => {
    setContent(value)

    // Cancel any pending debounce
    if (debounceRef.current) clearTimeout(debounceRef.current)

    // Schedule save after 1000ms of inactivity
    debounceRef.current = setTimeout(() => {
      if (value !== lastSaved) {
        doSave(value)
      }
    }, 1000)
  }

  const handleBlur = () => {
    // Cancel pending debounce and save immediately
    if (debounceRef.current) clearTimeout(debounceRef.current)
    if (content !== lastSaved) {
      doSave(content)
    }
  }

  // Cleanup timers on unmount
  useEffect(() => {
    return () => {
      if (debounceRef.current) clearTimeout(debounceRef.current)
      if (fadeTimerRef.current) clearTimeout(fadeTimerRef.current)
    }
  }, [])

  return (
    <>
      {/* Floating button (visible when collapsed) */}
      <button
        onClick={() => setIsCollapsed(false)}
        className={cn(
          'fixed right-2 top-1/2 z-40 -translate-y-1/2 rounded-md p-2.5',
          'bg-card border border-border shadow-md',
          'text-muted-foreground hover:bg-accent hover:text-foreground',
          'transition-opacity duration-200',
          isCollapsed ? 'opacity-100' : 'pointer-events-none opacity-0'
        )}
        title="Open scratchpad (Ctrl+/)"
        aria-label="Open scratchpad (Ctrl+/)"
      >
        <StickyNote className="h-5 w-5" />
        {hasUnsavedChanges && (
          <div className="absolute -left-0.5 -top-0.5 h-2.5 w-2.5 rounded-full bg-amber-500" />
        )}
      </button>

      {/* Mobile backdrop */}
      {!isCollapsed && (
        <div
          className="fixed inset-0 z-30 bg-black/80 backdrop-blur-sm sm:hidden"
          onClick={() => setIsCollapsed(true)}
          aria-hidden="true"
        />
      )}

      {/* Panel overlay */}
      <div
        className={cn(
          'fixed z-40',
          'inset-0 sm:inset-auto sm:right-2 sm:top-1/2 sm:-translate-y-1/2',
          'flex w-full flex-col sm:h-[55vh] sm:w-[420px]',
          'border-border bg-card/95 backdrop-blur-md shadow-xl sm:rounded-lg sm:border',
          'transition-transform duration-200 ease-out',
          isCollapsed ? 'translate-x-full' : 'translate-x-0'
        )}
      >
        {/* Header */}
        <div className="flex items-center justify-between border-b border-border px-3 py-2">
          <div className="flex items-center gap-2">
            <StickyNote className="h-4 w-4 text-muted-foreground" />
            <span className="text-sm font-medium text-foreground">Scratchpad</span>
            <span className="text-xs text-muted-foreground">Ctrl+/</span>
          </div>
          <div className="flex items-center gap-1">
            <button
              onClick={() => setShowPreview(!showPreview)}
              className="rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
              title={showPreview ? 'Edit' : 'Preview'}
            >
              {showPreview ? <Pencil className="h-3.5 w-3.5" /> : <Eye className="h-3.5 w-3.5" />}
            </button>
            <button
              onClick={() => setIsCollapsed(true)}
              className="rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
              title="Close scratchpad"
              aria-label="Close scratchpad"
            >
              <X className="h-4 w-4" />
            </button>
          </div>
        </div>

        {/* Content */}
        <div className="flex-1 overflow-y-auto p-3">
          {showPreview ? (
            <div className="min-h-[100px]">
              {content.trim() ? (
                <MarkdownContent content={content} className="text-sm" />
              ) : (
                <p className="text-sm italic text-muted-foreground">Nothing to preview</p>
              )}
            </div>
          ) : (
            <textarea
              value={content}
              onChange={(e) => handleChange(e.target.value)}
              onBlur={handleBlur}
              placeholder={"Capture IPs, error codes, server names, user info...\n\nSupports markdown formatting."}
              className={cn(
                'h-full min-h-[200px] w-full resize-none rounded-md border-0 bg-transparent p-0 text-sm',
                'text-foreground placeholder:text-muted-foreground',
                'focus:outline-none focus:ring-0'
              )}
            />
          )}
        </div>

        {/* Save Indicator */}
        <div className="border-t border-border px-3 py-1.5">
          <div className="flex items-center gap-1.5 text-xs">
            {saveStatus === 'unsaved' && (
              <span className="text-muted-foreground">Unsaved changes</span>
            )}
            {saveStatus === 'saving' && (
              <>
                <Loader2 className="h-3 w-3 animate-spin text-muted-foreground" />
                <span className="text-muted-foreground">Saving...</span>
              </>
            )}
            {saveStatus === 'saved' && (
              <span className="text-emerald-400">Saved</span>
            )}
            {saveStatus === 'error' && (
              <span className="text-red-400">Save failed</span>
            )}
            {saveStatus === 'idle' && (
              <span className="text-muted-foreground">Markdown supported</span>
            )}
          </div>
        </div>
      </div>
    </>
  )
}
