import { updateQuestionsInArray } from '../utils/actions'
import { QuestionDb, Subject, Question } from '../types/basicTypes'

import { questions } from './testData'
import { cleanDb } from '../utils/qdbUtils'

const [q1, q2, q3, q4] = questions.slice(0, 4).map((q) => ({
    ...q,
    data: {
        ...q.data,
        date: 100,
    },
}))
const [q5, q6] = questions.slice(4, 6).map((q) => ({
    ...q,
    data: {
        ...q.data,
        date: 1000,
    },
}))

function setupTest({
    newQuestions,
    data,
    subjToClean,
}: {
    newQuestions: Question[]
    data: Subject[]
    subjToClean?: string
}) {
    const recievedQuestions: Question[] = newQuestions.map((x) => {
        return {
            ...x,
            data: {
                ...x.data,
                date: 500,
            },
        }
    })
    const subjName = subjToClean || 'subject'
    const overwriteBeforeDate = 400
    const qdbIndex = 0
    const qdbs: QuestionDb[] = [
        {
            name: 'test',
            data: data,
            index: 0,
            path: '',
            shouldSearch: 'asd',
            shouldSave: {},
        },
    ]
    const subjIndex = qdbs[qdbIndex].data.findIndex((x) => {
        return x.Name.toLowerCase().includes(subjName.toLowerCase())
    })

    const questionIndexesToRemove = cleanDb(
        {
            questions: recievedQuestions,
            subjToClean: subjName,
            overwriteBeforeDate: overwriteBeforeDate,
            qdbIndex: qdbIndex,
        },
        qdbs
    )

    const updatedQuestions = updateQuestionsInArray(
        questionIndexesToRemove,
        qdbs[qdbIndex].data[subjIndex].Questions,
        recievedQuestions
    )

    return {
        questionIndexesToRemove: questionIndexesToRemove,
        updatedQuestions: updatedQuestions,
        overwriteBeforeDate: overwriteBeforeDate,
        subjIndex: subjIndex,
    }
}

const s1: Subject = { Name: 'test subject', Questions: [q1, q2, q4, q5] }

test('Old and duplicate questions should be removed from the database', () => {
    const { questionIndexesToRemove, updatedQuestions } = setupTest({
        newQuestions: [q1, q2, q3],
        data: [s1],
    })

    expect(questionIndexesToRemove[0].length).toBe(2)
    expect(questionIndexesToRemove[1].length).toBe(2)
    expect(questionIndexesToRemove[2].length).toBe(2)

    expect(updatedQuestions.length).toBe(5)
})

const s2: Subject = {
    Name: 'test subject',
    Questions: [q1, q2, q3, q4, q5, q6],
}

test('Old and duplicate questions should be removed from the database round 2', () => {
    const { questionIndexesToRemove, updatedQuestions } = setupTest({
        newQuestions: [q1, q4, q5],
        data: [s2],
    })

    expect(questionIndexesToRemove[0].length).toBe(3)
    expect(questionIndexesToRemove[1].length).toBe(1)
    expect(questionIndexesToRemove[2].length).toBe(0)

    expect(updatedQuestions.length).toBe(4)
})

test('Old and duplicate questions should be removed from the database round 3', () => {
    const { questionIndexesToRemove, updatedQuestions } = setupTest({
        newQuestions: [q5, q6],
        data: [s2],
    })

    expect(questionIndexesToRemove[0].length).toBe(0)
    expect(questionIndexesToRemove[1].length).toBe(0)

    expect(updatedQuestions.length).toBe(6)
})

const s3: Subject = {
    Name: 'test subject',
    Questions: [q5, q6].map((q) => ({
        ...q,
        data: {
            ...q.data,
            date: 50000,
        },
    })),
}

test('Old and duplicate questions should be removed from the database: questions should be left alone when they are newer', () => {
    const { questionIndexesToRemove, updatedQuestions } = setupTest({
        newQuestions: [q5, q6],
        data: [s3],
    })

    expect(questionIndexesToRemove.length).toBe(2)
    questionIndexesToRemove.forEach((x) => {
        expect(x.length).toBe(0)
    })

    expect(updatedQuestions.length).toBe(2)
})

const s4: Subject = {
    Name: 'something else',
    Questions: [q5, q6],
}

test('Old and duplicate questions should be removed from the database:other subjects should be left alone', () => {
    const { subjIndex } = setupTest({
        newQuestions: [q5, q6],
        data: [s2, s1, s4, s3],
        subjToClean: 'else',
    })

    expect(subjIndex).toBe(2)
})
