import type {
  VocabularyEntry, Session, StoredDocument, OcrPrompts, IpaMode, SyllableMode,
} from './types'
import { getApiBase } from './constants'

/**
 * Start a new session: create on server, upload document, process first page or PDF.
 */
export async function startSessionFlow(params: {
  sessionName: string
  selectedDocumentId: string | null
  directFile: File | null
  selectedMobileFile: { dataUrl: string; type: string; name: string } | null
  storedDocuments: StoredDocument[]
  ocrPrompts: OcrPrompts
  startActivity: (...args: any[]) => void
  setSession: (s: Session | null | ((prev: Session | null) => Session | null)) => void
  setWorksheetTitle: (t: string) => void
  setExtractionStatus: (s: string) => void
  setPdfPageCount: (n: number) => void
  setSelectedPages: (p: number[]) => void
  setPagesThumbnails: (t: string[]) => void
  setIsLoadingThumbnails: (l: boolean) => void
  setVocabulary: (v: VocabularyEntry[]) => void
  setActiveTab: (t: 'upload' | 'pages' | 'vocabulary' | 'spreadsheet' | 'worksheet' | 'export' | 'settings') => void
  setError: (e: string | null) => void
}): Promise<Session | null> {
  const {
    sessionName, selectedDocumentId, directFile, selectedMobileFile, storedDocuments,
    ocrPrompts, startActivity, setSession, setWorksheetTitle, setExtractionStatus,
    setPdfPageCount, setSelectedPages, setPagesThumbnails, setIsLoadingThumbnails,
    setVocabulary, setActiveTab, setError,
  } = params

  setError(null)
  setExtractionStatus('Session wird erstellt...')

  const API_BASE = getApiBase()

  const sessionRes = await fetch(`${API_BASE}/api/v1/vocab/sessions`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ name: sessionName, ocr_prompts: ocrPrompts }),
  })

  if (!sessionRes.ok) throw new Error('Session konnte nicht erstellt werden')

  const sessionData = await sessionRes.json()
  setSession(sessionData)
  setWorksheetTitle(sessionName)
  startActivity('vocab_extraction', { description: sessionName })

  let file: File
  let isPdf = false

  if (directFile) {
    file = directFile
    isPdf = directFile.type === 'application/pdf'
  } else if (selectedMobileFile) {
    isPdf = selectedMobileFile.type === 'application/pdf'
    const base64Data = selectedMobileFile.dataUrl.split(',')[1]
    const byteCharacters = atob(base64Data)
    const byteNumbers = new Array(byteCharacters.length)
    for (let i = 0; i < byteCharacters.length; i++) byteNumbers[i] = byteCharacters.charCodeAt(i)
    const blob = new Blob([new Uint8Array(byteNumbers)], { type: selectedMobileFile.type })
    file = new File([blob], selectedMobileFile.name, { type: selectedMobileFile.type })
  } else {
    const selectedDoc = storedDocuments.find(d => d.id === selectedDocumentId)
    if (!selectedDoc || !selectedDoc.url) throw new Error('Das ausgewaehlte Dokument ist nicht verfuegbar.')
    isPdf = selectedDoc.type === 'application/pdf'
    const base64Data = selectedDoc.url.split(',')[1]
    const byteCharacters = atob(base64Data)
    const byteNumbers = new Array(byteCharacters.length)
    for (let i = 0; i < byteCharacters.length; i++) byteNumbers[i] = byteCharacters.charCodeAt(i)
    const blob = new Blob([new Uint8Array(byteNumbers)], { type: selectedDoc.type })
    file = new File([blob], selectedDoc.name, { type: selectedDoc.type })
  }

  if (isPdf) {
    setExtractionStatus('PDF wird hochgeladen...')
    const formData = new FormData()
    formData.append('file', file)
    const pdfInfoRes = await fetch(`${API_BASE}/api/v1/vocab/sessions/${sessionData.id}/upload-pdf-info`, {
      method: 'POST', body: formData,
    })
    if (!pdfInfoRes.ok) throw new Error('PDF konnte nicht verarbeitet werden')
    const pdfInfo = await pdfInfoRes.json()
    setPdfPageCount(pdfInfo.page_count)
    setSelectedPages(Array.from({ length: pdfInfo.page_count }, (_, i) => i))
    setActiveTab('pages')
    setExtractionStatus(`${pdfInfo.page_count} Seiten erkannt. Vorschau wird geladen...`)
    setIsLoadingThumbnails(true)
    const thumbnails: string[] = []
    for (let i = 0; i < pdfInfo.page_count; i++) {
      try {
        const thumbRes = await fetch(`${API_BASE}/api/v1/vocab/sessions/${sessionData.id}/pdf-thumbnail/${i}?hires=true`)
        if (thumbRes.ok) { const blob = await thumbRes.blob(); thumbnails.push(URL.createObjectURL(blob)) }
      } catch (e) { console.error(`Failed to load thumbnail for page ${i}`) }
    }
    setPagesThumbnails(thumbnails)
    setIsLoadingThumbnails(false)
    setExtractionStatus(`${pdfInfo.page_count} Seiten bereit. Waehlen Sie die zu verarbeitenden Seiten.`)
  } else {
    setExtractionStatus('KI analysiert das Bild... (kann 30-60 Sekunden dauern)')
    const formData = new FormData()
    formData.append('file', file)
    const uploadRes = await fetch(`${API_BASE}/api/v1/vocab/sessions/${sessionData.id}/upload`, {
      method: 'POST', body: formData,
    })
    if (!uploadRes.ok) throw new Error('Bild konnte nicht verarbeitet werden')
    const uploadData = await uploadRes.json()
    setSession(prev => prev ? { ...prev, status: 'extracted', vocabulary_count: uploadData.vocabulary_count } : null)
    const vocabRes = await fetch(`${API_BASE}/api/v1/vocab/sessions/${sessionData.id}/vocabulary`)
    if (vocabRes.ok) {
      const vocabData = await vocabRes.json()
      setVocabulary(vocabData.vocabulary || [])
      setExtractionStatus(`${vocabData.vocabulary?.length || 0} Vokabeln gefunden!`)
    }
    await new Promise(r => setTimeout(r, 1000))
    setActiveTab('vocabulary')
  }

  return sessionData
}

/**
 * Resume an existing session from the API.
 */
export async function resumeSessionFlow(
  existingSession: Session,
  setSession: (s: Session) => void,
  setWorksheetTitle: (t: string) => void,
  setVocabulary: (v: VocabularyEntry[]) => void,
  setActiveTab: (t: 'upload' | 'pages' | 'vocabulary' | 'spreadsheet' | 'worksheet' | 'export' | 'settings') => void,
  setExtractionStatus: (s: string) => void,
): Promise<void> {
  const API_BASE = getApiBase()
  const sessionRes = await fetch(`${API_BASE}/api/v1/vocab/sessions/${existingSession.id}`)
  if (!sessionRes.ok) throw new Error('Session nicht gefunden')
  const sessionData = await sessionRes.json()
  setSession(sessionData)
  setWorksheetTitle(sessionData.name)

  if (sessionData.status === 'extracted' || sessionData.status === 'completed') {
    const vocabRes = await fetch(`${API_BASE}/api/v1/vocab/sessions/${existingSession.id}/vocabulary`)
    if (vocabRes.ok) { const vd = await vocabRes.json(); setVocabulary(vd.vocabulary || []) }
    setActiveTab('vocabulary')
    setExtractionStatus('')
  } else if (sessionData.status === 'pending') {
    setActiveTab('upload')
    setExtractionStatus('Diese Session hat noch keine Vokabeln. Bitte laden Sie ein Dokument hoch.')
  } else {
    setActiveTab('vocabulary')
    setExtractionStatus('')
  }
}
