
#include <iostream>
#include <string>
#include <limits>
using namespace std;

struct Book {
    int id;
    string title;
    string author;
    bool borrowed;
};

// Ham nhap so nguyen
bool readInt(const string& prompt, int& x) {
    cout << prompt;

    if (cin >> x)
        return true;

    if (cin.eof())
        return false;

    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    cout << "Vui long nhap so nguyen!\n";
    return false;
}

// Tim sach theo ID
Book* findBook(Book* ds, int n, int id) {
    for (int i = 0; i < n; i++) {
        if (ds[i].id == id) {
            return &ds[i];
        }
    }

    return nullptr;
}

// Nhap danh sach
void inputBooks(Book* ds, int n) {
    for (int i = 0; i < n; i++) {
        cout << "\nSach thu " << i + 1 << ":\n";

        while (true) {
            int id;

            if (!readInt("ID: ", id))
                continue;

            if (findBook(ds, i, id) != nullptr) {
                cout << "ID da ton tai!\n";
                continue;
            }

            ds[i].id = id;
            break;
        }

        cout << "Tieu de: ";
        getline(cin >> ws, ds[i].title);

        cout << "Tac gia: ";
        getline(cin >> ws, ds[i].author);

        ds[i].borrowed = false;
    }
}

// Hien thi mot cuon sach
void printBook(const Book& b) {
    cout << "ID: " << b.id
         << " | Tieu de: " << b.title
         << " | Tac gia: " << b.author
         << " | Trang thai: "
         << (b.borrowed ? "Da muon" : "Chua muon")
         << '\n';
}

// Hien thi danh sach
void showBooks(Book* ds, int n) {
    if (n == 0) {
        cout << "Danh sach trong!\n";
        return;
    }

    for (int i = 0; i < n; i++) {
        printBook(ds[i]);
    }
}

// Tim va hien thi sach
void searchBook(Book* ds, int n) {
    int id;

    if (!readInt("Nhap ID can tim: ", id))
        return;

    Book* p = findBook(ds, n, id);

    if (p == nullptr) {
        cout << "Khong tim thay sach!\n";
        return;
    }

    printBook(*p);
}

// Muon sach
void borrowBook(Book* ds, int n) {
    int id;

    if (!readInt("Nhap ID muon muon: ", id))
        return;

    Book* p = findBook(ds, n, id);

    if (p == nullptr) {
        cout << "Khong tim thay sach!\n";
        return;
    }

    if (p->borrowed) {
        cout << "Sach da duoc muon!\n";
        return;
    }

    p->borrowed = true;
    cout << "Muon sach thanh cong!\n";
}

// Tra sach
void returnBook(Book* ds, int n) {
    int id;

    if (!readInt("Nhap ID muon tra: ", id))
        return;

    Book* p = findBook(ds, n, id);

    if (p == nullptr) {
        cout << "Khong tim thay sach!\n";
        return;
    }

    if (!p->borrowed) {
        cout << "Sach chua duoc muon!\n";
        return;
    }

    p->borrowed = false;
    cout << "Tra sach thanh cong!\n";
}

// Xoa sach - chi Librarian
void deleteBook(Book*& ds, int& n, bool isLibrarian) {
    if (!isLibrarian) {
        cout << "Chi librarian duoc xoa sach!\n";
        return;
    }

    int id;

    if (!readInt("Nhap ID sach can xoa: ", id))
        return;

    int index = -1;

    for (int i = 0; i < n; i++) {
        if (ds[i].id == id) {
            index = i;
            break;
        }
    }

    if (index == -1) {
        cout << "Khong tim thay sach!\n";
        return;
    }

    Book* temp = nullptr;

    if (n > 1) {
        temp = new Book[n - 1];
        int j = 0;

        for (int i = 0; i < n; i++) {
            if (i == index)
                continue;

            temp[j++] = ds[i];
        }
    }

    delete[] ds;
    ds = temp;
    n--;

    cout << "Xoa sach thanh cong!\n";
}

// Dang nhap mo phong
bool login(bool& isLibrarian) {
    int role;

    if (!readInt("1. Librarian  2. User\nChon: ", role))
        return false;

    if (role == 2) {
        isLibrarian = false;
        return true;
    }

    if (role == 1) {
        string password;

        cout << "Nhap mat khau librarian: ";
        cin >> password;

        if (password == "Lib123") {
            isLibrarian = true;
            return true;
        }
    }

    cout << "Dang nhap that bai!\n";
    return false;
}

int main() {
    int n;

    if (!readInt("Nhap so sach (0..1000): ", n)
        || n < 0 || n > 1000) {
        cout << "So sach khong hop le!\n";
        return 0;
    }

    Book* ds = (n > 0) ? new Book[n] : nullptr;
    inputBooks(ds, n);

    int mainChoice = -1;

    do {
        if (!readInt(
                "\n=== MENU CHINH ===\n"
                "1. Dang nhap\n"
                "0. Thoat\n"
                "Chon: ", mainChoice)) {
            mainChoice = -1;
            if (cin.eof()) break;
            continue;
        }

        if (mainChoice == 1) {
            bool isLibrarian = false;

            if (!login(isLibrarian)) {
                if (cin.eof()) break;
                continue;
            }

            int choice = -1;

            do {
                if (!readInt(
                        "\n=== MENU THU VIEN ===\n"
                        "1. Hien thi\n"
                        "2. Tim sach\n"
                        "3. Muon sach\n"
                        "4. Tra sach\n"
                        "5. Xoa sach\n"
                        "0. Dang xuat\n"
                        "Chon: ", choice)) {
                    choice = -1;
                    if (cin.eof()) break;
                    continue;
                }

                switch (choice) {
                    case 1:
                        showBooks(ds, n);
                        break;

                    case 2:
                        searchBook(ds, n);
                        break;

                    case 3:
                        borrowBook(ds, n);
                        break;

                    case 4:
                        returnBook(ds, n);
                        break;

                    case 5:
                        deleteBook(ds, n, isLibrarian);
                        break;

                    case 0:
                        cout << "Da dang xuat!\n";
                        break;

                    default:
                        cout << "Lua chon khong hop le!\n";
                }

                if (cin.eof()) break;

            } while (choice != 0);
        }
        else if (mainChoice != 0) {
            cout << "Lua chon khong hop le!\n";
        }

        if (cin.eof()) break;

    } while (mainChoice != 0);

    delete[] ds;
    ds = nullptr;

    cout << "Da giai phong bo nho!\n";
    return 0;
}
