import { describe, it, expect } from "vitest"
import { parseHSKJson, validateHSKJsonEntry } from "./hsk-json-parser"

describe("parseHSKJson", () => {
  it("should parse valid single JSON entry", () => {
    const json = JSON.stringify({
      simplified: "爱好",
      radical: "爫",
      level: ["new-1", "old-3"],
      frequency: 4902,
      pos: ["n", "v"],
      forms: [
        {
          traditional: "愛好",
          transcriptions: {
            pinyin: "ài hào",
            numeric: "ai4 hao4",
          },
          meanings: ["to like; hobby"],
          classifiers: ["个"],
        },
      ],
    })

    const { result, data } = parseHSKJson(json)

    expect(result.success).toBe(true)
    expect(result.imported).toBe(1)
    expect(result.failed).toBe(0)
    expect(result.errors).toHaveLength(0)
    expect(data).toHaveLength(1)
    expect(data[0].simplified).toBe("爱好")
    expect(data[0].radical).toBe("爫")
    expect(data[0].frequency).toBe(4902)
    expect(data[0].hskLevels).toEqual(["new-1", "old-3"])
    expect(data[0].partsOfSpeech).toEqual(["n", "v"])
    expect(data[0].forms).toHaveLength(1)
    expect(data[0].forms[0].traditional).toBe("愛好")
    expect(data[0].forms[0].isDefault).toBe(true)
  })

  it("should parse valid JSON array", () => {
    const json = JSON.stringify([
      {
        simplified: "爱",
        forms: [
          {
            traditional: "愛",
            transcriptions: { pinyin: "ài" },
            meanings: ["to love"],
          },
        ],
      },
      {
        simplified: "好",
        forms: [
          {
            traditional: "好",
            transcriptions: { pinyin: "hǎo" },
            meanings: ["good"],
          },
        ],
      },
    ])

    const { result, data } = parseHSKJson(json)

    expect(result.success).toBe(true)
    expect(result.imported).toBe(2)
    expect(data).toHaveLength(2)
  })

  it("should handle missing optional fields", () => {
    const json = JSON.stringify({
      simplified: "好",
      forms: [
        {
          traditional: "好",
          transcriptions: { pinyin: "hǎo" },
          meanings: ["good"],
        },
      ],
    })

    const { result, data } = parseHSKJson(json)

    expect(result.success).toBe(true)
    expect(data[0].radical).toBeUndefined()
    expect(data[0].frequency).toBeUndefined()
    expect(data[0].hskLevels).toEqual([])
    expect(data[0].partsOfSpeech).toEqual([])
  })

  it("should split semicolon-separated meanings", () => {
    const json = JSON.stringify({
      simplified: "好",
      forms: [
        {
          traditional: "好",
          transcriptions: { pinyin: "hǎo" },
          meanings: ["good; fine; nice"],
        },
      ],
    })

    const { result, data } = parseHSKJson(json)

    expect(result.success).toBe(true)
    expect(data[0].forms[0].meanings).toHaveLength(3)
    expect(data[0].forms[0].meanings[0].meaning).toBe("good")
    expect(data[0].forms[0].meanings[1].meaning).toBe("fine")
    expect(data[0].forms[0].meanings[2].meaning).toBe("nice")
  })

  it("should handle multiple forms with second form not being default", () => {
    const json = JSON.stringify({
      simplified: "爱",
      forms: [
        {
          traditional: "愛",
          transcriptions: { pinyin: "ài" },
          meanings: ["to love"],
        },
        {
          traditional: "爱",
          transcriptions: { pinyin: "ài" },
          meanings: ["to love (simplified)"],
        },
      ],
    })

    const { result, data } = parseHSKJson(json)

    expect(result.success).toBe(true)
    expect(data[0].forms).toHaveLength(2)
    expect(data[0].forms[0].isDefault).toBe(true)
    expect(data[0].forms[1].isDefault).toBe(false)
  })

  it("should handle multiple transcription types", () => {
    const json = JSON.stringify({
      simplified: "好",
      forms: [
        {
          traditional: "好",
          transcriptions: {
            pinyin: "hǎo",
            numeric: "hao3",
            wadegiles: "hao3",
          },
          meanings: ["good"],
        },
      ],
    })

    const { result, data } = parseHSKJson(json)

    expect(result.success).toBe(true)
    expect(data[0].forms[0].transcriptions).toHaveLength(3)
    expect(data[0].forms[0].transcriptions.map(t => t.type)).toContain("pinyin")
    expect(data[0].forms[0].transcriptions.map(t => t.type)).toContain("numeric")
    expect(data[0].forms[0].transcriptions.map(t => t.type)).toContain("wadegiles")
  })

  it("should return error for invalid JSON", () => {
    const json = "{ invalid json }"

    const { result, data } = parseHSKJson(json)

    expect(result.success).toBe(false)
    expect(result.imported).toBe(0)
    expect(result.errors).toHaveLength(1)
    expect(result.errors[0].error).toContain("Invalid JSON")
    expect(data).toHaveLength(0)
  })

  it("should return error for missing required fields", () => {
    const json = JSON.stringify({
      simplified: "好",
      // Missing forms
    })

    const { result, data } = parseHSKJson(json)

    expect(result.success).toBe(false)
    expect(result.failed).toBe(1)
    expect(result.errors).toHaveLength(1)
    expect(data).toHaveLength(0)
  })

  it("should return error for empty simplified field", () => {
    const json = JSON.stringify({
      simplified: "",
      forms: [
        {
          traditional: "好",
          transcriptions: { pinyin: "hǎo" },
          meanings: ["good"],
        },
      ],
    })

    const { result, data } = parseHSKJson(json)

    expect(result.success).toBe(false)
    expect(result.errors).toHaveLength(1)
  })

  it("should return error for empty meanings array", () => {
    const json = JSON.stringify({
      simplified: "好",
      forms: [
        {
          traditional: "好",
          transcriptions: { pinyin: "hǎo" },
          meanings: [],
        },
      ],
    })

    const { result, data } = parseHSKJson(json)

    expect(result.success).toBe(false)
    expect(result.errors).toHaveLength(1)
  })

  it("should continue parsing after errors", () => {
    const json = JSON.stringify([
      {
        simplified: "好",
        forms: [
          {
            traditional: "好",
            transcriptions: { pinyin: "hǎo" },
            meanings: ["good"],
          },
        ],
      },
      {
        simplified: "", // Invalid
        forms: [
          {
            traditional: "x",
            transcriptions: { pinyin: "x" },
            meanings: ["x"],
          },
        ],
      },
      {
        simplified: "爱",
        forms: [
          {
            traditional: "愛",
            transcriptions: { pinyin: "ài" },
            meanings: ["love"],
          },
        ],
      },
    ])

    const { result, data } = parseHSKJson(json)

    expect(result.success).toBe(false)
    expect(result.imported).toBe(2)
    expect(result.failed).toBe(1)
    expect(data).toHaveLength(2)
  })
})

describe("validateHSKJsonEntry", () => {
  it("should validate correct entry", () => {
    const entry = {
      simplified: "好",
      forms: [
        {
          traditional: "好",
          transcriptions: { pinyin: "hǎo" },
          meanings: ["good"],
        },
      ],
    }

    const result = validateHSKJsonEntry(entry)

    expect(result.valid).toBe(true)
    expect(result.errors).toHaveLength(0)
  })

  it("should return errors for invalid entry", () => {
    const entry = {
      simplified: "",
      forms: [],
    }

    const result = validateHSKJsonEntry(entry)

    expect(result.valid).toBe(false)
    expect(result.errors.length).toBeGreaterThan(0)
  })
})
