#include "Course.h"
#include "Student.h"
#include <iostream>

Course::Course(std::string name) : name(std::move(name)) {
    firstStudent = nullptr;
}

void Course::addStudent(Student *newStudent) {
    if (firstStudent == nullptr) {
        firstStudent = newStudent;
        lastStudent = newStudent;
    } else {
        lastStudent->setNextStudent(newStudent);
        newStudent->setPreviousStudent(lastStudent);
        lastStudent = newStudent;
    }
}

void Course::deleteStudent(int matriculationNumber) {
    if (firstStudent == nullptr) {
        return;
    }
    Student *currentStudent = firstStudent;
    while (currentStudent != nullptr && currentStudent->getMatriculationNumber() != matriculationNumber) {
        currentStudent = currentStudent->getNextStudent();
    }
    if (currentStudent != nullptr) {
        if (currentStudent->getPreviousStudent() != nullptr) {
            currentStudent->getPreviousStudent()->setNextStudent(currentStudent->getNextStudent());
        }
        if (currentStudent->getNextStudent() != nullptr) {
            currentStudent->getNextStudent()->setPreviousStudent(currentStudent->getPreviousStudent());
        }
        if (currentStudent == firstStudent) {
            firstStudent = currentStudent->getNextStudent();
        }
        if (currentStudent == lastStudent) {
            lastStudent = currentStudent->getPreviousStudent();
        }
        delete currentStudent;
    }
}

void Course::displayStudent(int matriculationNumber) {
    Student *currentStudent = firstStudent;
    while (currentStudent != nullptr && currentStudent->getMatriculationNumber() != matriculationNumber) {
        currentStudent = currentStudent->getNextStudent();
    }
    if (currentStudent != nullptr) {
        std::cout << "Student: " << currentStudent->getFirstName() << " " << currentStudent->getLastName()
                  << std::endl;
    } else {
        std::cout << "Student not found." << std::endl;
    }
}

Student *Course::getStudent(int matriculationNumber) {
    Student *currentStudent = firstStudent;
    while (currentStudent != nullptr && currentStudent->getMatriculationNumber() != matriculationNumber) {
        currentStudent = currentStudent->getNextStudent();
    }
    if (currentStudent != nullptr) {
        return currentStudent;
    }
    return nullptr;
}

void Course::displayStudents() {
    // Display the firstStudent in the course in a table.
    std::cout << "Name\t\t| Vorname\t\t| Matrikelnummer" << std::endl;
    std::cout << "--------------------------------------------" << std::endl;

    Student *currentStudent = firstStudent;
    while (currentStudent != nullptr) {
        std::cout << currentStudent->getFirstName() << "\t\t\t" << currentStudent->getLastName() << "\t\t\t"
                  << currentStudent->getMatriculationNumber() << std::endl;
        currentStudent = currentStudent->getNextStudent();
    }
}

void Course::displayCourse() {
    std::cout << "Course name: " << name << std::endl;
    sort();
    displayStudents();
}

void Course::sort() {
    if (firstStudent == nullptr) {
        return;
    }
    Student *currentStudent = firstStudent->getNextStudent();
    while (currentStudent != nullptr) {
        Student *tempStudent = currentStudent;
        while (tempStudent->getPreviousStudent() != nullptr &&
               tempStudent->getPreviousStudent()->getLastName() > tempStudent->getLastName()) {
            // swap tempStudent and prevStudent
            if (tempStudent->getPreviousStudent() == firstStudent) firstStudent = tempStudent;
            if (tempStudent == lastStudent) lastStudent = tempStudent->getPreviousStudent();
            tempStudent->getPreviousStudent()->setNextStudent(tempStudent->getNextStudent());
            if (tempStudent->getNextStudent() != nullptr)
                tempStudent->getNextStudent()->setPreviousStudent(tempStudent->getPreviousStudent());
            tempStudent->setNextStudent(tempStudent->getPreviousStudent());
            tempStudent->setPreviousStudent(tempStudent->getPreviousStudent()->getPreviousStudent());
            if (tempStudent->getPreviousStudent() != nullptr)
                tempStudent->getPreviousStudent()->setNextStudent(tempStudent);
            tempStudent->getNextStudent()->setPreviousStudent(tempStudent);
        }
        currentStudent = currentStudent->getNextStudent();
    }
}

std::string Course::getName() const {
    return name;
}