
#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_invoice.h"
#include "function_driver.h"
#include "function_agents.h"
#include "medTrTransporter.h"

long medTranportBillables(CVars in, CVars &out);
long medTSaveInvloiceItem(CVars in);
long medTrGetMemberInvoice(CVars in, CVars &out) {
    CVars x,n,z;
    logfmt(logINFO, "START CALL long medTrGetMemberInvoice(CVars in, CVars &out)");
    try {

        //REQ_STRING(in, "sessionid", 15, 99, "(.*)");
        long request_id = 0;
        long member_id = 0;
        long transport = 0;
        long translate = 0;
        long hoursneeded = 0;
        long miles = 0;
        long invoice_mode = REQ_LONG(in, "invoice_mode", 0, -1);
        CVars p;
        CVars lt;
        long profile_multiple = 1;
        long totalv = 0;
        long extra_intr = 0;
        lt["transport"] = "0";
        lt["translate"] = "0";
        lt["concierge"] = "0";
        lt["transp_type"] = "0";
         
        if (invoice_mode == INVOICE_FINAL) {
            
            
            request_id = REQ_LONG(in, "request_id", 0, -1);
            member_id = REQ_LONG(in, "member_id", 0, -1);

            if (load_db_record(z, "SELECT t.bill_mutiple AS profile_multiple FROM members m LEFT JOIN members_acc_types t ON t.id=m.acc_type WHERE m.id = %lu", member_id)) {
                profile_multiple = z["profile_multiple"].Long();
                logfmt(logINFO, "-------------------==================-------- Profile Multiple =%lu", profile_multiple);
            } else {
                logfmt(logINFO, "ERROR CALL long medTrGetMemberInvoice(CVars in, CVars &out) -> Invalid user");
                return 0;
            }
            
         /*   if (load_db_record(x, "SELECT *,id AS transport_id, TO_CHAR(transport_date :: DATE, 'Day Mon dd, yyyy') AS report_day,"
                    " (CASE WHEN LOWER (TO_CHAR(transport_date :: DATE, 'Day'))::TEXT LIKE'%saturday%' THEN 100 "
                    " WHEN  LOWER (TO_CHAR(transport_date :: DATE, 'Day'))::TEXT LIKE'%sunday%' THEN 200  ELSE 0 END) AS day_handle "
                    "  FROM members_transport_request WHERE id = %lu", request_id)) 
            
          */
          
            if (load_db_record(x, "SELECT *,id AS transport_id, TO_CHAR(transport_date :: DATE, 'Day Mon dd, yyyy') AS report_day, LOWER (TO_CHAR(transport_date::DATE, 'Day')) AS day_name  "
                    "  FROM members_transport_request WHERE id = %lu", request_id)){
            
                load_db_record(n, "SELECT TO_CHAR('%s' :: DATE, 'Day Mon dd, yyyy') AS report_day", x["transport_date"].c_str());
                logfmt(logINFO, "*********medTrGetMemberInvoice = %s ", n["report_day"].c_str());
                
                CVars y;
                y["member_id"] = x["member_id"]; y["member_id"].set_valid( true );
                y["transport_id"] = x["transport_id"]; y["transport_id"].set_valid( true );   
                y["transp_type"] = "0"; y["transp_type"].set_valid( true );   
                out["invoice_id"] = insert_db_record(DBS_VALID, "members_invoice", "members_invoice_id_seq", y);
                
                 pgsql_query("UPDATE members_invoice SET flags = 3  WHERE flags <> 3 AND transport_id = %lu AND id  <> %lu", y["transport_id"].Long(), out["invoice_id"].Long());
                //--------------------------------------------------------------------------------------------

                if (x["transport"].Long() == 1 && x["miles"].Long() > 0) {

                     lt["transp_type"] = "1";                    
                    in["type_key"] = "T001"; // this is a variable
                    if (x["needwheelchair"].Long() == 1) {
                        in["type_key"] = "T002"; // this is a variable
                        lt["transp_type"] = "2";
                    }

                    if (x["stretcherneeded"].Long() == 1) {
                        in["type_key"] = "T003"; // this is a variable
                        lt["transp_type"] = "3";
                    }
                    in["type_key"].set_valid( true );
                     
                    load_db_record(p, "SELECT * FROM pricing_member_transport WHERE status=1 AND type_key='%s' ORDER BY id DESC LIMIT 1",in["type_key"].c_str()); // get transport profile
                    medTranportBillables(in, out);
                   //BASIC TRANSPORT
                    CVars z1;
                    z1["description"] = out["transp_basic"]; z1["description"].set_valid( true );
                    z1["g_key"] = "T"; z1["g_key"].set_valid( true );
                    z1["i_key"] = "T0001"; z1["i_key"].set_valid( true );
                    z1["invoice_id"] = out["invoice_id"]; z1["invoice_id"].set_valid( true );
                    z1["qty"] = "1"; z1["qty"].set_valid( true );
                    z1["total"] = profile_multiple*p["start_price"];  z1["total"].set_valid( true );
                    medTSaveInvloiceItem(z1);

                    if (p["miles"].Long() < x["miles"].Long()) {
                        totalv = profile_multiple*p["extra_price"].Long()*(x["miles"].Long() - p["miles"].Long());
                        out["extra_price"] = totalv;
            
                        CVars z2;
                        z2["description"] = out["transp_extra"]; z2["description"].set_valid( true );
                        z2["g_key"] = "T"; z2["g_key"].set_valid( true );
                        z2["i_key"] = "T0002"; z2["i_key"].set_valid( true );
                        z2["invoice_id"] = out["invoice_id"]; z2["invoice_id"].set_valid( true );
                        z2["qty"] = "1"; z2["qty"].set_valid( true );
                        z2["total"] = totalv;  z2["total"].set_valid( true );
                         medTSaveInvloiceItem(z2);
                                             
                        
                    }
                    long saturnday_charge=0;
                    if (x["day_name"] == "saturday") {
                        saturnday_charge = (profile_multiple * p["start_price"].Long() + totalv) *0.25;
                        CVars z3;
                        z3["description"] = "Transport Saturday Surcharge";
                        z3["description"].set_valid(true);
                        z3["g_key"] = "T";
                        z3["g_key"].set_valid(true);
                        z3["i_key"] = "T0003";
                        z3["i_key"].set_valid(true);
                        z3["invoice_id"] = out["invoice_id"];
                        z3["invoice_id"].set_valid(true);
                        z3["qty"] = "1";
                        z3["qty"].set_valid(true);
                        z3["total"] = saturnday_charge;
                        z3["total"].set_valid(true);
                        medTSaveInvloiceItem(z3);
                    }

                    if (x["day_name"] == "sunday") {

                    }
                   
                   
                    lt["transport"] =  profile_multiple*p["start_price"].Long() +  totalv + saturnday_charge;
                }
                
                 //trnaslate
                if (x["translate"].Long() == 1 && x["hoursneeded"].Long() > 0) {    
                    CVars pi;
                   load_db_record(pi, "SELECT * FROM pricing_member_translator WHERE status=1 ORDER BY id DESC LIMIT 1"); // get transport profile
                    /*
                        utransport=> select * from pricing_member_translator order by id desc limit 1;
                        id |           added            | pricing | hours | start_price | extra_price | status 
                        ----+----------------------------+---------+-------+-------------+-------------+--------
                        3 | 2017-12-28 17:29:58.340197 |       1 |     2 |        5000 |        2500 |      1
                        (1 row)

                     */
                    
                        CVars z10;
                        z10["description"] = "Interpretation Service"; z10["description"].set_valid( true );
                        z10["g_key"] = "I"; z10["g_key"].set_valid( true );
                        z10["i_key"] = "I0002"; z10["i_key"].set_valid( true );
                        z10["invoice_id"] = out["invoice_id"]; z10["invoice_id"].set_valid( true );
                        z10["qty"] = "1"; z10["qty"].set_valid( true );
                        z10["total"] = profile_multiple*pi["start_price"];  z10["total"].set_valid( true );
                        medTSaveInvloiceItem(z10);
                         
                        if ( x["hoursneeded"].Long()  > pi["hours"].Long())
                        {
                            extra_intr  = profile_multiple* ( x["hoursneeded"].Long()  - pi["hours"].Long()) * pi["extra_price"].Long();
                            CVars z11;
                            z11["description"] = "Extra hours Interpretation Service"; z11["description"].set_valid( true );
                            z11["g_key"] = "I"; z11["g_key"].set_valid( true );
                            z11["i_key"] = "I0002"; z11["i_key"].set_valid( true );
                            z11["invoice_id"] = out["invoice_id"]; z11["invoice_id"].set_valid( true );
                            z11["qty"] = "1"; z11["qty"].set_valid( true );
                            z11["total"] = extra_intr; /* pi["extra_price"]; */  z11["total"].set_valid( true );
                            medTSaveInvloiceItem(z11);
                            
                        }
                         
                   lt["translate"] =  profile_multiple*pi["start_price"].Long() +  extra_intr;
                }
                
                
                  //concierge
                if (x["conciergeneeded"].Long() == 1 && x["hoursneeded"].Long() > 0) {    
                    CVars p2;
                     load_db_record(p2, "SELECT * FROM pricing_member_concierge WHERE status=1 ORDER BY id DESC LIMIT 1"); // get transport profile
                     /*            
                        utransport=> SELECT * FROM pricing_member_concierge WHERE status=1 ORDER BY id DESC LIMIT 1;
                         id |           added            | pricing | hours | start_price | extra_price | status | dead_mile | wait_hour 
                        ----+----------------------------+---------+-------+-------------+-------------+--------+-----------+-----------
                          3 | 2017-12-28 17:29:32.944421 |       1 |     2 |       15000 |       10000 |      1 |       200 |        21
                        (1 row)
                        */
                    
                        CVars z20;
                        z20["description"] = "Basic Concierge Service"; z20["description"].set_valid( true );
                        z20["g_key"] = "C"; z20["g_key"].set_valid( true );
                        z20["i_key"] = "C0001"; z20["i_key"].set_valid( true );
                        z20["invoice_id"] = out["invoice_id"]; z20["invoice_id"].set_valid( true );
                        z20["qty"] = "1"; z20["qty"].set_valid( true );
                        z20["total"] = profile_multiple*p2["start_price"];  z20["total"].set_valid( true );
                        medTSaveInvloiceItem(z20);
                    
                        lt["concierge"] =  profile_multiple*p2["start_price"].Long();
                }
                 


                lt["transport"].set_valid(true);
                lt["translate"].set_valid(true);
                lt["concierge"].set_valid(true);
                update_db_record(DBS_VALID, "members_invoice", lt, out["invoice_id"]);
                
                //--------------------------------------------------------------------------------------------               
            }

        } else {
            transport = REQ_LONG(in, "transport", 0, -1);
            translate = REQ_LONG(in, "translate", 0, -1);
            hoursneeded = REQ_LONG(in, "hoursneeded", 0, -1);
            miles = REQ_LONG(in, "miles", 0, -1);
            REQ_STRING(in, "appt_time", 5, 25, "(.*)");
        }
        

                
        /*        
        load_db_record(x, "SELECT * FROM pricing_member_transport WHERE status=1 ORDER BY id DESC LIMIT 1");

        
        out["start_price"] = x["start_price"];
        out["miles"] = x["miles"];
        out["extra_price"] = "0";
        if ( x["miles"].Long() < in["miles"].Long())
        {
               long totalv = x["miles"].Long()*( in["miles"].Long() - x["miles"].Long()  );
               out["extra_price"] = totalv;
        }
        
        out["total_price"] = out["start_price"].Long() +  out["extra_price"].Long() ;
        in["type_key"] = "T001";
        medTranportBillables(in, out);

         * 
         * 
         * 
         * 
Basic Ambulatory Transport
Extra Ambulatory Transport Miles
Same Day Transport Surcharge 
Rush Hour Transport Surcharge 
Evening Transport Surcharge 
Saturday Transport Surcharge 
Holidays/Sundays Transport Surcharge 
Driver Callback Surcharge


Basic Wheelchair Transport
Extra Wheelchair Transport Miles
Same Day Request Surcharge 
Rush Hour Transport Surcharge 
Evening Transport Surcharge 
Saturday Transport Surcharge
Holidays/Sundays Transport Surcharge 
Driver Callback Surcharge


Basic Stretcher Transport
Extra Stretcher Transport Miles
Same Day Request Surcharge 
Rush Hour Transport Surcharge 
Evening Transport Surcharge 
Saturday Transport Surcharge
Holidays/Sundays Transport Surcharge 
Driver Callback Surcharge

Basic Concierge Service
Wait Hour Concierge 

Interpretation Service
Extra hours Interpretation Service

          "sessionid" => $sessionid,
            "member_id" => $member_id,
            "request_id" => "0",
            "invoice_mode" => INVOICE_PREVIEW,
            "transport" => "1",
            "translate" => "0",
            "hoursneeded" => "0",
            "miles" => $miles,
            "appt_time" => $picktime
         */


    } catch (bad_parameter) {
        logfmt(logINFO, "ERROR CALL long medTrGetMemberInvoice(CVars in, CVars &out)");
    }
    return 0;
}


long medTSaveInvloiceItem(CVars in)
{
    
    return insert_db_record(DBS_VALID, "members_invoice_detail", "members_invoice_detail_id_seq", in);
    
}

long getMemberInvoiceID(long transport_id) {
    long ret = 0;
    CVars x,out;
    if (load_db_record(x, "SELECT member_id,id AS request_id FROM members_transport_request WHERE id  = %lu", transport_id)) {
        x["invoice_mode"] = INVOICE_FINAL;
        medTrGetMemberInvoice(x, out);
        ret = out["invoice_id"].Long();
    }
    return ret;
}

long medTSendInvoice(CVars in, CVars &out) {
    CVars x;
    long invoice_id = REQ_LONG(in, "invoice_id", 0, -1);

    if (load_db_record(x, "SELECT *,id AS invoice_id FROM members_invoice WHERE id =%lu", invoice_id)) {
        member_email_calls(MEDTRANS_USER_SENDINVOICE, x, out);
        out["status"] ="Email Sent";
    }

    return 0;
}


long medTrInvoice(CVars in, CVars &out) {

    logfmt(logINFO, "****** ~~~~  medTrInvoice(CVars in, CVars &out)");

    long transport_id = REQ_LONG(in, "transport_id", 0, -1);
    long invoice_id = getMemberInvoiceID(transport_id);
    out["total_record"] = "0";
    const PGresult *res;
    char vname[30];

    if (load_db_record(out, "SELECT id AS invoice_id, transport AS transport_total, translate AS translate_total,concierge AS concierge_total,dt_paid, confirmation FROM members_invoice WHERE id = %lu AND flags<> 3 ", invoice_id)) {
        //   x["invoice_mode"] = INVOICE_FINAL;
        //    medTrGetMemberInvoice(x, out);
        //    ret = out["invoice_id"].Long();


        res = pgsql_query("SELECT * FROM  members_invoice_detail WHERE invoice_id  = %lu ORDER BY id ASC", out["invoice_id"].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), "g_key_%05d", i);
                out[vname] = rec["g_key"];

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

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

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

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

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

                snprintf(vname, sizeof (vname), "detail_id_%05d", i);
                out[vname] = rec["id"];
            }
        }
    }
    return 0;

}
/*
  g_key       | character varying(2)        | 
 i_key       | character varying(5)        | 
 description | character varying(50)       | 
 rates       | integer                     | default 0
 qty         | integer                     | default 0
 total       | integer                     | default 0
 status      | integer                     | default 1

 */
long medTranportBillables(CVars in, CVars &out) {

    REQ_STRING(in, "type_key", 2, 5, "(.*)");
    CVars x;
    char vname[60];
    /*
      type_key | type_name  
----------+------------
 T001     | Ambulatory
 T002     | Wheelchair
 T003     | Stretcher
     * 
     * 
     * Basic Ambulatory Transport
Extra Ambulatory Transport Miles
Same Day Transport Surcharge 
Rush Hour Transport Surcharge 
Evening Transport Surcharge 
Saturday Transport Surcharge 
Holidays/Sundays Transport Surcharge 
Driver Callback Surcharge
     */
    if (load_db_record(x, "SELECT * FROM transport_types WHERE type_key='%s'", in["type_key"].c_str())) {

        snprintf(vname, sizeof (vname), "Basic %s Transport", x["type_name"].c_str());
        out["transp_basic"] = vname;

        snprintf(vname, sizeof (vname), "Extra %s Transport", x["type_name"].c_str());
        out["transp_extra"] = vname;

        snprintf(vname, sizeof (vname), "Same Day Transport Surcharge");
        out["same_day"] = vname;

        snprintf(vname, sizeof (vname), "Rush Hour Transport Surcharge");
        out["rush_hour"] = vname;

        snprintf(vname, sizeof (vname), "Evening Transport Surcharge");
        out["evening_charges"] = vname;

        snprintf(vname, sizeof (vname), "Saturday Transport Surcharge");
        out["saturday"] = vname;

        snprintf(vname, sizeof (vname), "Holidays/Sundays Transport Surcharge");
        out["holiday"] = vname;

        snprintf(vname, sizeof (vname), "Driver Callback Surcharge");
        out["callback"] = vname;

    }
    return 0;

}



long medTrGetTransportInvoice(CVars in, CVars &out) {
    long ret = PHP_API_BAD_PARAM;
    logfmt(logINFO, "long medTrGetTransportInvoice(CVars in, CVars &out)");
    try {

        out["invoice_no"] = "INV007";
        out["total"] = 12345;
        out["responsible_name"] = "RealClient Name";
        out["dateof_service"] = "December 12, 2017";

        out["patient_name"] = "Patient Name";
          out["patient_phone"] = "911 000 0000";
        out["patient_from"] = "<li> Normand axis LTD</li> <li>3 Goodman Street </li><li> marietta, GA 30127</li>";

        out["patient_to"] = "<li><b> Destination</b></li> <li>56 marietta Street </li><li> Atlanta, GA 30339</li>";




    } catch (bad_parameter) {
        logfmt(logINFO, "ERROR CALL long medTrGetTransportInvoice(CVars in, CVars &out)");
    }
    logfmt(logINFO, "/long medTrGetTransportInvoice(CVars in, CVars &out)");
    return ret;
}

long medTrInvoiceFunctions(CVars in, CVars &out) {
    long ret = PHP_API_BAD_PARAM;

    try {








    } catch (bad_parameter) {
        logfmt(logINFO, "ERROR CALL long medTrInvoiceFunctions(CVars in, CVars &out)");
    }
    return ret;
}

long generateInvoiceData(CVars in, CVars &out) // most probably ran by cron job
{
    const PGresult *res;
    res = pgsql_query("SELECT id FROM members_transport_request WHERE miles > 0  order by id desc"); // condition for invloice listing 

    if (res != NULL && pgsql_num_rows(res) > 0) {
        for (int i = 0, n = pgsql_num_rows(res); i < n; i++) {


        }
    }
    return 0;
}
