#include "headers/Query.h"

vector<Park_time> query_parktimes_for_customer(int cid) {
    /*
    This is needed to initialize the park_instances for the customer constructor
    that is supposed to create a customer from data in the db.
    This should not be called on on it's own outside query_customer();
     */
    vector<Park_time> park_times;

    SQLite::Statement query(data::db, "SELECT * FROM Park_time WHERE customer_id = ?;");
    query.bind(1, cid);
    while (query.executeStep()) {
        int id = query.getColumn(0);
        int spot_id = query.getColumn(2);
        int start = query.getColumn(3);
        int duration = query.getColumn(5);

        Park_time result{id, cid, spot_id, start, duration};
        park_times.push_back(result);
    }
    query.reset();
    return park_times;
}

//--------------------------------------------- customers

vector<Customer> query_customer_with_name(string name) {
    /*
    We use this instead of plain customers because:
    1. no error handling needed here if there are no customers
    2. multiple customers could be returned with the same name.
     */
    vector<Customer> result;
    SQLite::Statement query(data::db,
                            "SELECT id, name, password, vehicle FROM Customer WHERE name = ?;");
    query.bind(1, name);
    while (query.executeStep()) {
        int id = query.getColumn(0);
        string name_ = query.getColumn(1);
        string password = query.getColumn(2);
        int vehicle = query.getColumn(3); // cast to vehicle
        string telephone = query.getColumn(4);
        vector<Park_time> park_instances = query_parktimes_for_customer(id);
        result.push_back(
            Customer{id, name_, password, Vehicle_type(vehicle), park_instances, telephone});
    }
    return result;
}

Customer query_customer_with_id(int id) {
    /*  do not call this function if you are not certain a customer with this id
    exists.
    // the only legitimate caller of this function is query_parkspot_x
    // there is no error handling in this function
    // for when this function doesn't find the customer with this id !!!!
    */

    SQLite::Statement query(data::db, "SELECT * FROM Customer WHERE id = ?;");
    query.bind(1, id);
    while (query.executeStep()) {
        string name = query.getColumn(1);
        string password = query.getColumn(2);
        int vehicle = query.getColumn(3); // cast to vehicle
        string telephone = query.getColumn(4);
        vector<Park_time> park_instances = query_parktimes_for_customer(id);
        Customer result{id, name, password, Vehicle_type(vehicle), park_instances, telephone};
        // DEBUG
        // cout << "{" << result.id << "," <<result.password <<"," <<
        // int(vehicle) << "}\n";
        return result;
    }
}

//------------------------------- parkspot info

Park_spot query_parkspot_with_id(int id, vector<Park_spot>& parkspots) {
    for (Park_spot& i : parkspots) {
        if (i.id == id) {
            return i;
        }
    }
}

void reports_from_parkspot(int spotid, bool weekly) {
    std::time_t t = std::time(0); // get time now
    std::tm* now = std::localtime(&t);

    if (weekly) {
        now->tm_wday = 1;
    } else {
        now->tm_mday = 1;
    }

    int s_since_epoch = mktime(now);

    vector<Park_time> park_times;
    SQLite::Statement query(data::db, "SELECT * FROM Park_time WHERE spot_id = ? AND start > ?;");
    query.bind(1, spotid);
    query.bind(2, s_since_epoch);
    while (query.executeStep()) {
        int id = query.getColumn(0);
        int cid = query.getColumn(1);
        int start = query.getColumn(3);
        int duration = query.getColumn(5);
        Park_time result{id, cid, spotid, start, duration};
        park_times.push_back(result);
    }
    query.reset();

    for (auto i : park_times) {
        cout << i;
    }
}

void reports_from_allparkspots(bool weekly) {
    std::time_t t = std::time(0); // get time now
    std::tm* now = std::localtime(&t);
    if (weekly) {
        now->tm_wday = 1;
    } else {
        now->tm_mday = 1;
    }

    int s_since_epoch = mktime(now);

    vector<Park_time> park_times;
    SQLite::Statement query(data::db, "SELECT * FROM Park_time WHERE start > ?;");
    query.bind(1, s_since_epoch);
    while (query.executeStep()) {
        int id = query.getColumn(0);
        int cid = query.getColumn(1);
        int spotid = query.getColumn(2);
        int start = query.getColumn(3);
        int duration = query.getColumn(5);
        Park_time result{id, cid, spotid, start, duration};
        park_times.push_back(result);
    }
    query.reset();

    for (auto i : park_times) {
        cout << i;
    }
}

void current_status_parkspots(vector<Park_spot>& spots) {
    for (auto& i : spots) {
        cout << "---------------------------\n";
        cout << "PS #" << i.id << "\n";
        cout << "Taken: " << ((i.taken) ? "true" : "false") << "\n";
        if (i.taken) {
            cout << "Customer#" << i.parked_customer << "  parked there\n";
        }
    }
}

// -------------- paroking spots

// vector<Park_spot> populate_spots(){
//         vector<Park_spot> spots;
//     SQLite::Statement query(data::db, "SELECT * FROM Park_spot WHERE id >
//     0;");
//     // query.bind(1, 2);
//     while (query.executeStep()) {
//         int id = query.getColumn(0);
//         int taken = query.getColumn(1);
//         int cid = query.getColumn(2);
//         // park_customers.push_back(query_customer_with_id(cid));
//         spots.push_back({id, taken, cid});
//     }
//     return spots;
// }