import { describe, it, expect } from "vitest"
import { parseCSV, generateCSVTemplate } from "./csv-parser"

describe("parseCSV", () => {
  it("should parse valid CSV with all fields", () => {
    const csv = `simplified,traditional,pinyin,meaning,hsk_level,radical,frequency,pos,classifiers
爱好,愛好,ài hào,"to like; hobby","new-1,old-3",爫,4902,"n,v",个`

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(true)
    expect(result.imported).toBe(1)
    expect(result.failed).toBe(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].classifiers).toEqual(["个"])
  })

  it("should parse CSV with only required fields", () => {
    const csv = `simplified,traditional,pinyin,meaning
好,好,hǎo,good`

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(true)
    expect(result.imported).toBe(1)
    expect(data[0].simplified).toBe("好")
    expect(data[0].radical).toBeUndefined()
    expect(data[0].frequency).toBeUndefined()
    expect(data[0].hskLevels).toEqual([])
    expect(data[0].partsOfSpeech).toEqual([])
  })

  it("should parse multiple rows", () => {
    const csv = `simplified,traditional,pinyin,meaning
好,好,hǎo,good
爱,愛,ài,love
你,你,nǐ,you`

    const { result, data } = parseCSV(csv)

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

  it("should handle quoted values with commas", () => {
    const csv = `simplified,traditional,pinyin,meaning
好,好,hǎo,"good, fine, nice"`

    const { result, data } = parseCSV(csv)

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

  it("should handle quoted values with semicolons (multiple meanings)", () => {
    const csv = `simplified,traditional,pinyin,meaning
好,好,hǎo,"good; fine; nice"`

    const { result, data } = parseCSV(csv)

    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 escaped quotes in values", () => {
    const csv = `simplified,traditional,pinyin,meaning
好,好,hǎo,"He said ""good"""`

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(true)
    expect(data[0].forms[0].meanings[0].meaning).toBe('He said "good"')
  })

  it("should skip empty lines", () => {
    const csv = `simplified,traditional,pinyin,meaning
好,好,hǎo,good

爱,愛,ài,love

你,你,nǐ,you`

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(true)
    expect(result.imported).toBe(3)
  })

  it("should parse comma-separated HSK levels", () => {
    const csv = `simplified,traditional,pinyin,meaning,hsk_level
好,好,hǎo,good,"new-1,old-2,old-3"`

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(true)
    expect(data[0].hskLevels).toEqual(["new-1", "old-2", "old-3"])
  })

  it("should parse comma-separated parts of speech", () => {
    const csv = `simplified,traditional,pinyin,meaning,hsk_level,radical,frequency,pos
好,好,hǎo,good,,,,"adj,v,n"`

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(true)
    expect(data[0].partsOfSpeech).toEqual(["adj", "v", "n"])
  })

  it("should parse comma-separated classifiers", () => {
    const csv = `simplified,traditional,pinyin,meaning,hsk_level,radical,frequency,pos,classifiers
好,好,hǎo,good,,,,,"个,只,条"`

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(true)
    expect(data[0].forms[0].classifiers).toEqual(["个", "只", "条"])
  })

  it("should parse frequency as number", () => {
    const csv = `simplified,traditional,pinyin,meaning,hsk_level,radical,frequency
好,好,hǎo,good,,,1234`

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(true)
    expect(data[0].frequency).toBe(1234)
  })

  it("should return error for empty CSV", () => {
    const csv = ""

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(false)
    expect(result.errors).toHaveLength(1)
    expect(result.errors[0].error).toContain("Invalid CSV headers")
  })

  it("should return error for invalid headers", () => {
    const csv = `wrong,headers
好,好`

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(false)
    expect(result.errors).toHaveLength(1)
    expect(result.errors[0].error).toContain("Invalid CSV headers")
  })

  it("should return error for missing required fields", () => {
    const csv = `simplified,traditional,pinyin,meaning
好,好,,good`

    const { result, data } = parseCSV(csv)

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

  it("should continue parsing after errors", () => {
    const csv = `simplified,traditional,pinyin,meaning
好,好,hǎo,good
爱,愛,,love
你,你,nǐ,you`

    const { result, data } = parseCSV(csv)

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

  it("should set first form as default", () => {
    const csv = `simplified,traditional,pinyin,meaning
好,好,hǎo,good`

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(true)
    expect(data[0].forms[0].isDefault).toBe(true)
  })

  it("should create pinyin transcription", () => {
    const csv = `simplified,traditional,pinyin,meaning
好,好,hǎo,good`

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(true)
    expect(data[0].forms[0].transcriptions).toHaveLength(1)
    expect(data[0].forms[0].transcriptions[0].type).toBe("pinyin")
    expect(data[0].forms[0].transcriptions[0].value).toBe("hǎo")
  })

  it("should set language code to English", () => {
    const csv = `simplified,traditional,pinyin,meaning
好,好,hǎo,good`

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(true)
    expect(data[0].forms[0].meanings[0].languageCode).toBe("en")
  })

  it("should assign order indices to meanings", () => {
    const csv = `simplified,traditional,pinyin,meaning
好,好,hǎo,"good; fine; nice"`

    const { result, data } = parseCSV(csv)

    expect(result.success).toBe(true)
    expect(data[0].forms[0].meanings[0].orderIndex).toBe(0)
    expect(data[0].forms[0].meanings[1].orderIndex).toBe(1)
    expect(data[0].forms[0].meanings[2].orderIndex).toBe(2)
  })
})

describe("generateCSVTemplate", () => {
  it("should generate valid CSV template", () => {
    const template = generateCSVTemplate()

    expect(template).toContain("simplified,traditional,pinyin,meaning")
    expect(template).toContain("爱好,愛好,ài hào")

    const lines = template.split("\n")
    expect(lines).toHaveLength(2) // Header + example
  })

  it("should have parseable template", () => {
    const template = generateCSVTemplate()

    const { result } = parseCSV(template)

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