import { useState, useRef, useEffect } from 'react'
import { nostrAuthService } from '@/lib/nostrAuth'
import { getWordSuggestions } from '@/lib/keyManagementBIP39'

interface UnlockAccountModalProps {
  onSuccess: () => void
  onClose: () => void
}

function WordInputWithAutocomplete({
  index,
  value,
  onChange,
  onFocus,
  onBlur,
}: {
  index: number
  value: string
  onChange: (value: string) => void
  onFocus: () => void
  onBlur: () => void
}): React.ReactElement {
  const [suggestions, setSuggestions] = useState<string[]>([])
  const [showSuggestions, setShowSuggestions] = useState(false)
  const [selectedIndex, setSelectedIndex] = useState(-1)
  const inputRef = useRef<HTMLInputElement>(null)
  const suggestionsRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (value.length > 0) {
      const newSuggestions = getWordSuggestions(value, 5)
      setSuggestions(newSuggestions)
      setShowSuggestions(newSuggestions.length > 0)
      setSelectedIndex(-1)
    } else {
      setSuggestions([])
      setShowSuggestions(false)
    }
  }, [value])

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
    const newValue = event.target.value.trim().toLowerCase()
    onChange(newValue)
  }

  const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>): void => {
    if (event.key === 'ArrowDown') {
      event.preventDefault()
      setSelectedIndex((prev) => (prev < suggestions.length - 1 ? prev + 1 : prev))
    } else if (event.key === 'ArrowUp') {
      event.preventDefault()
      setSelectedIndex((prev) => (prev > 0 ? prev - 1 : -1))
    } else if (event.key === 'Enter' && selectedIndex >= 0 && suggestions[selectedIndex]) {
      event.preventDefault()
      onChange(suggestions[selectedIndex] ?? '')
      setShowSuggestions(false)
      inputRef.current?.blur()
    } else if (event.key === 'Escape') {
      setShowSuggestions(false)
      inputRef.current?.blur()
    }
  }

  const handleSuggestionClick = (suggestion: string): void => {
    onChange(suggestion)
    setShowSuggestions(false)
    inputRef.current?.blur()
  }

  return (
    <div className="relative">
      <label htmlFor={`word-${index}`} className="block text-sm font-medium text-gray-700 mb-2">
        Mot {index + 1}
      </label>
      <input
        ref={inputRef}
        id={`word-${index}`}
        type="text"
        value={value}
        onChange={handleChange}
        onKeyDown={handleKeyDown}
        onFocus={onFocus}
        onBlur={() => {
          // Delay to allow click on suggestion
          setTimeout(() => {
            setShowSuggestions(false)
            onBlur()
          }, 200)
        }}
        className="w-full px-3 py-2 border border-gray-300 rounded-lg font-mono text-lg text-center"
        autoComplete="off"
        autoCapitalize="off"
        autoCorrect="off"
        spellCheck="false"
      />
      {showSuggestions && suggestions.length > 0 && (
        <div
          ref={suggestionsRef}
          className="absolute z-10 w-full mt-1 bg-white border border-gray-300 rounded-lg shadow-lg max-h-40 overflow-y-auto"
        >
          {suggestions.map((suggestion, idx) => (
            <button
              key={suggestion}
              type="button"
              onClick={() => handleSuggestionClick(suggestion)}
              className={`w-full text-left px-3 py-2 hover:bg-gray-100 ${
                idx === selectedIndex ? 'bg-gray-100' : ''
              }`}
            >
              {suggestion}
            </button>
          ))}
        </div>
      )}
    </div>
  )
}

function WordInputs({
  words,
  onWordChange,
}: {
  words: string[]
  onWordChange: (index: number, value: string) => void
}): React.ReactElement {
  const [, setFocusedIndex] = useState<number | null>(null)

  return (
    <div className="grid grid-cols-2 gap-4">
      {words.map((word, index) => (
        <WordInputWithAutocomplete
          key={index}
          index={index}
          value={word}
          onChange={(value) => onWordChange(index, value)}
          onFocus={() => setFocusedIndex(index)}
          onBlur={() => setFocusedIndex(null)}
        />
      ))}
    </div>
  )
}

function useUnlockAccount(words: string[], setWords: (words: string[]) => void, setError: (error: string | null) => void): {
  handleWordChange: (index: number, value: string) => void
  handlePaste: () => Promise<void>
} {
  const handleWordChange = (index: number, value: string): void => {
    const newWords = [...words]
    newWords[index] = value.trim().toLowerCase()
    setWords(newWords)
    setError(null)
  }

  const handlePaste = async (): Promise<void> => {
    try {
      const text = await navigator.clipboard.readText()
      const pastedWords = text.trim().split(/\s+/).slice(0, 4)
      if (pastedWords.length === 4) {
        setWords(pastedWords.map((w) => w.toLowerCase()))
        setError(null)
      }
    } catch {
      // Ignore clipboard errors
    }
  }

  return { handleWordChange, handlePaste }
}

function UnlockAccountButtons({
  loading,
  words,
  onUnlock,
  onClose,
}: {
  loading: boolean
  words: string[]
  onUnlock: () => void
  onClose: () => void
}): React.ReactElement {
  return (
    <div className="flex gap-4">
      <button
        onClick={onClose}
        className="flex-1 py-2 px-4 bg-gray-200 hover:bg-gray-300 rounded-lg font-medium transition-colors"
      >
        Annuler
      </button>
      <button
        onClick={() => {
          void onUnlock()
        }}
        disabled={loading || words.some((word) => !word)}
        className="flex-1 py-2 px-4 bg-neon-cyan/20 hover:bg-neon-cyan/30 text-neon-cyan rounded-lg font-medium transition-all border border-neon-cyan/50 hover:shadow-glow-cyan disabled:opacity-50"
      >
        {loading ? 'Déverrouillage...' : 'Déverrouiller'}
      </button>
    </div>
  )
}

function UnlockAccountForm({
  words,
  handleWordChange,
  handlePaste,
}: {
  words: string[]
  handleWordChange: (index: number, value: string) => void
  handlePaste: () => void
}): React.ReactElement {
  return (
    <div className="mb-4">
      <WordInputs words={words} onWordChange={handleWordChange} />
      <button
        type="button"
        onClick={() => {
          void handlePaste()
        }}
        className="mt-2 text-sm text-gray-600 hover:text-gray-800 underline"
      >
        Coller depuis le presse-papiers
      </button>
    </div>
  )
}

export function UnlockAccountModal({ onSuccess, onClose }: UnlockAccountModalProps): React.ReactElement {
  const [words, setWords] = useState(['', '', '', ''])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const { handleWordChange, handlePaste } = useUnlockAccount(words, setWords, setError)

  const handleUnlock = async (): Promise<void> => {
    if (words.some((word) => !word)) {
      setError('Veuillez remplir tous les mots-clés')
      return
    }

    setLoading(true)
    setError(null)
    try {
      await nostrAuthService.unlockAccount(words)
      onSuccess()
      onClose()
    } catch (unlockError) {
      setError(unlockError instanceof Error ? unlockError.message : 'Échec du déverrouillage. Vérifiez vos mots-clés.')
    } finally {
      setLoading(false)
    }
  }

  return (
    <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
      <div className="bg-white rounded-lg p-6 max-w-md w-full mx-4">
        <h2 className="text-2xl font-bold mb-4">Déverrouiller votre compte</h2>
        <p className="text-gray-600 mb-6">
          Entrez vos 4 mots-clés de récupération (dictionnaire BIP39) pour déverrouiller votre compte.
          Ces mots déchiffrent la clé de chiffrement (KEK) stockée dans l&apos;API Credentials, qui déchiffre ensuite votre clé privée.
        </p>
        <UnlockAccountForm words={words} handleWordChange={handleWordChange} handlePaste={handlePaste} />
        {error && <p className="text-sm text-red-600 mb-4">{error}</p>}
        <UnlockAccountButtons loading={loading} words={words} onUnlock={handleUnlock} onClose={onClose} />
      </div>
    </div>
  )
}
