<?php

date_default_timezone_set('America/New_York');
http_response_code(200);
error_reporting(E_ERROR);
session_start();

include '/var/www/html/utilitiesquickassits/common/generalWs.php';
require '/var/www/html/utilitiesquickassits/vendor/autoload.php';

// include 'common/generalWs.php';
// require 'vendor/autoload.php';

$obj_function = new coFunction();
$obj_bdmysql = new coBdmysql();

$conn = mysqli_connect(DBHOST, DBUSER, DBPASS, DBNOM); /* Database connection end */ //RDS
$conn->set_charset('utf8mb4');

$date = new DateTime();
$date_today = $date->format('Y-m-d');
$full_date_today = $date->format('Y-m-d H:i:s');

$secret_key = SECRET_KEY_STRIPE;
$public_key = PUBLISHABLE_KEY;

\Stripe\Stripe::setApiKey($secret_key);
$endpoint_secret = 'whsec_35182ed783c3c7735f3001050b28562cd05f6752cbe93f801b6e070c310e9133';

$payload = @file_get_contents('php://input');
$event = null;

$ws_path = "https://wshunitydev.gosmartcrm.com:4000/ws";

$jsondebug = "/var/www/html/utilities/cron_hunity/cron/jsondebug.log";
//$jsondebug = "jsondebug.log";

try {
    $event = \Stripe\Event::constructFrom(
        json_decode($payload, true)
    );
} catch(\UnexpectedValueException $e) {
    error_log("\n".date('d/m/Y h:i:s')."\n".print_r($e,true), 3, $jsondebug);
    // Invalid payload
    //echo '⚠️  Webhook error while parsing basic request.';
    http_response_code(400);
    exit();
}


switch ($event->type) {
    case 'payment_intent.succeeded':
        error_log("\n".date('d/m/Y h:i:s')." $event->type"."\n".print_r($event->data->object,true), 3, $jsondebug);
        $paymentIntent = $event->data->object;
        paymentIntentSucceeded($paymentIntent);
    break;

    case 'payment_intent.payment_failed':
        error_log("\n".date('d/m/Y h:i:s')." $event->type"."\n".print_r($event->data->object,true), 3, $jsondebug);
        $paymentIntent = $event->data->object;
        paymentIntentFailed($paymentIntent);
    break; 

    case 'setup_intent.succeeded':
        error_log("\n".date('d/m/Y h:i:s')." $event->type"."\n".print_r($event->data->object,true), 3, $jsondebug);
        $paymentIntent = $event->data->object;
        setupIntentSucceeded($paymentIntent);
    break;
     
    default:
        // Unexpected event type error_log('Received unknown event type' . $event->type);
        error_log("\n".date('d/m/Y h:i:s')."\n".print_r($event->type,true), 3, $jsondebug);
}

function paymentIntentSucceeded($paymentIntent){ 
    //die();
    //cambiar el stado del pago de "procesando" a "pago"
    global $conn, $obj_bdmysql, $obj_function, $date_today, $full_date_today, $jsondebug, $ws_path;

    $id_payment_intent = $paymentIntent->id;

    $sql = "SELECT pa.id, pa.id_payment_due, pa.id_client, pd.amount, pd.payment_date, pd.fee, ap.id_user, ap.id_status as id_status_app, ap.id as id_application, le.commission as user_commission, ap.agreement_number, ap.data_json, bp.name as billing_period_name, pd.id_pay_method
        FROM payment_attempt pa 
        INNER JOIN payment_due pd ON pd.id = pa.id_payment_due 
        INNER JOIN pay_method pm ON pm.id = pd.id_pay_method 
        INNER JOIN application ap ON ap.id = pd.id_application 
        INNER JOIN applicant appli ON appli.id = ap.id_applicant 
        INNER JOIN user us ON us.id = ap.id_user 
        INNER JOIN level le ON le.id = us.id_level 
        INNER JOIN plan_price pp ON pp.id = ap.id_plan_price
        INNER JOIN plan p ON p.id = pp.id_plan
        INNER JOIN billing_period bp ON bp.id = pp.id_billing_period
        WHERE pa.data->> '$.id' = '$id_payment_intent' AND pm.method_inf_json->> '$.type' = 'bank'"; // solo para tipos bancario

    $query = $obj_bdmysql->query($sql,$conn);

    if (is_array($query)) {
        $data = $paymentIntent != "" ? json_encode($paymentIntent) : "{}";

        $id_payment_attempt = $query[0]['id'];
        $id_payment_due = $query[0]['id_payment_due'];
        $id_client = $query[0]['id_client'];

        $billing_period_name = $query[0]['billing_period_name'];
        $id_pay_method = $query[0]['id_pay_method'];

        $user_commission = $query[0]['user_commission'];
        $id_user = $query[0]['id_user'];
        $payment_date = $query[0]['payment_date'];
        $amount = $query[0]['amount'];
        $id_client = $query[0]['id_client'];
        $fee = $query[0]['fee'];
        $id_status_app = $query[0]['id_status_app'];
        $id_application = $query[0]['id_application'];
        $agreement_number = $query[0]['agreement_number'];

        $data_json = json_decode($query[0]["data_json"]);
        $amount_next = isset($data_json->payment->nextPayment) ? $data_json->payment->nextPayment : $amount;

        $sql = "UPDATE payment_attempt SET status='2', note='Successfully Paid', data='$data' WHERE id = $id_payment_attempt";
        $obj_bdmysql->query($sql, $conn);

        $sql = "UPDATE payment_due SET status='2', payment_due_date='$full_date_today', user_commission='$user_commission' WHERE id = $id_payment_due";
        $obj_bdmysql->query($sql, $conn);

        saveCommissions($id_payment_due, $id_user, $user_commission, $payment_date, $amount, $id_client, $fee);

        if($agreement_number == null OR $agreement_number == ""){
            // 1) generar el agreement para la aplicacion
            $obj_bdmysql->query("call spAgreementCode($id_application);", $conn, FALSE, 'CALL');

            // 2) actualizar el campo date_sale en la tabla application
            // 3) actualizar status de la aplicacion a "sale"
            $campo = "id_status = 3, date_sale = '$full_date_today'";
            $where = "id = '$id_application'";
            $query = $obj_bdmysql->update("application", $campo, $where, $conn);

            // 4) enviar emails de bienvenida y membresia
            $url = $ws_path."/payment/notification/landingpage";
            $jsonData = [
                "id_application" => $id_application,
                "id_client" => $id_client
            ];
            $curl_sendPdf = $obj_function->curlSetOpt($url, $jsonData);
            //error_log("\n".date('d/m/Y h:i:s')."\n".print_r($curl_sendPdf,true), 3, $jsondebug);
            
            // 5) crear cuotas siguientes (usar funcion de nextPayments)
            if ($billing_period_name == "monthly" or $billing_period_name == "biannual" or $billing_period_name == "3 payment") {
                //LA VARIABLE "amount" DEBE SER REEMPLZADA POR LA VARIABLE "amount_next" QUE AUN NO EXISTE EN EL DESARROLLO
                nextPayments($id_application, $id_pay_method, $amount_next, $user_commission, $billing_period_name);
            }
        }

        //Al pagar la cuota, se deben desactivar las notificaciones de pago para esta cuota. 
        $campo = "status = 4";
        $where = "id_payment_due = '$id_payment_due'";
        $query = $obj_bdmysql->update("noti_app_anulcancel", $campo, $where, $conn);

        //Y si la aplicacion está pausada y no tiene otra deuda vieja, vuelve al status "SALE"
        if($id_status_app == 5){
            $sql = "SELECT id FROM payment_due pd WHERE pd.id_application = $id_application AND (pd.status != 2 AND pd.status != 0)";
            $query = $obj_bdmysql->query($sql, $conn);

            if(!is_array($query)){
                $campo = "id_status = 3";
                $where = "id = '$id_application'";
                $query = $obj_bdmysql->update("application", $campo, $where, $conn);
            }
        }
    }
}

function paymentIntentFailed($paymentIntent){
    //cambiar el stado del pago de "esperando confirmacion" a "confirmacion fallida"

    global $conn, $obj_bdmysql, $obj_function, $jsondebug, $ws_path;

    $id_payment_intent = $paymentIntent->id;
    $note = $paymentIntent->charges->data[0]->failure_code != "" ? $paymentIntent->charges->data[0]->failure_code : "";
    $note = addslashes($note);

    $sql = "SELECT pa.*, pd.retries, pd.id_application, pd.payment_date FROM payment_attempt pa 
    INNER JOIN payment_due pd ON pd.id = pa.id_payment_due 
    INNER JOIN pay_method pm ON pm.id = pd.id_pay_method 
    WHERE pa.data->> '$.id' = '$id_payment_intent' AND pm.method_inf_json->> '$.type' = 'bank'"; // pt.id 5 = tipo cuenta bancaria stripe
    $query = $obj_bdmysql->query($sql,$conn);

    if (is_array($query)) {
        $id_payment_attempt = $query[0]['id'];
        $id_payment_due = $query[0]['id_payment_due'];
        $retries = $query[0]['retries'];
        $id_application = $query[0]['id_application'];
        $payment_date = $query[0]['payment_date'];

        $date = new DateTime();
        $date = $date->format('Y-m-d H:i:s');

        $sql = "UPDATE payment_attempt SET status='8', note='$note' WHERE id = $id_payment_attempt"; // evaluar actualizar tambien el campo "data"
        $obj_bdmysql->query($sql, $conn);

        if ($retries < 2) {
            $status = 1;
            $campo = "retries = retries + 1, status = $status";//status 1 = pendiente para reintentar 
        }else if($retries >= 2 ){
            $status = 3;
            $campo = "retries = retries + 1, status = $status";//status 3 = fallo por muchos intentos 
        }

        $where = "id = '$id_payment_due'";
        $query = $obj_bdmysql->update("payment_due", $campo, $where, $conn);
        
        $template = $status == 1 ? 3 : 4;

        $url = $ws_path."/payment/sendnotificationcronjob";
        $jsonData = [
            "id_payment_due" => $id_payment_due,
            "template" => $template,
        ];
        $curl_notification = $obj_function->curlSetOpt($url, $jsonData);
    }
}

function setupIntentSucceeded($paymentIntent){ 

    //Adjuntar methodo de pago verificado al customer y guardarlo en la bd
    global $conn, $obj_bdmysql, $secret_key, $jsondebug;

    $id_payment_method = $paymentIntent->payment_method;

    $sql = "SELECT DISTINCT pm.id, pm.id_applicant, pm.status, u.id_client 
            FROM pay_method pm 
            INNER JOIN application ap ON ap.id_applicant = pm.id_applicant 
            INNER JOIN user u ON u.id = ap.id_user 
            WHERE pm.method_inf_json->> '$.id' = '$id_payment_method' AND pm.status = 2";
    $query = $obj_bdmysql->query($sql,$conn);

    if(is_array($query)){
        $id_applicant = $query[0]['id_applicant'];
        $id_pay_method = $query[0]['id'];
        $id_client = $query[0]['id_client'];

        $sql = "SELECT id_customer_stripe FROM applicant WHERE id = $id_applicant";
        $query = $obj_bdmysql->query($sql, $conn);
        $id_customer_stripe = $query[0]['id_customer_stripe'];

        $stripe = new \Stripe\StripeClient($secret_key);
        $attach = $stripe->paymentMethods->attach(
            $id_payment_method,
            ['customer' => $id_customer_stripe]
        );

        if($attach['type'] == "us_bank_account"){
            
            $financial_connections_account = $attach['us_bank_account']['financial_connections_account'];
            $bank_name = $attach['us_bank_account']['bank_name'];
            $last4 = $attach['us_bank_account']['last4'];

            $campo = "status = '1', method_inf_json = JSON_REPLACE(method_inf_json, '$.last4', '$last4'), method_inf_json = JSON_REPLACE(method_inf_json, '$.bank_name', '$bank_name'), method_inf_json = JSON_REPLACE(method_inf_json, '$.financial_connections_account', '$financial_connections_account')";

            $sql = "UPDATE pay_method SET $campo WHERE id = '$id_pay_method'";
            $update = $obj_bdmysql->query($sql, $conn);

            //SI TIENE EL STATUS DE "pending_payment" se debe hacer la ejecusion de ese pago pendiente al completar la verificaciond el metodo de pago  
        }
    }
}

function nextPayments($id_application, $id_pay_method, $amount_next, $user_commission, $billing_period_name)
{

    global $conn, $obj_bdmysql, $obj_function, $jsondebug, $date_today;

    $data_type_payment = 0;

    if ($billing_period_name == "monthly") {
        $months = 1;
        $count = 11;
    }
    if ($billing_period_name == "biannual") {
        $months = 6;
        $count = 1;
    }
    if ($billing_period_name == "3 payment") {
        $months = 1;
        $count = 2;
    }

    $new_date_payment = $date_today; // formatear a Y-m-d
    $init_day= date("d", strtotime($new_date_payment));

    for ($i = 0; $i < $count; $i++) {
        $day_now = date("d", strtotime($new_date_payment));
        $month_now = date("m", strtotime($new_date_payment));
        $year_now = date("Y", strtotime($new_date_payment));

        if($month_now== 1 && $day_now > 28){
            $new_date_payment = date("Y-m-d", strtotime($new_date_payment . "last day of + $months month"));
        }else if($month_now == 2 && ($billing_period_name == "monthly" || $billing_period_name == "3 payment")){
            $nueva_fecha = $year_now.'-01-'.$init_day;
            $new_date_payment = date("Y-m-d", strtotime($nueva_fecha . "+ 2 month"));            
        }else if($month_now == 8 && $billing_period_name == "biannual"){
            $new_date_payment = date("Y-m-d", strtotime($new_date_payment . "last day of + $months month"));
        }else if($month_now > 2 && $day_now > 30){
            $new_date_payment = date("Y-m-d", strtotime($new_date_payment . "last day of + $months month"));
        }else{      
            $new_date_payment = date("Y-m-d", strtotime($new_date_payment . "+ $months month"));
        }

        $campo = "id_application, id_pay_method, amount, user_commission, payment_date";
        $valor = "$id_application, $id_pay_method, $amount_next, '$user_commission', '$new_date_payment'";
        $obj_bdmysql->insert("payment_due", $campo, $valor, $conn);
    }
}

function saveCommissions($id_payment_due, $id_user, $user_commission, $payment_date, $amount, $id_client, $fee){
    // función desarrollada, para registro de intentos de pago realizados con o sin exito.
    //se guarda data en tabla ( contacts_services_payment). 
    global $conn, $obj_bdmysql, $obj_function;

    $date = date("Y-m-d H:i:s");

    if ($fee > 0) {
        $amount = $amount - $fee;
    }

    if($amount > 0){
        $amount_commission = ($amount * $user_commission) / 100;
        $campo = "id_payment_due, id_user, id_client, id_user_prev, commission_percentage, commission_amount, type, date_create, date_commission, source, flag_edit";
        $valor = "$id_payment_due, $id_user, $id_client, 0, $user_commission, $amount_commission, '1', '$date', '$payment_date', 'Cron', '1'";
        $id = $obj_bdmysql->insert("commission_payments", $campo, $valor, $conn);

        //$sql = "INSERT INTO commission_payments ($campo) VALUES ($valor)";
        //print_r($sql);exit();

        $sql = "SELECT u.id, u.id_parent, l.commission, u.id_client FROM user u INNER JOIN level l ON l.id = u.id_level where u.id = $id_user";
        $query = $obj_bdmysql->query($sql, $conn);

        if ($query[0]['id_parent'] > 0) {
            $id_user_prev = $query[0]['id'];
            $id_parent = $query[0]['id_parent'];
            $check_id_parent = 1;
            $old_commission = $user_commission;
            $i = 0;
            do {
                $sql = "SELECT u.id, u.id_parent, l.commission, l.name AS level_name, u.id_client 
                        FROM user u INNER JOIN level l ON l.id = u.id_level WHERE u.id = $id_parent";
                $query = $obj_bdmysql->query($sql, $conn);   
                
                $level = $query[0]['level_name'];

                if($level == "Other"){
                    $check_id_parent = 0;//Stop cycle
                } else {
                    $id_client = $query[0]['id_client'];
                    $id_user = $query[0]['id'];        
                    $commission = $query[0]['commission'];
                    $id_parent = $query[0]['id_parent'];        

                    if ($commission > $old_commission) {
                        $result_commission = $commission - $old_commission;
                        $amount_commission = ($amount * $result_commission) / 100;
                        $commission_percentage = $commission;
                    }else if($commission <= $old_commission){
                        if($level == "Agent" || $level == "Associate"){
                            $commission_percentage = 0;
                            $amount_commission = 0;
                        }else{
                            $commission_percentage = 5;
                            $amount_commission = ($amount * $commission_percentage) / 100;
                        }
                    }

                    $campo = "id_payment_due, id_user, id_client, id_user_prev, commission_percentage, commission_amount, type, date_create, date_commission, source, flag_edit";        
                    $valor = "$id_payment_due, $id_user, $id_client, $id_user_prev, $commission_percentage, $amount_commission, '2', '$date', '$payment_date', 'Cron', '1'";
                    $obj_bdmysql->insert("commission_payments", $campo, $valor, $conn);
                
                    $old_commission = $commission;
                    $id_user_prev = $query[0]['id'];
                }                

                if ($id_parent == 0 || $i == 20) {
                    $check_id_parent = 0;            
                }

                $i++;
                //cuando $i llegue a 20 iteraciones, se debe parar el do while
                //por seguridad para evita ciclo infinito
            } while ($check_id_parent == 1);   
        }
    }
}

function pausedApplication($id_application, $payment_date, $id_payment_due){
    global $conn, $obj_bdmysql, $obj_function, $jsondebug;
    
    $id_status_app = 5; //status 5 = paused
    $campo = "id_status = $id_status_app";
    $where = "id = $id_application";
    $query = $obj_bdmysql->update("application", $campo, $where, $conn);

    $date = new DateTime();
    $date = $date->format('Y-m-d');

    $sql = "SELECT id FROM history_app_status WHERE id_application = $id_application AND createdAt like '%$date%'";
    $query = $obj_bdmysql->query($sql, $conn);
    if(!is_array($query)){
        $campo = "id_application, id_status_app, createdAt";
        $valor = "$id_application, '$id_status_app', '$date'";
        $obj_bdmysql->insert("history_app_status", $campo, $valor, $conn);
    }   

    $sql = "SELECT id FROM noti_app_anulcancel WHERE id_payment_due = $id_payment_due";
    $query = $obj_bdmysql->query($sql, $conn);
    if(!is_array($query)){
        for ($i=0; $i < 3; $i++) {
            if ($i == 0) {
                $days = 30;
                $type = "1";
            }elseif ($i == 1) {
                $days = 60;
                $type = "2";
            }elseif ($i == 2) {
                $days = 90;
                $type = "3";
            }

            $date_notification = new DateTime($payment_date);
            $date_notification = $date_notification->format('Y-m-d');
            $date_notification = date("Y-m-d",strtotime($date_notification."+ $days day"));

            $campo = "id_payment_due, type, status, date_notification";
            $valor = "'$id_payment_due', '$type', '1', '$date_notification'";
            $obj_bdmysql->insert("noti_app_anulcancel", $campo, $valor, $conn);
        }
    }   
}

?>
