import { getNewDataSince, mergeSubjects } from '../modules/api/submodules/p2p'
import {
    countQuestionsInSubjects,
    getSubjectDifference,
} from '../utils/qdbUtils'
// import { QuestionDb, Subject } from '../types/basicTypes'

import { questions, subjects } from './testData'

// ------------------------------------------------------------------------------------
// getSubjectDifference
// ------------------------------------------------------------------------------------

test('Merging two similar question dbs should result in the same', () => {
    const { newData, newSubjects } = getSubjectDifference(subjects, subjects)

    const newQuestionCount = countQuestionsInSubjects(newData)

    expect(newSubjects.length).toBe(0)
    expect(newQuestionCount).toBe(0)
})

test('Merging qdb with another that has one extra question should get added', () => {
    const { newData, newSubjects } = getSubjectDifference(subjects, [
        subjects[0],
        {
            ...subjects[1],
            Questions: [...subjects[1].Questions, questions[10]],
        },
    ])

    const newQuestionCount = countQuestionsInSubjects(newData)

    expect(newSubjects.length).toBe(0)
    expect(newQuestionCount).toBe(1)
})

test('Qdb merging adding new subject', () => {
    const { newData, newSubjects } = getSubjectDifference(
        [subjects[0]],
        [subjects[0], subjects[1]]
    )

    const newQuestionCount = countQuestionsInSubjects(newData)

    expect(newSubjects.length).toBe(1)
    expect(newQuestionCount).toBe(0)
})

test('Qdb merging adding new subject and new questions', () => {
    const { newData, newSubjects } = getSubjectDifference(
        [subjects[0]],
        [
            {
                ...subjects[0],
                Questions: [...subjects[0].Questions, questions[10]],
            },
            subjects[1],
            subjects[2],
        ]
    )

    const newQuestionCount = countQuestionsInSubjects(newData)

    expect(newSubjects.length).toBe(2)
    expect(newQuestionCount).toBe(1)
})

// ------------------------------------------------------------------------------------
// getNewDataSince
// ------------------------------------------------------------------------------------

test('get new data since works', () => {
    const [q1, q2, q3] = questions
        .slice(0, 3)
        .map((q) => ({ ...q, data: { ...q.data, date: 500 } }))
    const [q4, q5, q6] = questions
        .slice(3, 6)
        .map((q) => ({ ...q, data: { ...q.data, date: 1000 } }))

    const res = getNewDataSince(
        [
            {
                Name: '1',
                Questions: [q1, q2, q3, q4, q5, q6],
            },
        ],
        750
    )
    expect(res.length).toBe(1)
    expect(res[0].Questions.length).toBe(3)
})

test('get new data since works, multiple subjects', () => {
    const [q1, q2, q3] = questions
        .slice(0, 3)
        .map((q) => ({ ...q, data: { ...q.data, date: 500 } }))
    const [q4, q5, q6] = questions
        .slice(3, 6)
        .map((q) => ({ ...q, data: { ...q.data, date: 1000 } }))

    const res = getNewDataSince(
        [
            {
                Name: '1',
                Questions: [q1, q2, q3, q4, q5, q6],
            },
            {
                Name: '2',
                Questions: [q1, q2, q3, q4],
            },
        ],
        750
    )
    expect(res.length).toBe(2)
    expect(res[0].Questions.length).toBe(3)
    expect(res[1].Questions.length).toBe(1)
})

test('get new data since works, multiple subjects round  2', () => {
    const [q1, q2, q3] = questions
        .slice(0, 3)
        .map((q) => ({ ...q, data: { ...q.data, date: 500 } }))
    const [q4, q5, q6] = questions
        .slice(3, 6)
        .map((q) => ({ ...q, data: { ...q.data, date: 1000 } }))
    const [q7, q8, q9] = questions
        .slice(6, 9)
        .map((q) => ({ ...q, data: { ...q.data, date: 500 } }))

    const res = getNewDataSince(
        [
            {
                Name: '1',
                Questions: [q1, q2, q3, q4, q5, q6],
            },
            {
                Name: '2',
                Questions: [q7, q8, q9],
            },
        ],
        750
    )
    expect(res.length).toBe(1)
    expect(res[0].Questions.length).toBe(3)
})

// ------------------------------------------------------------------------------------
// mergeQdbs
// ------------------------------------------------------------------------------------
test('merge subjects works', () => {
    const [s1] = subjects

    const res = mergeSubjects([s1], [s1], [s1])
    expect(res.length).toBe(2)
    expect(res[0].Questions.length).toBe(8)
})

test('merge subjects works, three new subjects', () => {
    const [s1] = subjects

    const res = mergeSubjects([s1], [s1], [s1, s1, s1])
    expect(res.length).toBe(4)
    expect(res[0].Questions.length).toBe(8)
    expect(res[1].Questions.length).toBe(4)
    expect(res[2].Questions.length).toBe(4)
    expect(res[3].Questions.length).toBe(4)
})

test('merge subjects works, no new subjects, two subjects to merge', () => {
    const [s1] = subjects

    const res = mergeSubjects([s1], [s1, s1, s1, s1], [])
    expect(res.length).toBe(1)
    expect(res[0].Questions.length).toBe(20)
})

test('merge subjects works, merging a subject with different name gets ignored', () => {
    const [s1, s2, s3] = subjects

    const res = mergeSubjects([s1, s2], [s3], [])
    expect(res.length).toBe(2)
    expect(res[0].Questions.length).toBe(4)
    expect(res[1].Questions.length).toBe(4)
})

test('merge subjects works, 2 subjects to 2, 1 new', () => {
    const [s1, s2, s3] = subjects

    const res = mergeSubjects([s1, s2], [s1, s2], [s3])
    expect(res.length).toBe(3)
    expect(res[0].Questions.length).toBe(8)
    expect(res[1].Questions.length).toBe(8)
    expect(res[2].Questions.length).toBe(4)
})

test('merge subjects works, no new data', () => {
    const [s1, s2] = subjects

    const res = mergeSubjects([s1, s2], [], [])
    expect(res.length).toBe(2)
    expect(res[0].Questions.length).toBe(4)
    expect(res[1].Questions.length).toBe(4)
})
