// Account management toosl
#include "clog.h"
#include "cgi.h"
#include "input.h"
#include "wrenchboard_api.h"
#include "contract.h"
#include "email.h"
#include "payments.h"
#include "safestring.h"
#include <string>
#include "pgsql.h"
#include "pgsql_wrapper.h"
#include "cfg.h"
#include <curl/curl.h>



long contract_calls(CVars in, CVars &out)
{
	logfmt( logINFO, "contract_calls()" );
	out["result"] = "YES I GET TO BACK END";
    long action = REQ_LONG( in, "action", 0, -1);
	switch( action )
    { 		
		case WRENCHBOARD_CONTRACT_MESSAGE:
			return WrenchContractMessage( in, out);		
		break;

		case WRENCHBOARD_CONTRACT_STATUS:
			return WrenchContractStatus( in, out);		
		break;			

        case WRENCHBOARD_CONTRACT_MSGLIST:
            return WrenchContractMessageList( in, out);
        break;
   }
	logfmt( logINFO, "/contract_calls()" );
	return 0;
}


long  WrenchContractStatus( CVars in, CVars &out )
{
	long ret = -1;
	logfmt( logINFO, "WrenchContractStatus()" );
	REQ_LONG( in, "member_id", 1, -1 );
	REQ_STRING (in, "contract",   7, 25, "(.*)");
	REQ_STRING (in, "contract_uid",   7, 125, "(.*)");
	//REQ_LONG( in, "job_id", 1, -1 );
	long job_action = REQ_LONG( in, "job_action", 1, -1 );
	out["result"] = "Yes i go to this back end";
	long extension = 0;
	CVars xy;
    logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() job_action == %lu", job_action);

        long retF = load_db_record( out, "SELECT id AS contract_id FROM members_jobs_contract WHERE contract='%s' AND uid = '%s'",in["contract"].c_str(),in["contract_uid"].c_str());
        if (retF){
             if ( out["contract_id"].Long() >   0 ){
              logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() ID  found =%lu", out["contract_id"].Long());
            }
            else{
              logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() ID not found 001" );
            return ret;
            }
        }
        else{
              logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() ID not found 002" );
            return ret;
        }
	/*
	'uid' => '3119b744-42ad-4834-bb83-b737588754ca',
    'contract' => 'X2Y9WR5632',
    'contract_uid' => '10654dc5-f574-4aa6-b8e6-93b95ac5fcec',
    'job_action' => ‘ACCEPT_COMPLETE’,

	*/
	in["contract_id"] = out["contract_id"]; in["contract_id"].set_valid( true ); // the email system uses contract_id
	in["job_contract"] = in["contract"];    in["job_contract"].set_valid( true );
	
	switch( job_action )
    { 
	  case CONTRACT_NOTIFY_COMPLETE:
	  	  logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() CONTRACT_NOTIFY_COMPLETE" );
		  ret = load_db_record( out, "SELECT id AS jobs_contract_id, * FROM members_jobs_contract WHERE status IN (1,2)  "
		                              " AND contract='%s' AND id=%lu AND client_id =%lu",in["job_contract"].c_str(),in["contract_id"].Long(),in["member_id"].Long() );
		  logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() ret 1 = %lu",ret );
		  if (ret)
		  {
		       if ( out["jobs_contract_id"].Long() >   0 ){
                      pgsql_exec("UPDATE members_jobs_contract SET status = %lu,updated=now() WHERE id = %lu",CONTRACT_NOTIFY_COMPLETE, in["contract_id"].Long() );

                      if ( load_db_record( out, "SELECT * FROM members_jobs_contract "
                                                " WHERE status = %lu  AND id=%lu AND client_id =%lu",CONTRACT_NOTIFY_COMPLETE,in["contract_id"].Long(),in["member_id"].Long() ) )
                      {
                           project_email(CONTRACT_NOTIFY_COMPLETE, in, out);
                           out["result"] = "We have notify the task owner of your completion. Expect a response soon";
                      }
		       }
		  }
	  break;
	  
	  case CONTRACT_REQUEST_CANCEL:
	  	  logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() CONTRACT_REQUEST_CANCEL" );
		  ret = load_db_record( out, "SELECT  id AS jobs_contract_id,* FROM members_jobs_contract WHERE status IN (1,2)  "
		                             " AND contract='%s' AND id=%lu AND client_id =%lu",in["job_contract"].c_str(),in["contract_id"].Long(),in["member_id"].Long() );
		  logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() ret 1 = %lu",ret );
		  if (ret)
		  {
              if ( out["jobs_contract_id"].Long() >   0 ){
                    logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() CONTRACT_REQUEST_CANCEL****************");
                    logfmt( logINFO, "~~~~ ~~~~ WrenchContractStatus() REFUND THE ESCROW_CANCEL****************");
                    logfmt( logINFO, "~~~~ ~~~~ WrenchContractStatus() REFUND THE ESCROW_CANCEL****************");
                    logfmt( logINFO, "~~~~ ~~~~ WrenchContractStatus() REFUND THE ESCROW_CANCEL****************");
                    logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() CONTRACT_REQUEST_CANCEL****************");
                      pgsql_exec("UPDATE members_jobs_contract SET status = %lu,updated=now() "
                                 " WHERE id = %lu",CONTRACT_REQUEST_CANCEL, out["jobs_contract_id"].Long() );
                      if ( load_db_record( out, "SELECT * FROM members_jobs_contract WHERE status = %lu  "
                                                " AND id=%lu AND client_id =%lu",CONTRACT_REQUEST_CANCEL,in["contract_id"].Long(),in["member_id"].Long() )>0 )
                      {
                           project_email(CONTRACT_REQUEST_CANCEL, in, out);
                           out["result"] = "We have notify the task owner of your request for cancellation.";
                      }
              }

		  }	  
	  break;
	  
	  case CONTRACT_ACCEPT_COMPLETE:
	      logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() ::  :: :: CONTRACT_ACCEPT_COMPLETE" );
	  	  //logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() CONTRACT_ACCEPT_COMPLETE" );
		  ret = load_db_record( out, "SELECT *, id AS contract_id FROM members_jobs_contract WHERE status = %lu AND contract='%s' AND id=%lu "
		  " AND member_id =%lu",CONTRACT_NOTIFY_COMPLETE,in["job_contract"].c_str(),in["contract_id"].Long(),in["member_id"].Long() );
		  logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() ret 1 = %lu",ret );
		  if (ret && out["contract_id"].Long()  > 0 )
		  {
				  pgsql_exec("UPDATE members_jobs_contract SET status = %lu,updated=now() WHERE id = %lu",CONTRACT_ACCEPT_COMPLETE, out["contract_id"].Long() );
				// make sure the update was done 
				  if ( load_db_record( out, "SELECT * FROM members_jobs_contract WHERE status = %lu  AND id=%lu "
				  " AND member_id =%lu",CONTRACT_ACCEPT_COMPLETE,in["contract_id"].Long(),in["member_id"].Long() ) > 0 )
				  {
				    //let us do the accounting parts here now
					CVars y;
					y["member_id"] = in["member_id"]; // note we are actually paying the client_id
					y["contract_id"] = out["contract_id"];
					y["code"] = "COPAY";
					y["dir"] = DIR_TARGET;
					if (  WrenchContractPayment(y,out) == PHP_CREATED_OK )
					{ // if you reserve pauments
						//char offer_code[15] = "";
						//GetOfferCode(offer_id, offer_code, sizeof (offer_code)); // this stamp the offer code directly in that call	
						pgsql_exec("UPDATE members_jobs_contract SET updated = now(),payment_date=now()  WHERE id = %lu",out["contract_id"].Long());
					}
					else
					{
						out["error_msg"] ="valid_contract_not_found";
					}
					//----------------------------------------
					  
				   project_email(CONTRACT_ACCEPT_COMPLETE, in, out);  //USES in["contract_id"]
				   out["result"] = "This task is now complete. We have notified all parties accordingly";
				  }
		  }
	  break;
	  case CONTRACT_REJECT_COMPLETE:
	  	  logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() CONTRACT_REJECT_COMPLETE" );
	  	  ret = load_db_record( out, "SELECT * FROM members_jobs_contract WHERE status = %lu AND contract='%s' AND id=%lu AND member_id =%lu",CONTRACT_NOTIFY_COMPLETE,in["job_contract"].c_str(),in["contract_id"].Long(),in["member_id"].Long() );
		  logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() ret 1 = %lu",ret );
		  if (ret)
		  {
				  pgsql_exec("UPDATE members_jobs_contract SET status = %lu,updated=now() WHERE id = %lu",CONTRACT_REJECT_COMPLETE, in["contract_id"].Long() );
				// make sure the update was done 
				  if ( load_db_record( out, "SELECT * FROM members_jobs_contract WHERE status = %lu  AND id=%lu AND member_id =%lu",CONTRACT_REJECT_COMPLETE,in["contract_id"].Long(),in["member_id"].Long() ) )
				  {
				   project_email(CONTRACT_REJECT_COMPLETE, in, out);
				   out["result"] = "You have rejected that this task is complete. We have notified all parties accordingly";
				  }
		  }
	  break;  

	  case CONTRACT_REQUEST_TIMELINE:
            /*
            {
                "uid": "3119b744-42ad-4834-bb83-b737588754ca",
                "member_id": "1",
                "sessionid": "38E1B8E88F0A1F029C390FCBC63573C1E71566C1C1FB586203B6F2D9E2440BDB",
                "action": 14015,
                "contract": "8R0B101BRW",
                "contract_uid": "a12cf3b6-391e-4003-803d-799128d528a4",
                "job_action": "NOTIFY_REQEXTENT"
            }
            */
              logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() CONTRACT_REQUEST_TIMELINE" );
              out["result"] = "CONTRACT_EXTEND_TIMELINE";
            //  extension =   REQ_LONG( in, "extension", 1, -1 );

              ret = load_db_record( out, "SELECT * FROM members_jobs_contract "
                                          " WHERE status IN (1,2) AND contract='%s' "
                                          " AND id=%lu AND client_id =%lu "
                                          " AND delivery_date < now()",in["job_contract"].c_str(),in["contract_id"].Long(),in["member_id"].Long() );
              logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() CONTRACT_REQUEST_TIMELINEret 1 = %lu",ret );
              if (ret>0)
              {
                     pgsql_exec("UPDATE members_jobs_contract SET ext_request = now(), updated = now()  WHERE  status IN (1,2) AND id = %lu AND contract='%s'", in["contract_id"].Long() ,in["job_contract"].c_str());
                    // make sure the update was done
                      if ( load_db_record( out, "SELECT * FROM members_jobs_contract WHERE id=%lu AND member_id =%lu AND delivery_date > now()",in["contract_id"].Long(),in["member_id"].Long() ) )
                      {
                        project_email(CONTRACT_REQUEST_TIMELINE, in, out);
                        out["result"] = "We have requested the timeline increase";

                            if ( load_db_record(xy, "SELECT id AS member_id, uid AS member_uid, 'message.svg' AS icon  "
                                                    " FROM members WHERE id = %lu ",out["member_id"].Long()) > 0 ){
                                         xy["msg"] = "Task timeline extension was requested";
                                         xy["msg"].set_valid(true);
                                         plan_notification(xy, out);
                             }
                      }
              }

	  break;

	  case CONTRACT_EXTEND_TIMELINE:
	      logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() CONTRACT_EXTEND_TIMELINE" );
		  out["result"] = "CONTRACT_EXTEND_TIMELINE";
		  extension =   REQ_LONG( in, "extension", 1, -1 );
		  
	  	  ret = load_db_record( out, "SELECT * FROM members_jobs_contract "
	  	                              " WHERE status IN (1,2) AND contract='%s' "
	  	                              " AND id=%lu AND member_id =%lu "
	  	                              " AND delivery_date < now()",in["job_contract"].c_str(),in["contract_id"].Long(),in["member_id"].Long() );
		  logfmt( logINFO, "~~~~ ~~~~~ WrenchContractStatus() ret 1 = %lu",ret );
		  if (ret>0)
		  {
				  pgsql_exec("UPDATE members_jobs_contract SET ext_request = NULL, "
				                                              " due_remind = NULL, delivery_date = now() +'%lu days' "
				                                              " WHERE  status IN (1,2) AND id = %lu AND contract='%s'",extension, in["contract_id"].Long() ,in["job_contract"].c_str());
				// make sure the update was done 
				  if ( load_db_record( out, "SELECT * FROM members_jobs_contract WHERE id=%lu AND member_id =%lu AND delivery_date > now()",in["contract_id"].Long(),in["member_id"].Long() ) )
				  {
				    project_email(CONTRACT_EXTEND_TIMELINE, in, out);
				   out["result"] = "We have extended the timeline as requested";
				  }
		  }
	  break;
	  
	  case CONTRACT_CANCEL_CONTRACT:
	    out["result"] = "CONTRACT_CANCEL_CONTRACT";
		
	      ret = load_db_record( out, "SELECT id AS contract_id, * FROM members_jobs_contract "
	                                 " WHERE status IN (1,2) AND delivery_date < now() "
	                                 " AND contract='%s' AND id=%lu AND member_id =%lu AND refund_date IS NULL",in["job_contract"].c_str(),in["contract_id"].Long(),in["member_id"].Long() );
  		  if (ret)
		  {
		         if ( out["contract_id"].Long() <0 ){
		         out["result"] = "General failure";
		         return ret;
		         }
				  pgsql_exec("UPDATE members_jobs_contract SET status = %lu,updated=now() WHERE id = %lu",CONTRACT_CANCEL_CONTRACT, out["contract_id"].Long() );
				// make sure the update was done 
				  if ( load_db_record( out, "SELECT * FROM members_jobs_contract WHERE status = %lu  AND id=%lu AND member_id =%lu",CONTRACT_CANCEL_CONTRACT,in["contract_id"].Long(),in["member_id"].Long() ) )
				  {
				    //let us do the accounting parts here now
					CVars y;
					y["member_id"] = in["member_id"]; // note we are actually paying the client_id
					y["contract_id"] = in["contract_id"];
					y["code"] = "COCNL";
					y["dir"] = DIR_TARGET;
					y["job_status"] = CONTRACT_CANCEL_CONTRACT;
					if (  WrenchCanceContractPayment(y,out) == PHP_CREATED_OK )
					{ // if you reserve pauments
						//char offer_code[15] = "";
						//GetOfferCode(offer_id, offer_code, sizeof (offer_code)); // this stamp the offer code directly in that call	
						pgsql_exec("UPDATE members_jobs_contract SET updated = now(),payment_date=now(),refund_date=now()  WHERE id = %lu",out["contract_id"].Long());
					}
					else
					{
						
					}
					//----------------------------------------
					  
				   project_email(CONTRACT_CANCEL_CONTRACT, in, out);  //USES in["contract_id"]
				   out["result"] = "This task is now cancelled. We have notified all parties accordingly";
				  }
		  }
		
		
		
	  break;
	}
	
	
	//$mysql = "SELECT * FROM members_jobs_contract WHERE contract ='" . $data['job_contract'] . "' AND id  =" . $data['job_id'];
	
	
	
	
	/*
	
	Array ( [member_id] => 3 [proc] => ACCEPTCMP [job_id] => 13 [job_contract] => 7BW9B9R8BB [job_action] => 5 ) 
	
	#define CONTRACT_NOTIFY_COMPLETE 4
	#define CONTRACT_REQUEST_CANCEL  3
	#define CONTRACT_ACCEPT_COMPLETE 5
	#define CONTRACT_REJECT_COMPLETE 1
	*/
		logfmt( logINFO, "/WrenchContractStatus()" );
	return 0;
}

long  WrenchContractMessage( CVars in, CVars &out )
{
    out["message_sent"] = "0";
	/*
		--- // note thet we did not refrenece members table  - this is to ensure that the system can insert items too into the disucssion
		CREATE TABLE jobs_contract_message (
		id SERIAL,
		member_id INT,
		contract VARCHAR(25) REFERENCES members_jobs_contract(contract),
		msg_type VARCHAR(5) NOT NULL,
		message TEXT,
		status INT DEFAULT 1,
		created timestamp without time zone DEFAULT now()
		);

		$msgArray =  array();
		$msgArray['message'] = trim($this->input->post('jobmessage'));
		$msgArray['contract'] = $this->input->post('contractId');
		$msgArray['msg_type'] = 'TEXT';
		$msgArray['member_id'] = $_SESSION['member_id']; // = $ret->email;
	*/
	long ret = PHP_API_BAD_PARAM;
	logfmt( logINFO, "WrenchContractMessage()" );
	ULONG message_id = 0;
	
	REQ_LONG( in, "member_id", 1, -1 );
	REQ_STRING (in, "contract",   10, 25, "(.*)");
	REQ_STRING (in, "msg_type",   1, 5, "(.*)");
	REQ_STRING (in, "message",   1, 1299, "(.*)");
	
	const char * loc = getenv("REMOTE_ADDR");
	in["loc"]  = loc; in["loc"].set_valid(true);	
	CVars x;
	x["member_id"] = in["member_id"]; x["member_id"].set_valid( true );
	x["contract"] = in["contract"]; x["contract"].set_valid( true );	
	x["msg_type"] = in["msg_type"]; x["msg_type"].set_valid( true );	
	x["message"] = in["message"]; x["message"].set_valid( true );		

	message_id = insert_db_record( DBS_VALID, "jobs_contract_message", "jobs_contract_message_id_seq", x );
			
		if (message_id) {
	      ret = PHP_CREATED_OK;
		  x["message_id"] = message_id;  x["message_id"].set_valid( true );
		  job_email(JOBS_MESSAGE_ADDED,x,out);
		  load_db_record( out, "SELECT *,id AS message_id FROM jobs_contract_message WHERE id = %lu ", message_id );
                  out["status"] = "Message Sent";
                   out["message_sent"] = "200";
		} else {
			out["status"] = "Unable to send message";
		}
			
	logfmt( logINFO, "/WrenchContractMessage()" );	
	return ret;
}

long  WrenchContractMessageList( CVars in, CVars &out )
{
	long ret = PHP_API_BAD_PARAM;
	logfmt( logINFO, "WrenchContractMessageList()" );
    char vname[30];
    
	const char * loc = getenv("REMOTE_ADDR");
	in["loc"]  = loc; in["loc"].set_valid(true);

      try {
        long member_id = REQ_LONG(in, "member_id", 1, -1);
        REQ_STRING (in, "contract",   10, 25, "(.*)");
        out["total_record"] = "0";

          const PGresult *res;


            res = pgsql_query(" SELECT to_char(jc.created, 'YYYY-MM-DD HH24:MI') AS msg_date,"
            " m.firstname AS msg_firstname,jc.id as msg_id,jc.message AS msg,"
            " jc.msg_type, jc.message,jc.member_id AS sender_id, jc.uid AS msg_uid "
            " FROM jobs_contract_message jc "
            " LEFT JOIN members m ON m.id=jc.member_id "
            " WHERE jc.contract='%s' ORDER by jc.id DESC", in["contract"].c_str());

          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), "msg_date_%05d", i);
                    out[vname] = rec["msg_date"];

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

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

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

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

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

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

                    snprintf(vname, sizeof (vname), "who_%05d", i);
                    if( rec["sender_id"].Long() ==  member_id){
                      out[vname] = "SENDER";
                    }
                    else{
                      out[vname] = "RECIPIENT";
                    }

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

//******************************************************************************
