import { useState } from 'react'
import { nostrAuthService } from '@/lib/nostrAuth'
import { RecoveryStep, ImportStep, ChooseStep } from './CreateAccountModalSteps'

interface CreateAccountModalProps {
  onSuccess: (npub: string) => void
  onClose: () => void
  initialStep?: Step
}

type Step = 'choose' | 'import' | 'recovery'

async function createAccountWithKey(key?: string): Promise<{ recoveryPhrase: string[]; npub: string; publicKey: string }> {
  return nostrAuthService.createAccount(key)
}

interface HandleAccountCreationParams {
  key: string | undefined
  setLoading: (loading: boolean) => void
  setError: (error: string | null) => void
  setRecoveryPhrase: (phrase: string[]) => void
  setNpub: (npub: string) => void
  setStep: (step: Step) => void
  errorMessage: string
}

async function handleAccountCreation(params: HandleAccountCreationParams): Promise<void> {
  if (params.key !== undefined && !params.key.trim()) {
    params.setError('Please enter a private key')
    return
  }

  params.setLoading(true)
  params.setError(null)
  try {
    const result = await createAccountWithKey(params.key?.trim())
    params.setRecoveryPhrase(result.recoveryPhrase)
    params.setNpub(result.npub)
    params.setStep('recovery')
  } catch (e) {
    params.setError(e instanceof Error ? e.message : params.errorMessage)
  } finally {
    params.setLoading(false)
  }
}

interface AccountCreationState {
  step: Step
  setStep: (step: Step) => void
  importKey: string
  setImportKey: (key: string) => void
  loading: boolean
  error: string | null
  setError: (error: string | null) => void
  recoveryPhrase: string[]
  npub: string
  handleGenerate: () => Promise<void>
  handleImport: () => Promise<void>
}

function useAccountCreation(initialStep: Step = 'choose'): AccountCreationState {
  const [step, setStep] = useState<Step>(initialStep)
  const [importKey, setImportKey] = useState('')
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [recoveryPhrase, setRecoveryPhrase] = useState<string[]>([])
  const [npub, setNpub] = useState('')

  const handleGenerate = (): Promise<void> =>
    handleAccountCreation({
      key: undefined,
      setLoading,
      setError,
      setRecoveryPhrase,
      setNpub,
      setStep,
      errorMessage: 'Failed to create account',
    })

  const handleImport = (): Promise<void> =>
    handleAccountCreation({
      key: importKey,
      setLoading,
      setError,
      setRecoveryPhrase,
      setNpub,
      setStep,
      errorMessage: 'Failed to import key',
    })

  return { step, setStep, importKey, setImportKey, loading, error, setError, recoveryPhrase, npub, handleGenerate, handleImport }
}

function handleImportBack(setStep: (step: Step) => void, setError: (error: string | null) => void, setImportKey: (key: string) => void): void {
  setStep('choose')
  setError(null)
  setImportKey('')
}

interface RenderStepParams {
  step: Step
  recoveryPhrase: string[]
  npub: string
  importKey: string
  setImportKey: (key: string) => void
  loading: boolean
  error: string | null
  handleContinue: () => void
  handleImport: () => void
  setStep: (step: Step) => void
  setError: (error: string | null) => void
  handleGenerate: () => void
  onClose: () => void
}

function renderStep(params: RenderStepParams): React.ReactElement {
  if (params.step === 'recovery') {
    return <RecoveryStep recoveryPhrase={params.recoveryPhrase} npub={params.npub} onContinue={params.handleContinue} />
  }

  if (params.step === 'import') {
    return (
      <ImportStep
        importKey={params.importKey}
        setImportKey={params.setImportKey}
        loading={params.loading}
        error={params.error}
        onImport={params.handleImport}
        onBack={() => handleImportBack(params.setStep, params.setError, params.setImportKey)}
      />
    )
  }

  return (
    <ChooseStep
      loading={params.loading}
      error={params.error}
      onGenerate={params.handleGenerate}
      onImport={() => params.setStep('import')}
      onClose={params.onClose}
    />
  )
}

export function CreateAccountModal({ onSuccess, onClose, initialStep = 'choose' }: CreateAccountModalProps): React.ReactElement {
  const {
    step,
    setStep,
    importKey,
    setImportKey,
    loading,
    error,
    setError,
    recoveryPhrase,
    npub,
    handleGenerate,
    handleImport,
  } = useAccountCreation(initialStep)

  const handleContinue = (): void => {
    onSuccess(npub)
    onClose()
  }

  return renderStep({
    step,
    recoveryPhrase,
    npub,
    importKey,
    setImportKey,
    loading,
    error,
    handleContinue,
    handleImport: () => {
      void handleImport()
    },
    setStep,
    setError,
    handleGenerate: () => {
      void handleGenerate()
    },
    onClose,
  })
}
