import fs from 'fs'
import path from 'path'

type Verse = { verseNum: number; text: string }
type Chapter = { chapterNum: number; verses: Verse[] }
type Book = { name: string; chapters: Chapter[] }

// Mapping to determine testament + order, reused to split OT / NT
const BOOK_MAPPINGS: Record<string, { testament: 'Old Testament' | 'New Testament'; orderNum: number }> = {
  // Old Testament
  'Geneza': { testament: 'Old Testament', orderNum: 1 },
  'Exodul': { testament: 'Old Testament', orderNum: 2 },
  'Leviticul': { testament: 'Old Testament', orderNum: 3 },
  'Numerii': { testament: 'Old Testament', orderNum: 4 },
  'Numeri': { testament: 'Old Testament', orderNum: 4 },
  'Deuteronomul': { testament: 'Old Testament', orderNum: 5 },
  'Deuteronom': { testament: 'Old Testament', orderNum: 5 },
  'Iosua': { testament: 'Old Testament', orderNum: 6 },
  'Judecătorii': { testament: 'Old Testament', orderNum: 7 },
  'Judecători': { testament: 'Old Testament', orderNum: 7 },
  'Rut': { testament: 'Old Testament', orderNum: 8 },
  '1 Samuel': { testament: 'Old Testament', orderNum: 9 },
  '2 Samuel': { testament: 'Old Testament', orderNum: 10 },
  '1 Împăraţi': { testament: 'Old Testament', orderNum: 11 },
  '2 Împăraţi': { testament: 'Old Testament', orderNum: 12 },
  '1 Imparati': { testament: 'Old Testament', orderNum: 11 },
  '2 Imparati': { testament: 'Old Testament', orderNum: 12 },
  '1 Cronici': { testament: 'Old Testament', orderNum: 13 },
  '2 Cronici': { testament: 'Old Testament', orderNum: 14 },
  'Ezra': { testament: 'Old Testament', orderNum: 15 },
  'Neemia': { testament: 'Old Testament', orderNum: 16 },
  'Estera': { testament: 'Old Testament', orderNum: 17 },
  'Iov': { testament: 'Old Testament', orderNum: 18 },
  'Psalmii': { testament: 'Old Testament', orderNum: 19 },
  'Proverbele': { testament: 'Old Testament', orderNum: 20 },
  'Proverbe': { testament: 'Old Testament', orderNum: 20 },
  'Eclesiastul': { testament: 'Old Testament', orderNum: 21 },
  'Cântarea Cântărilor': { testament: 'Old Testament', orderNum: 22 },
  'Isaia': { testament: 'Old Testament', orderNum: 23 },
  'Ieremia': { testament: 'Old Testament', orderNum: 24 },
  'Plângerile': { testament: 'Old Testament', orderNum: 25 },
  'Ezechiel': { testament: 'Old Testament', orderNum: 26 },
  'Daniel': { testament: 'Old Testament', orderNum: 27 },
  'Osea': { testament: 'Old Testament', orderNum: 28 },
  'Ioel': { testament: 'Old Testament', orderNum: 29 },
  'Amos': { testament: 'Old Testament', orderNum: 30 },
  'Obadia': { testament: 'Old Testament', orderNum: 31 },
  'Iona': { testament: 'Old Testament', orderNum: 32 },
  'Mica': { testament: 'Old Testament', orderNum: 33 },
  'Naum': { testament: 'Old Testament', orderNum: 34 },
  'Habacuc': { testament: 'Old Testament', orderNum: 35 },
  'Ţefania': { testament: 'Old Testament', orderNum: 36 },
  'Țefania': { testament: 'Old Testament', orderNum: 36 },
  'Hagai': { testament: 'Old Testament', orderNum: 37 },
  'Zaharia': { testament: 'Old Testament', orderNum: 38 },
  'Maleahi': { testament: 'Old Testament', orderNum: 39 },
  // New Testament
  'Matei': { testament: 'New Testament', orderNum: 40 },
  'Marcu': { testament: 'New Testament', orderNum: 41 },
  'Luca': { testament: 'New Testament', orderNum: 42 },
  'Ioan': { testament: 'New Testament', orderNum: 43 },
  'Faptele Apostolilor': { testament: 'New Testament', orderNum: 44 },
  'Romani': { testament: 'New Testament', orderNum: 45 },
  '1 Corinteni': { testament: 'New Testament', orderNum: 46 },
  '2 Corinteni': { testament: 'New Testament', orderNum: 47 },
  'Galateni': { testament: 'New Testament', orderNum: 48 },
  'Efeseni': { testament: 'New Testament', orderNum: 49 },
  'Filipeni': { testament: 'New Testament', orderNum: 50 },
  'Coloseni': { testament: 'New Testament', orderNum: 51 },
  '1 Tesaloniceni': { testament: 'New Testament', orderNum: 52 },
  '2 Tesaloniceni': { testament: 'New Testament', orderNum: 53 },
  '1 Timotei': { testament: 'New Testament', orderNum: 54 },
  '2 Timotei': { testament: 'New Testament', orderNum: 55 },
  'Tit': { testament: 'New Testament', orderNum: 56 },
  'Titus': { testament: 'New Testament', orderNum: 56 },
  'Filimon': { testament: 'New Testament', orderNum: 57 },
  'Evrei': { testament: 'New Testament', orderNum: 58 },
  'Iacov': { testament: 'New Testament', orderNum: 59 },
  '1 Petru': { testament: 'New Testament', orderNum: 60 },
  '2 Petru': { testament: 'New Testament', orderNum: 61 },
  '1 Ioan': { testament: 'New Testament', orderNum: 62 },
  '2 Ioan': { testament: 'New Testament', orderNum: 63 },
  '3 Ioan': { testament: 'New Testament', orderNum: 64 },
  'Iuda': { testament: 'New Testament', orderNum: 65 },
  'Apocalipsa': { testament: 'New Testament', orderNum: 66 },
  'Revelaţia': { testament: 'New Testament', orderNum: 66 },
  'Revelația': { testament: 'New Testament', orderNum: 66 }
}

function parseRomanianBibleMarkdown(md: string): Book[] {
  const lines = md.split(/\r?\n/)

  const books: Book[] = []
  let currentBook: Book | null = null
  let currentChapter: Chapter | null = null

  // The MD file uses a pattern of a centered title line with ellipses like: … GENEZA …
  // We detect those as book delimiters.
  const isBookHeader = (line: string) => /^…\s*.+\s*…$/.test(line.trim())

  const normalizeBookName = (raw: string) => {
    // Strip leading/trailing ellipsis and extra spaces
    const name = raw.replace(/^…\s*|\s*…$/g, '').trim()
    // Try to map known variants to our mapping keys
    // The MD sometimes uses slightly different diacritics or spacing; leave as-is if not found
    return name
  }

  for (let i = 0; i < lines.length; i++) {
    const raw = lines[i].trim()
    if (!raw) continue

    if (isBookHeader(raw)) {
      // Save previous chapter and book if they have content
      if (currentChapter && currentChapter.verses.length > 0 && currentBook) {
        currentBook.chapters.push(currentChapter)
      }
      if (currentBook && currentBook.chapters.length > 0) {
        books.push(currentBook)
      }

      const bookName = normalizeBookName(raw)
      currentBook = { name: bookName, chapters: [] }
      currentChapter = null
      continue
    }

    // Detect chapter markers like: Capitolul X (case-insensitive, diacritics tolerant)
    const chapterMatch = raw.match(/^[cC][aA][pP][iI][tT][oO][lL][uU][lL]\s+(\d+)$/)
    if (chapterMatch && currentBook) {
      // Save previous chapter if exists
      if (currentChapter && currentChapter.verses.length > 0) {
        currentBook.chapters.push(currentChapter)
      }
      currentChapter = { chapterNum: parseInt(chapterMatch[1], 10), verses: [] }
      continue
    }

    // Detect verses that begin with a number: "1 text..."
    const verseMatch = raw.match(/^(\d+)\s+(.+)$/)
    if (verseMatch && currentChapter) {
      const verseNum = parseInt(verseMatch[1], 10)
      let verseText = verseMatch[2].trim()

      // Remove paragraph markers if present
      verseText = verseText.replace(/^¶\s*/, '')

      // Merge continuation lines that don't start with a verse or chapter/book markers
      let j = i + 1
      while (j < lines.length) {
        const lookahead = lines[j].trim()
        if (!lookahead) break
        if (/^(\d+)\s+/.test(lookahead)) break // next verse
        if (isBookHeader(lookahead)) break // next book
        if (/^[cC][aA][pP][iI][tT][oO][lL][uU][lL]\s+\d+$/.test(lookahead)) break // next chapter
        verseText += ' ' + lookahead
        j++
      }
      i = j - 1

      verseText = verseText.replace(/\s+/g, ' ').trim()
      if (verseText) {
        currentChapter.verses.push({ verseNum, text: verseText })
      }
    }
  }

  // Save last chapter and book
  if (currentChapter && currentChapter.verses.length > 0 && currentBook) {
    currentBook.chapters.push(currentChapter)
  }
  if (currentBook && currentBook.chapters.length > 0) {
    books.push(currentBook)
  }

  return books
}

function writeTestamentJson(books: Book[], outPath: string, testament: 'Old Testament' | 'New Testament') {
  const data = {
    testament,
    books: books.map(b => ({ name: b.name, chapters: b.chapters }))
  }
  fs.mkdirSync(path.dirname(outPath), { recursive: true })
  fs.writeFileSync(outPath, JSON.stringify(data, null, 2), 'utf-8')
  console.log(`Wrote ${outPath} with ${books.length} books.`)
}

async function main() {
  const mdPath = path.join(process.cwd(), 'bibles', 'Biblia-Fidela-limba-romana.md')
  if (!fs.existsSync(mdPath)) {
    throw new Error(`Markdown not found at ${mdPath}`)
  }

  console.log(`Reading: ${mdPath}`)
  const md = fs.readFileSync(mdPath, 'utf-8')
  const parsedBooks = parseRomanianBibleMarkdown(md)
  console.log(`Parsed ${parsedBooks.length} books from Markdown`)

  // Filter and sort into OT and NT using the mapping
  const otBooks: Book[] = []
  const ntBooks: Book[] = []
  for (const b of parsedBooks) {
    const meta = BOOK_MAPPINGS[b.name]
    if (!meta) {
      console.warn(`Skipping unknown book in mapping: ${b.name}`)
      continue
    }
    if (meta.testament === 'Old Testament') otBooks.push(b)
    else ntBooks.push(b)
  }

  // Sort by canonical order
  otBooks.sort((a, b) => BOOK_MAPPINGS[a.name].orderNum - BOOK_MAPPINGS[b.name].orderNum)
  ntBooks.sort((a, b) => BOOK_MAPPINGS[a.name].orderNum - BOOK_MAPPINGS[b.name].orderNum)

  // Write JSON outputs compatible with import-romanian-versioned.ts
  const otOut = path.join(process.cwd(), 'data', 'old_testament.json')
  const ntOut = path.join(process.cwd(), 'data', 'new_testament.json')
  writeTestamentJson(otBooks, otOut, 'Old Testament')
  writeTestamentJson(ntBooks, ntOut, 'New Testament')
}

main().catch(err => {
  console.error('Conversion failed:', err)
  process.exit(1)
})
