import { describe, it, expect, beforeEach, beforeAll } from "vitest"
import { prisma } from "@/lib/prisma"
import { parseHSKJson } from "@/lib/import/hsk-json-parser"
import { parseCSV } from "@/lib/import/csv-parser"

/**
 * Integration tests for admin import functionality
 * These tests focus on the database operations and data transformation
 */

describe("Admin Import Integration Tests", () => {
  let englishLanguage: any

  beforeAll(async () => {
    // Create English language
    englishLanguage = await prisma.language.upsert({
      where: { code: "en" },
      create: {
        code: "en",
        name: "English",
        nativeName: "English",
        isActive: true,
      },
      update: {},
    })
  })

  beforeEach(async () => {
    // Clear hanzi-related tables
    await prisma.sessionReview.deleteMany()
    await prisma.learningSession.deleteMany()
    await prisma.collectionItem.deleteMany()
    await prisma.userHanziProgress.deleteMany()
    await prisma.hanziClassifier.deleteMany()
    await prisma.hanziMeaning.deleteMany()
    await prisma.hanziTranscription.deleteMany()
    await prisma.hanziForm.deleteMany()
    await prisma.hanziPOS.deleteMany()
    await prisma.hanziHSKLevel.deleteMany()
    await prisma.hanzi.deleteMany()
  })

  // Helper function to import parsed hanzi data
  async function saveParsedHanzi(parsedData: any[]) {
    // Ensure English language exists
    const engLanguage = await prisma.language.upsert({
      where: { code: "en" },
      create: {
        code: "en",
        name: "English",
        nativeName: "English",
        isActive: true,
      },
      update: {},
    })

    for (const hanzi of parsedData) {
      const hanziRecord = await prisma.hanzi.upsert({
        where: { simplified: hanzi.simplified },
        update: {
          radical: hanzi.radical,
          frequency: hanzi.frequency,
        },
        create: {
          simplified: hanzi.simplified,
          radical: hanzi.radical,
          frequency: hanzi.frequency,
        },
      })

      // Delete existing related data
      await prisma.hanziForm.deleteMany({
        where: { hanziId: hanziRecord.id },
      })
      await prisma.hanziHSKLevel.deleteMany({
        where: { hanziId: hanziRecord.id },
      })
      await prisma.hanziPOS.deleteMany({
        where: { hanziId: hanziRecord.id },
      })

      // Create HSK levels
      if (hanzi.hskLevels.length > 0) {
        await prisma.hanziHSKLevel.createMany({
          data: hanzi.hskLevels.map((level: string) => ({
            hanziId: hanziRecord.id,
            level,
          })),
        })
      }

      // Create parts of speech
      if (hanzi.partsOfSpeech.length > 0) {
        await prisma.hanziPOS.createMany({
          data: hanzi.partsOfSpeech.map((pos: string) => ({
            hanziId: hanziRecord.id,
            pos,
          })),
        })
      }

      // Create forms
      for (const form of hanzi.forms) {
        const formRecord = await prisma.hanziForm.create({
          data: {
            hanziId: hanziRecord.id,
            traditional: form.traditional,
            isDefault: form.isDefault,
          },
        })

        // Create transcriptions
        if (form.transcriptions.length > 0) {
          await prisma.hanziTranscription.createMany({
            data: form.transcriptions.map((trans: any) => ({
              formId: formRecord.id,
              type: trans.type,
              value: trans.value,
            })),
          })
        }

        // Create meanings
        if (form.meanings.length > 0) {
          await prisma.hanziMeaning.createMany({
            data: form.meanings.map((meaning: any) => ({
              formId: formRecord.id,
              languageId: engLanguage.id,
              meaning: meaning.meaning,
              orderIndex: meaning.orderIndex,
            })),
          })
        }

        // Create classifiers
        if (form.classifiers.length > 0) {
          await prisma.hanziClassifier.createMany({
            data: form.classifiers.map((classifier: string) => ({
              formId: formRecord.id,
              classifier,
            })),
          })
        }
      }
    }
  }

  describe("Import JSON to Database", () => {
    it("should parse and save JSON data to database", async () => {
      const jsonData = JSON.stringify([
        {
          simplified: "好",
          radical: "女",
          level: ["new-1"],
          frequency: 123,
          pos: ["adj"],
          forms: [
            {
              traditional: "好",
              transcriptions: {
                pinyin: "hǎo",
                numeric: "hao3",
              },
              meanings: ["good"],
              classifiers: ["个"],
            },
          ],
        },
      ])

      const { result, data } = parseHSKJson(jsonData)

      expect(result.success).toBe(true)
      expect(result.imported).toBe(1)
      expect(result.failed).toBe(0)

      // Save to database
      await saveParsedHanzi(data)

      // Verify data was saved
      const hanzi = await prisma.hanzi.findUnique({
        where: { simplified: "好" },
        include: {
          forms: {
            include: {
              transcriptions: true,
              meanings: true,
              classifiers: true,
            },
          },
          hskLevels: true,
          partsOfSpeech: true,
        },
      })

      expect(hanzi).toBeDefined()
      expect(hanzi?.radical).toBe("女")
      expect(hanzi?.frequency).toBe(123)
      expect(hanzi?.forms).toHaveLength(1)
      expect(hanzi?.forms[0].traditional).toBe("好")
      expect(hanzi?.forms[0].transcriptions).toHaveLength(2)
      expect(hanzi?.forms[0].meanings).toHaveLength(1)
      expect(hanzi?.forms[0].classifiers).toHaveLength(1)
      expect(hanzi?.hskLevels).toHaveLength(1)
      expect(hanzi?.partsOfSpeech).toHaveLength(1)
    })

    it("should parse and save CSV data to database", async () => {
      const csvData = `simplified,traditional,pinyin,meaning,hsk_level,radical,frequency,pos,classifiers
爱,愛,ài,love,new-1,爫,456,v,个`

      const { result, data } = parseCSV(csvData)

      expect(result.success).toBe(true)
      expect(result.imported).toBe(1)

      // Save to database
      await saveParsedHanzi(data)

      const hanzi = await prisma.hanzi.findUnique({
        where: { simplified: "爱" },
        include: {
          forms: {
            include: {
              transcriptions: true,
              meanings: true,
            },
          },
        },
      })

      expect(hanzi).toBeDefined()
      expect(hanzi?.forms[0].traditional).toBe("愛")
      expect(hanzi?.forms[0].transcriptions[0].value).toBe("ài")
    })

    it("should upsert existing hanzi", async () => {
      // First import
      const jsonData1 = JSON.stringify({
        simplified: "好",
        forms: [
          {
            traditional: "好",
            transcriptions: { pinyin: "hǎo" },
            meanings: ["good"],
          },
        ],
      })

      const { data: data1 } = parseHSKJson(jsonData1)
      await saveParsedHanzi(data1)

      // Second import with updated data
      const jsonData2 = JSON.stringify({
        simplified: "好",
        radical: "女",
        frequency: 100,
        forms: [
          {
            traditional: "好",
            transcriptions: { pinyin: "hǎo" },
            meanings: ["good", "fine"],
          },
        ],
      })

      const { result, data: data2 } = parseHSKJson(jsonData2)

      expect(result.success).toBe(true)

      await saveParsedHanzi(data2)

      const hanzi = await prisma.hanzi.findUnique({
        where: { simplified: "好" },
        include: {
          forms: {
            include: {
              meanings: true,
            },
          },
        },
      })

      expect(hanzi?.radical).toBe("女")
      expect(hanzi?.frequency).toBe(100)
      // Should have replaced meanings
      expect(hanzi?.forms[0].meanings).toHaveLength(2)
    })

    it("should handle multiple hanzi import", async () => {
      const jsonData = JSON.stringify([
        {
          simplified: "好",
          forms: [
            {
              traditional: "好",
              transcriptions: { pinyin: "hǎo" },
              meanings: ["good"],
            },
          ],
        },
        {
          simplified: "爱",
          forms: [
            {
              traditional: "愛",
              transcriptions: { pinyin: "ài" },
              meanings: ["love"],
            },
          ],
        },
        {
          simplified: "你",
          forms: [
            {
              traditional: "你",
              transcriptions: { pinyin: "nǐ" },
              meanings: ["you"],
            },
          ],
        },
      ])

      const { result, data } = parseHSKJson(jsonData)

      expect(result.success).toBe(true)
      expect(data).toHaveLength(3)

      await saveParsedHanzi(data)

      const count = await prisma.hanzi.count()
      expect(count).toBe(3)
    })
  })
})
