/*
ChiefSoft Works LLC
2017 - Users/Members Management Extension Module
www.chiefsoft.com  
*/


// Topup management toosl
#include "clog.h"
#include "cgi.h"
#include "input.h"
#include "mermsemr_api.h"
#include "safestring.h"
#include <string>
#include "pgsql.h"
#include "pgsql_wrapper.h"
#include <curl/curl.h>
#include "medTEmails.h"
/* -- */

#include "function_users.h"
/*
 kleen=> SELECT * FROM dryclean_service ORDER BY id ASC;
 id | code |    description    | price |           added            
----+------+-------------------+-------+----------------------------
  1 | S01  | Shirt (Laundry)   |   160 | 2018-07-19 09:43:21.379297
  2 | S02  | Shirt (Dry Clean) |   400 | 2018-07-19 09:43:21.383512
  3 | S03  | Shirt (Ladies)    |   400 | 2018-07-19 09:43:21.386951
  4 | S04  | Polo Shirt        |   350 | 2018-07-19 09:43:21.390057
  5 | S05  | Pants             |   400 | 2018-07-19 09:43:21.392852
  6 | S06  | 2 Piece Suit      |   800 | 2018-07-19 09:43:21.395957
  7 | S07  | Blouse            |   500 | 2018-07-19 09:43:21.398769
  8 | S08  | Skirt             |   500 | 2018-07-19 09:43:21.401478
  9 | S09  | Dress             |   600 | 2018-07-19 09:43:21.404238
 10 | S10  | Bedsheets         |  1500 | 2018-07-19 09:43:21.407218
 11 | S11  | Apron             |   350 | 2018-08-10 06:53:05.885366
(11 rows)

 */
long kleenDryCleanList(CVars in, CVars &out) {
    long ret = PHP_API_BAD_PARAM;
    char vname[20];
    try {
        out["total_record"] = "0";

        const PGresult *res = pgsql_query("SELECT * FROM dryclean_service ORDER BY id ASC");
        if (res != NULL && pgsql_num_rows(res) > 0) {
            out["total_record"] = pgsql_num_rows(res);

            for (int i = 0, n = pgsql_num_rows(res); i < n; i++) {
                map<const char*, const char*>f = pgsql_fetch_assoc(res, i);
                if (f.empty()) continue;
                CVars rec;
                map_to_cvars(f, rec);

                snprintf(vname, sizeof (vname), "code_%05d", i);
                out[vname] = rec["code"];

                snprintf(vname, sizeof (vname), "id_%05d", i);
                out[vname] = rec["id"];

                snprintf(vname, sizeof (vname), "description_%05d", i);
                out[vname] = rec["description"];

                snprintf(vname, sizeof (vname), "price_%05d", i);
                out[vname] = rec["price"];

            }
        }
        ret = PHP_API_OK;
        out["status"] = "OK";
    } catch (bad_parameter) {
        logfmt(logINFO, "ERROR CALL long kleenDryCleanList(CVars in, CVars &out)");
    }
    return ret;
}

long passwordReset(CVars in, CVars &out) {
    logfmt(logINFO, "passwordReset()");

    long mode = REQ_LONG(in, "mode", 0, -1);
    switch (mode) {

        case RESET_START:
            return startPassReset(in, out);
            break;

        case RESET_CONFIRM:
            return confirmPassReset(in, out);
            break;


        case RESET_COMPLETE:
            return completePassReset(in, out);
            break;
    }
}


long startPassReset(CVars in, CVars &out) {
    logfmt(logINFO, "startPassReset()");
    long ret = PHP_API_BAD_PARAM;
    CVars x,y;
    try {
        REQ_STRING(in, "username", 2, 49, "(.*)");
        const char * loc = getenv("REMOTE_ADDR");
        ret = load_db_record(out, "SELECT id AS member_id,now() AS reset_seed FROM members WHERE status=1 AND LOWER(username)=LOWER('%s') ", in["username"].c_str());
        if (ret && out["member_id"].Long() > 0) {
            // remove all existing session
            pgsql_exec("UPDATE resetpassword SET status=7 WHERE status NOT IN (3,5) AND member_id=%ld ", out["member_id"].Long());
            // Create New Session Now

            if (load_db_record(y, "SELECT floor( random()*100000) AS reset_pin ,md5('%s') AS reset_key", out["reset_seed"].c_str()) >= 0) {
                x["username"] = in["username"];
                x["member_id"] = out["member_id"];
                x["loc"] = loc;
                x["reset_key"] = y["reset_key"];
                x["reset_pin"] = y["reset_pin"];

                x["username"].set_valid(true);
                x["loc"].set_valid(true);
                x["reset_key"].set_valid(true);
                x["reset_pin"].set_valid(true);
                x["member_id"].set_valid( true );
                
                out["reset_id"] = insert_db_record(DBS_VALID, "resetpassword", "resetpassword_id_seq", x);
                if (out["reset_id"].Long() > 0) {
                    ret = PHP_API_OK;
                    out["reset_key"] = "YOU WILL GET THIS IF PIN IS CORRECT IN CONFIRM"; //x["reset_key"];
                    out["mode"] = RESET_START;
                    member_email_calls(in["action"].Long(), out, x); // note the use of out to send in 
                }
            }
        } else {
            x["username"] = in["username"];
            x["loc"] = loc;
            x["status"] = 3;

            x["username"].set_valid(true);
            x["loc"].set_valid(true);
            x["status"].set_valid(true);
            out["reset_id"] = insert_db_record(DBS_VALID, "resetpassword", "resetpassword_id_seq", x);
            
            out["status_message"] = "Invalid Username or disabled account";
            out["status_advice"] = "Check username or Contact support";
        }
        out["reset_seed="] = "REMOVED";
    } catch (bad_parameter) {
        logfmt(logINFO, "ERROR CALL long startPassReset(CVars in, CVars &out)");
    }

    return ret;
}

long confirmPassReset(CVars in, CVars &out) {
    logfmt(logINFO, "confirmPassReset()");
    long ret = PHP_API_BAD_PARAM;
    CVars x, y;
    try {
        REQ_STRING(in, "username", 2, 49, "(.*)");
        REQ_LONG(in, "reset_pin", 0, -1);
        const char * loc = getenv("REMOTE_ADDR");

        ret = load_db_record(out, "SELECT * FROM resetpassword WHERE status=1 AND LOWER(username)=LOWER('%s') AND reset_pin=%lu AND loc='%s'", in["username"].c_str(), in["reset_pin"].Long(), loc);
        if (ret && out["id"].Long() > 0) {
            ret = PHP_API_OK;
        } else {
            out["status_message"] = "Invalid PIN  or disabled account";
            out["status_advice"] = "Contact support or Start all over";
        }
        //  out["reset_seed="] = "REMOVED";
    } catch (bad_parameter) {
        logfmt(logINFO, "ERROR CALL long confirmPassReset(CVars in, CVars &out)");
    }
    return ret;
}

long completePassReset(CVars in, CVars &out) {
    logfmt(logINFO, "completePassReset()");
    long ret = PHP_API_BAD_PARAM;
    CVars x, y;
    try {
        REQ_STRING(in, "username", 2, 49, "(.*)");
        REQ_STRING(in, "newpassword", 2, 15, "(.*)");
        REQ_LONG(in, "reset_pin", 0, -1);
        const char * loc = getenv("REMOTE_ADDR");

        ret = load_db_record(out, "SELECT *,id AS reset_id FROM resetpassword WHERE status=1 AND LOWER(username)=LOWER('%s') AND reset_pin=%lu AND loc='%s' AND reset_key='%s'", in["username"].c_str(), in["reset_pin"].Long(), loc, in["reset_key"].c_str());
        if (ret && out["reset_id"].Long() > 0) {


            if (pgsql_query("UPDATE members SET password=md5('%s') WHERE id =%lu", in["newpassword"].c_str(), out["member_id"].Long()) >= 0) {
                pgsql_query("UPDATE resetpassword SET status = 5,reset_key=NULL WHERE id =%lu", out["reset_id"].Long());
                ret = PHP_API_OK;
            }


            out["reset_key"] = "YOU WILL GET THIS IF PIN IS CORRECT IN CONFIRM"; //x["reset_key"];
            out["mode"] = RESET_COMPLETE;
            member_email_calls(in["action"].Long(), out, x); // note the use of out to send in 


        } else {
            out["status_message"] = "Invalid call  or disabled account";
            out["status_advice"] = "Contact Support";
        }
        //  out["reset_seed="] = "REMOVED";
    } catch (bad_parameter) {
        logfmt(logINFO, "ERROR CALL long confirmPassReset(CVars in, CVars &out)");
    }
    return ret;
}

long DstartPassReset(CVars in, CVars &out) {
    logfmt(logINFO, "startPassReset()");
    return 0;
}

long DconfirmPassReset(CVars in, CVars &out) {
    logfmt(logINFO, "confirmPassReset()");
    return 0;
}

long DcompletePassReset(CVars in, CVars &out) {
    logfmt(logINFO, "completePassReset()");
    return 0;
}

long manageUserCCList(CVars in, CVars &out) {
    logfmt(logINFO, "manageUserCCList()");



    return 0;
}

/*
 
 utransport=> SELECT * FROM creditcard LIMIT 10 ;
 id | member_id | type | digits | cvv2 | attempts | sha1 | firstname | lastname  |       street1        | street2 |   city   | state | postal | country | status | active |           added_dt            | description |        stripe_card_id         | expiration_month | expiration_year 
----+-----------+------+--------+------+----------+------+-----------+-----------+----------------------+---------+----------+-------+--------+---------+--------+--------+-------------------------------+-------------+-------------------------------+------------------+-----------------
  1 |      2588 |    0 | 4242   |      |        3 |      |           |           |                      |         |          |       |        |         |      3 |      1 | 2017-11-23 01:58:06.516697-05 | Visa        | card_1BREevF5FERRcWDywupMIc0F |               12 |            2018
  2 |      2589 |    0 | 4242   |      |        3 |      | Chiedozie | Charles   | 935 Merryweather Dr. |         | Austell  | GA    | 30106  | US      |      3 |      1 | 2017-11-23 02:22:44.008819-05 | Visa        | card_1BRF2kF5FERRcWDypw0Hqc9q |               12 |            2018
  3 |       674 |    0 | 4242   |      |        3 |      | rodriguez | marylynne | 1426 Mandalay Court  |         | Lilburn  | GA    | 30047  | US      |      3 |      1 | 2017-11-23 06:50:09.836866-05 | Visa        | card_1BRJDYF5FERRcWDyqqo7pQc4 |               12 |            2018
  4 |       639 |    0 | 4242   |      |        3 |      | Gbadehan  | Adebayo   | 356 Holbrook Road    |         | Smyrna   | GA    | 30082  | US      |      3 |      1 | 2017-11-23 07:15:37.774145-05 | Visa        | card_1BRJcCF5FERRcWDyaiCdMwZA |               12 |            2018
  5 |       765 |    0 | 4242   |      |        3 |      | de vries  | chris     | 741 Crestwell Circle |         | Atlanta  | GA    | 30331  | US      |      3 |      1 | 2017-11-23 12:15:11.514433-05 | Visa        | card_1BROI6F5FERRcWDyfpRUXoza |               12 |            2018
  6 |       765 |    0 | 4242   |      |        3 |      | de vries  | chris     | 741 Crestwell Circle |         | Atlanta  | GA    | 30331  | US      |      3 |      1 | 2017-11-23 12:16:24.561285-05 | Visa        | card_1BROJHF5FERRcWDytk2IvLnq |               12 |            2018
  7 |      1942 |    0 | 4242   |      |        3 |      | Chevalier | Reynault  | 1438 Mclendon drive  |         | Decatur  | GA    | 30033  | US      |      3 |      1 | 2017-11-24 01:59:38.679594-05 | Visa        | card_1BRb9xF5FERRcWDyj3EXBSxQ |               12 |            2018
  8 |      2404 |    0 | 4242   |      |        3 |      | turiano   | james     | 3907 Amicalola Pass  |         | Marietta | GA    | 30062  | US      |      3 |      1 | 2017-11-25 22:25:48.909543-05 | Visa        | card_1BSGm7F5FERRcWDyZ6F4B6qS |               12 |            2018
  9 |      2404 |    0 | 4242   |      |        3 |      | turiano   | james     | 3907 Amicalola Pass  |         | Marietta | GA    | 30062  | US      |      3 |      1 | 2017-11-26 22:19:28.49225-05  | Visa        | card_1BSd9XF5FERRcWDy8YbQA2me |               12 |            2018
 10 |      2404 |    0 | 4242   |      |        3 |      | turiano   | james     | 3907 Amicalola Pass  |         | Marietta | GA    | 30062  | US      |      3 |      1 | 2017-11-26 22:25:00.447243-05 | Visa        | card_1BSdEtF5FERRcWDyohmt90nI |               12 |            2018
(10 rows)

utransport=> 

 */
long userDeleteCard(CVars in, CVars &out) {
    logfmt(FLOG_MAX, "long userDeleteCard(CVars in, CVars &out)");
    long ret = PHP_API_BAD_PARAM;

    REQ_LONG(in, "member_id", 0, -1);
    REQ_STRING(in, "sessionid", 2, 100, "(.*)");
    REQ_LONG(in, "paymentid", 0, -1);

    long ret2 = load_db_record(out, "SELECT *,id AS card_id FROM creditcard "
            " WHERE member_id = %lu "
            " AND id = %lu  AND status  =  3", in["member_id"].Long(), in["paymentid"].Long());
    if (ret && out["card_id"].Long() > 0) {

       if (   pgsql_query("UPDATE creditcard SET status = 7 WHERE status =3 AND member_id =%lu AND id = %lu",in["member_id"].Long(), in["paymentid"].Long())>=0 )
       {
           ret = 100;           
       }

    }
    out["delete_status"] = ret;
    
    return ret;
    logfmt(FLOG_MAX, "/long userDeleteCard(CVars in, CVars &out)");
}


long getUserCCList(CVars in, CVars &out) {

    logfmt(FLOG_MAX, "long getUserCCList(CVars in, CVars &out)");
    long ret = PHP_API_BAD_PARAM;
    char vname[30];
    try {
        REQ_LONG(in, "limit", 0, -1);
        REQ_LONG(in, "member_id", 0, -1);

        out["total_record"] = "0";

        const PGresult *res = pgsql_query("SELECT * FROM creditcard "
        " WHERE member_id= %lu AND stripe_card_id IS NOT NULL AND status<>7 "
        " ORDER BY id DESC LIMIT %lu", in["member_id"].Long(), in["limit"].Long());
        
        if (res != NULL && pgsql_num_rows(res) > 0) {
            out["total_record"] = pgsql_num_rows(res);

            for (int i = 0, n = pgsql_num_rows(res); i < n; i++) {
                map<const char*, const char*>f = pgsql_fetch_assoc(res, i);
                if (f.empty()) continue;
                CVars rec;
                map_to_cvars(f, rec);

                snprintf(vname, sizeof (vname), "description_%05d", i);
                out[vname] = rec["description"];

                snprintf(vname, sizeof (vname), "digits_%05d", i);
                out[vname] = rec["digits"];
                snprintf(vname, sizeof (vname), "expiration_month_%05d", i);
                out[vname] = rec["expiration_month"];

                snprintf(vname, sizeof (vname), "expiration_year_%05d", i);
                out[vname] = rec["expiration_year"];
                
                
                snprintf(vname, sizeof (vname), "paymentid_%05d", i);
                out[vname] = rec["id"];


                            
               
            }
        }
        ret = PHP_API_OK;
        out["status"] = "OK";
    } catch (bad_parameter) {
        logfmt(logINFO, "ERROR CALL long getUserCCList(CVars in, CVars &out)");
    }
    logfmt(FLOG_MAX, "/long getUserCCList(CVars in, CVars &out)");
    return ret;
    

    return 0;
}
