#include <iostream>
#include <string>
#include <vector>
using namespace std;


class FlightOptions {
public:

    // vectors created to store location and airline information
    vector<string>
    locations = {"Florida", "Spain", "Portugal", "New York", "Turkey"};
    vector<string>
    airlines = {"British Airways", "EasyJet", "Ryanair", "Virgin Atlantic", "Turkish Airlines" };

    // print location details function created to iterate through vector and print details to console
    void printLocationDetails() {
        int counter = 0;
        int flightno = 1;
        cout << "Please see a list of areas that we offer flights too..." << endl;
        int noLocations = locations.size();
        while (noLocations != counter) {
            cout << flightno << ". " << locations[counter] << ", " << airlines[counter] << endl;
            counter++;
            flightno++;
        }
    }
    
    // add location function created to allow admin users to add new locations to vector
    //https://www.programiz.com/cpp-programming/vectors#:~:text=Add%20Elements%20to%20a%20Vector&text=num.-,push_back(6)%3B%20num.,add%20elements%20to%20a%20vector.
    void addLocation(string location, string airline) {
        if (std::find(std::begin(locations), std::end(locations), location) != std::end(locations)) {
            cout << "Location already exists in the list.";
        }
        else {
            locations.push_back(location);
            airlines.push_back(airline);
            cout << "Location has been added to the list." << endl;
        }
    }
};


class Bookings : public FlightOptions {
public:

    // inialising and declaring current year
    string currentYear = "2024";

    // vectors created to store location and booking date information
    // https://www.programiz.com/cpp-programming/vectors#:~:text=Add%20Elements%20to%20a%20Vector&text=num.-,push_back(6)%3B%20num.,add%20elements%20to%20a%20vector.
    std::vector<string>
        bookingLocation = {};
    std::vector<string>
        bookingDate = {};

    // assign booking function created to add booking details to vectors
    int assignBooking(string location, int flightDay, int flightMonth, string flightYear) {

        // https://www.quora.com/What-is-the-SIMPLEST-way-to-check-if-an-element-is-in-an-array-in-C-C#:~:text=This%20code%20uses%20%5Bcode%5Dstd,()%5B%2Fcode%5D.
        // https://www.w3resource.com/cpp-exercises/oop/cpp-oop-exercise-8.php#:~:text=The%20member%20functions%20getDay%2C%20getMonth,and%20that%20the%20specific%20month.
        // https://cplusplus.com/reference/string/to_string/
        if (std::find(std::begin(locations), std::end(locations), location) != std::end(locations)) {
            if (flightDay > 0 && flightDay < 32) {
                if (flightMonth > 0 && flightMonth < 13) {
                    if (flightYear == currentYear) {
                        // combines int's and converts into string to store in booking date vector
                        string flightDate = std::to_string(flightDay) + "/" + std::to_string(flightMonth);
                        flightDate = flightDate + "/" + flightYear;
                        bookingLocation.push_back(location);
                        bookingDate.push_back(flightDate);
                        cout << "Your booking is complete" << endl;
                        return 1;
                    }
                    else {
                        cout << "ERROR - unable to book a flight before or after the year of " << currentYear << "." << endl;
                    }
                }
                else {
                    cout << "ERROR - invalid date entered.";
                }
            }
            else {
                cout << "ERROR - invalid date entered.";
            }

        }
        else {
            cout << " ERROR - Location entered is not available." << endl;
            return 0;
        }
    }


    // display booking function created to iterate through vector and print details to console
    //https://stackoverflow.com/questions/10750057/how-do-i-print-out-the-contents-of-a-vector
    void displayBooking(int noOfBooking) {
        if (noOfBooking == 0) {
            cout << "ERROR - no bookings associated with this account." << endl;
        }
        else {
            cout << "Bookings associated with this account: " << endl;
            for (int i = 0; i < bookingLocation.size(); ++i)
                std::cout << bookingLocation[i] << " on " << bookingDate[i] << endl;
        }
    }

};


class Account : public Bookings {
public:

    // user account function set up to restrict access to the system
    int userAccount(string username, string password) {

        string uname1 = "admin";
        string pword1 = "admin";
        string uname2 = "test1";
        string pword2 = "test1";


        if (username == uname1) {
            if (password == pword1) {
                return 2;
            }
            else {
                cout << "\nIncorrect details provided." << endl;
                cout << "\nTerminating session..." << endl;
                return 0;
            }
        }
        else if (username == uname2) {
            if (password == pword2) {
                return 1;
            }
            else {
                cout << "\nIncorrect details provided." << endl;
                cout << "\nTerminating session..." << endl;
                return 0;
            }
        }
        else {
            cout << "\nIncorrect details provided." << endl;
            cout << "\nTerminating session..." << endl;
            return 0;
        }

    }
};


int main() {
    int choice;
    int loggedIn;
    string username;
    string password;
    string location;
    string airline;
    int dayOfFlight;
    int monthOfFlight;
    string yearOfFlight;
    int noOfBookings = 0;
    int successfulBooking;
    
    // creating account object
    Account account1;
    FlightOptions availableFlights;

    cout << "Welcome to the flight booking system..." << endl;
    cout << "\nPlease enter your username: ";
    cin >> username;
    cout << "\nPlease enter your password: ";
    cin >> password;

    loggedIn = account1.userAccount(username, password);
    
    while (loggedIn == 1 || loggedIn == 2) {

        if (loggedIn == 1) {
            cout << "\nPress 1 to search for flight locations";
            cout << "\nPress 2 to book a flight";
            cout << "\nPress 3 to manage booking";
            cout << "\nPress 4 to exit" << endl;
            cin >> choice;

            // reference: https://stackoverflow.com/questions/67355343/making-a-menu-in-c-oop
            switch (choice) {
            case 1:
                cout << "menu option 1" << endl;
                availableFlights.printLocationDetails();
                break;

            case 2:
                cout << "menu option 2" << endl;
                cout << "Please enter the name of location you would like to book your flight to?" << endl;
                cin >> location;
                cout << "Please enter the day of flight?" << endl;
                cin >> dayOfFlight;
                cout << "Please enter the month of flight?" << endl;
                cin >> monthOfFlight;
                cout << "Please enter the year of flight?" << endl;
                cin >> yearOfFlight;
                //https://www.tutorialspoint.com/cplusplus/cpp_date_time.htm
                successfulBooking = account1.assignBooking(location, dayOfFlight, monthOfFlight, yearOfFlight);
                if (successfulBooking == 1) {
                    noOfBookings++;
                }
                break;

            case 3:
                cout << "menu option 3" << endl;
                account1.displayBooking(noOfBookings);
                break;

            case 4:
                cout << "Exit" << endl;
                loggedIn = 0;
                break;
            }
        }
        else {
            cout << "\nPress 1 to search for flight locations";
            cout << "\nPress 2 to add to the list of flight locations";
            cout << "\nPress 3 to exit" << endl;
            cin >> choice;

            // reference: https://stackoverflow.com/questions/67355343/making-a-menu-in-c-oop
            switch (choice) {
            case 1:
                cout << "menu option 1" << endl;
                availableFlights.printLocationDetails();
                break;

            case 2:
                cout << "menu option 2" << endl;
                cout << "Please enter the name of location that you would like to add to the list?" << endl;
                cin >> location;
                cout << "Please enter the airline that will be used to fly to " << location << " ?" << endl;
                cin >> airline;
                availableFlights.addLocation(location, airline);
                break;

            case 3:
                cout << "Exit" << endl;
                loggedIn = 0;
                break;
            }
        }
    }
}
