<?php
include_once __dir__ . '/../vendor/autoload.php';
include_once __dir__ . '/../core/Config.php';
include_once __dir__ . '/../core/PaymentHelper.php';

use Gerencianet\Exception\GerencianetException;
use Gerencianet\Gerencianet;

const PLANS_CONTRACT_MAP = array(
    'monthly' => array(
        'interval' => 1,
        'label' => 'Mensal'
    ),
    'biannual' => array(
        'interval' => 6,
        'label' => 'Semestral'
    ),
    'annual' => array(
        'interval' => 12,
        'label' => 'Anual'
    )
);

class GerencianetPayment extends Core {

    use PaymentHelper;
    private $api;
    private $env;

    function __construct($conn) {

        parent::__construct($conn);
        $this->env = parse_ini_file(__DIR__ . '/../.env');
        
        $options = [
            'client_id' => $this->env['GERENCIANET_CLIENT_ID'],
            'client_secret' => $this->env['GERENCIANET_CLIENT_SECRET'],
            'sandbox' => $this->env['GERENCIANET_IS_SANDBOX'] == 1,
			'debug' => false,
			'timeout' => 30
        ];
		
        $this->api = new Gerencianet($options);
    }
    
    function listPlans() {

        $params = ['limit' => 20, 'offset' => 0];
        $plans = $this->api->getPlans($params, []);
        
        return [ 'type' => 'OK', 'data' => $plans ];

    }

    function getPlan($plan_payment_option_id) {

        $sql = "SELECT PPO.*, P.name, P.base_price, `period`, PPO.price FROM plan_payment_options AS PPO
            LEFT JOIN plan_payment_contracts AS PPC ON PPC.id = PPO.plan_payment_id
            LEFT JOIN plans AS P ON P.id = PPC.plan_id 
            WHERE PPO.id = :id";
        $stmt  = parent::$conn->prepare($sql);
        $stmt->execute([':id' => $plan_payment_option_id]);
        $plan = $stmt->fetch(PDO::FETCH_ASSOC);
        $contract = PLANS_CONTRACT_MAP[$plan['period']];

        return [
            'price' => $plan['price'],
            'name' => 'Plano ' . $plan['name'] . ' ' . $contract['label'],
            'interval' => $contract['interval'],
            'free' => $plan['base_price'] == 0
        ];
    }    

    function getSignature($company_id) {

        $sql = "SELECT A1.*, base_price FROM company_signatures A1
            LEFT JOIN plans AS A2 ON A1.plan_id = A2.id
            WHERE company_id = :company_id AND type = 'signature'";
        $stmt  = parent::$conn->prepare($sql);
        $stmt->execute([':company_id' => $company_id]);
        $signature = $stmt->fetch(PDO::FETCH_ASSOC);

        return $signature;

    }
    
    function paymentBillet() {

        try {

            $user_id = $_POST['userId'];
            $endcheck = isset($_POST['acceptEnd']) ? $_POST['acceptEnd'] : null;
            $vencimento = isset($_POST['vencimento']) ? $_POST['vencimento'] : null;
            
            $sql = "SELECT * FROM companies WHERE id = ?";
            $stmt = parent::$conn->prepare($sql);
            $stmt->execute([ $user_id ]);
            $user = $stmt->fetch(PDO::FETCH_ASSOC);
            
            $plan_id = $_POST['plan'];
            $plan_payment_id = $_POST['planPayment'];
            $plan_payment_option_id = $_POST['planPaymentOption'];

            $signature = $this->getSignature($user_id);

            if($signature) {
                
                if(empty($signature['created_at'])/* && empty($signature['reference'])*/){
            
                    $signature_id = $signature['signature_id'];
                    $params = [
                        'id' => $signature_id
                    ];                
                    $details = $this->api->detailSubscription($params, []);
                    $statusPlan = $details['data']['status'];
                    
                    if($statusPlan == 'active' || $statusPlan == 'new'){

                        $this->api->cancelSubscription($params, []);
            
                        $status = 'CANCELED';
                        $status_text = 'Assinatura cancelada troca de plano';
                        $this->updateSignature($user_id, null, null, null, null, null, $status, $status_text, $signature_id);

                    }

                }
                
                $this->deleteSignature($user_id);
                $this->deleteSignatureQuotes($user_id);

            }

            $plan = $this->getPlan($plan_payment_option_id);

            if($plan['free']) {
                $this->updateMakeFreeAccount($user['id']);
                return [ 'type' => 'OK' ];
            }            

            $address1 = $_POST['street'];
            $address2 = $_POST['number'];
            $city = $_POST['city'];
            $state_uf = $_POST['state'];
            $zipcode = $_POST['zipCode'];
            $neighborhood = $_POST['district'];
            $complement = isset($_POST['complement']) ? $_POST['complement'] : '';
            $email = $_POST['email'];
            $phone = $_POST['mobile'] ?? '';
            $birthdate = isset($_POST['birthdate']) ? $_POST['birthdate'] : '';
            
            if(!empty($user["cupom"]) && empty($user['cupom_check'])){
                
                $sql = "UPDATE companies SET cupom_check = ? WHERE id = ?";
                $stmt = parent::$conn->prepare($sql);
                $stmt->execute([ $user['cupom'], $user_id ]);
        
            }
            
            if(!empty($birthdate)){
                if (strpos($birthdate, '/') !== false) {
                    $birthdate = implode('-', array_reverse(explode('/', $birthdate)));
                }
                
                // Verifica se o formato é "15022001" e converte para "2001-02-15"
                if (strlen($birthdate) === 8 && is_numeric($birthdate)) {
                    $birthdate = substr($birthdate, 4, 4) . '-' . substr($birthdate, 2, 2) . '-' . substr($birthdate, 0, 2);
                }
            }
            
            $companyname = $_POST['companyName'];
            $cnpj = $_POST['cnpj'];
            
            //verifica se existe plano
            $params = array(
                'name' => $plan['name']
            );
            
            $query_result = $this->api->listPlans($params, []);
            
            if(sizeof($query_result['data']) > 0)
                $gen_plan_id = $query_result['data'][0]['plan_id'];
            else {

                $body = [
                    'name' => $plan['name'],
                    'interval' => $plan['interval'],
                    'repeats' => null
                ];
                $result = $this->api->createPlan([], $body);
                $gen_plan_id = $result['data']['plan_id'];

            }
            
            $params = ['id' => $gen_plan_id];
            $items = [
                [
                    'name' => $plan['name'],
                    'amount' => 1,
                    'value' => intval(floatval($plan['price']) * 100)
                ]
            ];
            
            $metadata = ['notification_url'=>$this->env['GERENCIANET_NOTIFICATION_URL']];
            
            $body  =  [
                'items' => $items,
                'metadata' => $metadata
            ];
            
            $subscription = $this->api->createSubscription($params, $body);            
            $subscription_id = $subscription['data']['subscription_id'];            
            $params = [ 'id' => $subscription_id ];			
            //$billet_name = $user['account_type'] === 'company' ? $user['company'] : $user['firstname'] . ' ' . $user['lastname'];
            
            if(!empty($companyname)){
                $customer = [
                    'email' => $email,
                    'phone_number' => $phone,
                    'juridical_person' => [
                        'corporate_name' => $companyname,
                        'cnpj' => $cnpj
                    ],
                    'address' => [
                        'street' => $address1,
                        'number' => $address2,
                        'neighborhood' => $neighborhood,
                        'zipcode' => $zipcode,
                        'city' => $city,
                        'complement' => $complement,
                        'state' => $state_uf
                    ]
                ];
            }


            $date = new DateTime();
            //$date = $plan['free'] ? $date->add(new DateInterval('P90D')) : $date->add(new DateInterval('P7D'));
            
            if(!empty($vencimento)){
                $date = $date->add(new DateInterval('P15D'));
            }else{
                $date = $date->add(new DateInterval('P3D'));
            }
            
            $banking_billet = [
                'expire_at' => $date->format('Y-m-d'),
                'message' => "Memprega.com.br, {$plan['name']}",
                'customer' => $customer
            ];
            $payment = [
                'banking_billet' => $banking_billet, //forma de pagamento (banking_billet = boleto)                
            ];
            $body = [
                'payment' => $payment
            ];
            
            $payment = $this->api->defineSubscriptionPayMethod($params, $body);
            
            $signature_id = $subscription_id;
            $charge_link = $payment['data']['billet_link'];
            
            $signature_status_text = 'Assinatura criada, aguardando confirmação de pagamento do boleto';
            $this->updateSignature(
                $user_id, 
                $plan_id, 
                $plan_payment_id,
                $plan_payment_option_id, 
                'BILLET', 
                null, 
                'CANCELED', 
                $signature_status_text, 
                $signature_id, 
                $gen_plan_id, 
                $charge_link,
                'signature',
                $plan['price']
            );
            
            $this->insertSignatureQuotes($user_id, $plan_id, $plan_payment_id);
        
            $sql = "SELECT id FROM leads WHERE email = ?";
            $stmt = parent::$conn->prepare($sql);
            $stmt->execute([ $user['companyemail'] ]);
            $lead = $stmt->fetch(PDO::FETCH_ASSOC);
            
            
            $sql = "INSERT IGNORE INTO lead_lists_leads(leadlist_id, lead_id, date_added, manually_removed, manually_added)
                VALUES(42, ?,NOW(), 0, 0)";        
            $stmt = parent::$conn->prepare($sql);
            $stmt->execute([ $lead['id'] ]);

            return [ 
                'type' => 'OK', 
                'data' => [
                    'id' => $signature_id,
                    'link' => $charge_link
                ]
            ];            
            
        } catch(\Exception $err) {
            
            return [ 'type' => 'ERROR', 'data' => $err->getMessage() ];
        }
        
    }

    function notification() {
 
        define('GEN_STATUS', array(
            'new' => [
                'status' => 'PENDING',
                'text' => 'Liberada momentaneamente, esperando autorização da operadora do cartão'
            ],
            'new_charge' => [
                'status' => 'PENDING',
                'text' => 'Liberada momentaneamente, esperando autorização da operadora do cartão'
            ],
            'active' => [
                'status' => 'PENDING',
                'text' => 'Assinatura ativa'
            ],
            'paid' => [
                'status' => 'ACTIVE',
                'text' => 'Assinatura/cobrança paga'
            ],
            'waiting' => [
                'status' => 'PENDING',
                'text' => 'Liberada momentaneamente, aguardando prazo e esperando autorização da operadora do cartão'
            ],
            'canceled' => [
                'status' => 'CANCELED',
                'text' => 'Assinatura cancelada'
            ],
            'expired' => [
                'status' => 'CANCELED',
                'text' => 'Assinatura cancelada por falta de pagamento ou expirada, você pode emitir um novo boleto e fazer o pagamento antes do vencimento'
            ],
            'contested' => [
                'status' => 'PENDING',
                'text' => 'Pagamento em processo de contestação'
            ],
            'refunded' => [
                'status' => 'CANCELED',
                'text' => 'Pagamento devolvido pelo lojista ou pelo intermediador Efí'
            ],
            'settled' => [
                'status' => 'ACTIVE',
                'text' => 'Cobrança foi marcada como pago manualmente'
            ],
            'unpaid' => [
                'status' => 'CANCELED',
                'text' => 'Não foi possível confirmar o pagamento da cobrança'
            ]
        ));
 
        try {
            $token = $_POST['notification'];
            $params = [
                'token' => $token
            ];
            $notification = $this->api->getNotification($params, []);
            
            $i = count($notification["data"]); 
            $last_status = $notification["data"][$i-1];    
            $status = $last_status["status"];
            $type = $last_status["type"] ?? null;
            $subcription = null;
            switch ($type) {
                case "subscription":
                case "subscription_charge":
                    $subcription = true;
                    break;
                case "charge": // cobrança avulsa
                    $subcription = false;
                    break;
                default:
                    $subcription = null; // melhor do que assumir assinatura
                    break;
            }
            $charge_id = $last_status["identifiers"]["charge_id"] ?? null;
            $subscription_id = $last_status["identifiers"]["subscription_id"] ?? null;    
            $current_status = $status["current"];            
            $status = GEN_STATUS[$current_status] ?? [ 'status' => 'CANCELED', 'text' => 'Assinatura cancelada por falta de pagamento ou expirada' ];
            
            if($subcription === true && $subscription_id){
                
                $sql = "UPDATE company_signatures SET `status` = :status, status_text = :text, last_update = NOW() WHERE signature_id = :id";
                $stmt = parent::$conn->prepare($sql);
                $stmt->execute([ 
                    ':status' => $status['status'],
                    ':text' => $status['text'],
                    ':id' => $subscription_id,
                ]);
                
                $sql = "SELECT C.companyemail FROM companies AS C LEFT JOIN company_signatures AS CS ON CS.company_id = C.id WHERE CS.signature_id = ?";
                $stmt = parent::$conn->prepare($sql);
                $stmt->execute([ $subscription_id ]);
                $user = $stmt->fetch(PDO::FETCH_ASSOC);
                
                if(!$user) {
                    http_response_code(200);
                    return;
                }

                $sql = "SELECT id FROM leads WHERE email = ?";
                $stmt = parent::$conn->prepare($sql);
                $stmt->execute([ $user['companyemail'] ]);
                $lead = $stmt->fetch(PDO::FETCH_ASSOC);

                //deleta se estiver nos segmentos de pendentes ou cancelados
                $sql = "DELETE FROM lead_lists_leads WHERE leadlist_id IN(42, 41, 39) AND lead_id = ?";
                $stmt = parent::$conn->prepare($sql);
                $stmt->execute([ $lead['id'] ]);

                if($status['status'] === 'ACTIVE') {
                    $sql = "INSERT INTO lead_lists_leads(leadlist_id, lead_id, date_added, manually_removed, manually_added)
                        VALUES(39, ?,NOW(), 0, 0)";   
                    $stmt = parent::$conn->prepare($sql);
                    $stmt->execute([ $lead['id'] ]);
                    //$this->updateMakePaidAccount($user['email']);

                    
                } else {
                    //Segmentos dos cancelados, ID  41
                    $sql = "INSERT INTO lead_lists_leads(leadlist_id, lead_id, date_added, manually_removed, manually_added)
                        VALUES(41, ?,NOW(), 0, 0)";        
                    $stmt = parent::$conn->prepare($sql);
                    $stmt->execute([ $lead['id'] ]);
                }    
            }elseif($subcription === false && $charge_id){

                $sql = "UPDATE company_signatures SET `status` = :status, status_text = :text, last_update = NOW() WHERE signature_id = :id";
                $stmt = parent::$conn->prepare($sql);
                $stmt->execute([ 
                    ':status' => $status['status'],
                    ':text' => $status['text'],
                    ':id' => $charge_id,
                ]);

                $this->updateCampaignProcessListStatus($charge_id, $status['status'], $status['text']);

            }
 
        } catch(\Exception $err) {
            http_response_code(500);
            
        }
 
        http_response_code(200);
 
    }

    function paymentBilletSimple() {
        try {
            $userId = $_POST['userId'];
            
            $plan_id = $_POST['plan'];
            $plan_payment_id = $_POST['planPayment'];
            $plan_payment_option_id = $_POST['planPaymentOption'] ?? null;
            
            $payment_name = $_POST['paymentName'];
            $payment_price = $_POST['paymentPrice'];

            // 1. Itens da cobrança
            $items = [
                [
                    'name'   => $payment_name,
                    'amount' => 1,
                    'value'  => intval(floatval($payment_price) * 100) // em centavos
                ]
            ];
                        
            $address1 = $_POST['street'];
            $address2 = $_POST['number'];
            $city = $_POST['city'];
            $state_uf = $_POST['state'];
            $zipcode = $_POST['zipCode'];
            $neighborhood = $_POST['district'];
            $complement = isset($_POST['complement']) ? $_POST['complement'] : '';
            $email = $_POST['email'];
            $phone = $_POST['mobile'];
            $birthdate = isset($_POST['birthdate']) ? $_POST['birthdate'] : '';
            $companyname = $_POST['companyName'];
            $cnpj = $_POST['cnpj'];
            $process_id = $_POST['processId'] ?? null;
            $sale_id = $_POST['saleId'] ?? null;
            $user_id = $_POST['userId'] ?? null;
            
            // 2. Dados do cliente
            $customer = [
                'email' => $email,
                'phone_number' => $phone,
                'juridical_person' => [
                    'corporate_name' => $companyname,
                    'cnpj' => $cnpj
                ],
                'address' => [
                    'street' => $address1,
                    'number' => $address2,
                    'neighborhood' => $neighborhood,
                    'zipcode' => $zipcode,
                    'city' => $city,
                    'state' => $state_uf
                ]
            ];
            // 3. Configurar vencimento do boleto
            $date = new DateTime();
            $date->add(new DateInterval('P3D')); // boleto vence em 3 dias
            // 4. Montar o body para OneStepCharge
            $body = [
                'items' => $items,
                'metadata' => [
                    'notification_url' => $this->env['GERENCIANET_NOTIFICATION_URL']
                ],
                'payment' => [
                    'banking_billet' => [
                        'expire_at' => $date->format('Y-m-d'),
                        'message'   => "Memprega.com.br, {$payment_name}",
                        'customer'  => $customer
                    ]
                ]
            ];
            // 5. Criar a cobrança com boleto direto
            $charge = $this->api->createOneStepCharge([], $body);
            $charge_id   = $charge['data']['charge_id'];
            $billet_link = $charge['data']['link'];
            // 6. Salvar no banco
            $signature_status_text = 'Cobrança Criada, Aguardando Confirmação de Pgto do Boleto';
            
            $this->updateSignature(
                $userId,
                $plan_id,
                $plan_payment_id,
                $plan_payment_option_id,
                'SINGLE_BILLET',
                null,
                'PENDING',
                $signature_status_text,
                $charge_id,
                $charge_id,
                $billet_link,
                'boosting',
                $payment_price,
                [ 'process_id' => $process_id, 'sale_id' => $sale_id, 'user_id' => $_POST['user_id'] ]
            );

            $this->updateCampaignProcessList($userId, $charge_id);

            return [
                'type' => 'OK',
                'data' => [
                    'id' => $charge_id,
                    'link' => $billet_link
                ]
            ];
        } catch (\Exception $err) {
            return [ 'type' => 'ERROR', 'data' => $err->getMessage() ];
        }
    }

    private function updateMakePaidAccount($email) {

        $sql = "UPDATE companies SET free_account = 0 WHERE companyemail = ?";
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute([ $user['email'] ]);

    }

    private function updateMakeFreeAccount($company_id) {
        
        // $sql = "UPDATE leads SET signature_status = 'ACTIVE', voucher = NULL, signature_date = NOW(), signature_status_text = 'Liberado momentaneamente, esperando autorização da operadora do cartão' WHERE email = ?";
        $sql = "UPDATE company_signatures SET `status` = 'ACTIVE', status_text = 'Liberado momentaneamente, esperando autorização da operadora do cartão' WHERE company_id = ?";
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute([ $company_id ]);

    }

    function cancelSignature() {

        try {
        
            $id = $_GET['id'];
            $user_id = $_GET['userId'];
            $status = isset($_GET['new_status']) ? $_GET['new_status'] : 'CANCELED';
            // $sql = "SELECT companyemail, signature_id FROM companies WHERE id = ?";
            $sql = "SELECT companyemail, signature_id, company_id FROM companies AS C
                LEFT JOIN company_signatures AS CS ON CS.company_id = C.id WHERE C.id = ?";
            $stmt = parent::$conn->prepare($sql);
            $stmt->execute([ $id ]);
            $signature = $stmt->fetch(PDO::FETCH_ASSOC);
            $plan_id = $signature['signature_id'];
            $params = [
                'id' => $plan_id
            ];

            $this->addCancellationProtocol($id);

            if($plan_id !== null){
                $this->api->cancelSubscription($params, []);
                $status_text = ($status === 'CANCELED') ? 'Assinatura cancelada pelo assinante' : 'Periodo de Teste e Assinatura cancelada pelo assinante';
                // $sql = "UPDATE companies SET signature_status = ?, signature_status_text = ?, signature_status_user = ?, signature_status_lastupdate = NOW() WHERE companyemail = ?";
                $sql = "UPDATE company_signatures SET `status` = ?, status_text = ?, status_user = ?, last_uppdate = NOW() WHERE company_id = ?";
                $stmt = parent::$conn->prepare($sql);
                $stmt->execute([ $status, $status_text, $user_id, $signature['company_id'] ]);

                if($stmt->errorCode() != '00000')
                    throw new \Exception(json_encode($stmt->errorInfo()));                

                return [ 'type' => 'OK' ];
            
            }else{

                return [ 'type' => 'FAIL' ];

            }

        } catch(\Exception $err) {
            return [ 'type' => 'ERROR', 'data' => $err->getMessage() ];
            
        }

    }

    function alterPaymentMethod() {

        try {

            /*$user_id = $_POST['userId'];            
            $sql = "SELECT signature_id FROM leads WHERE id = ?";
            $stmt = parent::$conn->prepare($sql);
            $stmt->execute([ $user_id ]);
            $signature = $stmt->fetch(PDO::FETCH_ASSOC);            
            $plan_id = $signature['signature_id'];
            $params = [
                'id' => $plan_id
            ];
            $this->api->cancelSubscription($params, []);*/

            return $this->paymentCreditCard();

        } catch(\Exception $err) {
            return [ 'type' => 'ERROR', 'data' => $err->getMessage() ];

        }

    }
    
    function getDetailSubscription() {
        try {
            $subscriptionId = $_POST['id'];
            $params = ['id' => $subscriptionId];
            $response = $this->api->detailSubscription($params, []);
            return ['type' => 'OK', 'data' => $response];
        } catch (GerencianetException $e) {
            return ['type' => 'ERROR', 'data' => $e->errorDescription];
        } catch (Exception $e) {
            return ['type' => 'ERROR', 'data' => $e->getMessage()];
        }
    }
    
    function getDetailCharge() {
        try {
            $chargeId = $_POST['id'];
            $params = ['id' => $chargeId];
            $response = $this->api->detailCharge($params, []);
            return ['type' => 'OK', 'data' => $response];
        } catch (GerencianetException $e) {
            return ['type' => 'ERROR', 'data' => $e->errorDescription];
        } catch (Exception $e) {
            return ['type' => 'ERROR', 'data' => $e->getMessage()];
        }
    }

    function consultPayments() {

        $id = $_POST['id'] ?? null;

        if (!$id) {
            throw new Exception('ID da assinatura não fornecido.');
        }

        $clientId = $this->env['GERENCIANET_CLIENT_ID'];
        $clientSecret = $this->env['GERENCIANET_CLIENT_SECRET'];
        $client = new \GuzzleHttp\Client();

        // 1) Obter token

        $response = $client->request('POST', "{$this->env['GERENCIANET_COBRANCA_URL']}/v1/authorize", [
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode($clientId . ':' . $clientSecret),
                'Accept'        => 'application/json',
                'Content-Type'  => 'application/json',
            ],
            'body' => json_encode([
                'grant_type' => 'client_credentials'
            ]),
            //'debug' => true
        ]);

        $body = $response->getBody()->getContents();
        $status = $response->getStatusCode();

        if ($status !== 200) {
            throw new Exception("Erro ao obter token. HTTP {$status} - {$body}");
        }

        $json = json_decode($body, true);

        if (empty($json['access_token'])) {
            throw new Exception("Token não retornado. Resposta: {$body}");
        }

        $token = $json['access_token'];

        // 2) Consultar a cobrança

        $response = $client->request('GET', "{$this->env['GERENCIANET_COBRANCA_URL']}/v1/charge/{$id}", [
            'headers' => [
                'Authorization' => 'Bearer ' . $token,
                'Accept'        => 'application/json',
            ],

        ]);

        $retorno = $response->getBody()->getContents();
        $result = json_decode($retorno, true);
        return ['type' => 'OK', 'data' => $result];

    }

    function paymentCardSimple() {
        try {

            $userId = $_POST['userId'];            
            $plan_id = $_POST['plan'];
            $plan_payment_id = $_POST['planPayment'];
            $plan_payment_option_id = $_POST['planPaymentOption'] ?? null;
            
            $payment_name = $_POST['paymentName'];
            $payment_price = $_POST['paymentPrice'];
            $payment_token = $_POST['cardToken'] ?? null;
            $installments  = isset($_POST['installments']) ? intval($_POST['installments']) : 1; //parcelas
                        
            if (empty($payment_token)) {
                throw new \Exception("payment_token não informado. Gere o token no front-end e envie para o servidor.");
            }
    
            // Itens (valor em centavos para a API de charge)
            $items = [
                [
                    'name'   => $payment_name,
                    'amount' => 1,
                    'value'  => intval(floatval($payment_price) * 100) // ex: R$ 10,00 -> 1000
                ]
            ];
    
            $card_holder_name = $_POST['holderName'];
            $address1 = $_POST['street'];
            $address2 = $_POST['number'];
            $city = $_POST['city'];
            $state_uf = $_POST['state'];
            $zipcode = $_POST['zipCode'];
            $neighborhood = $_POST['district'];
            $complement = isset($_POST['complement']) ? $_POST['complement'] : '';
            $email = $_POST['email'];
            $phone = $_POST['mobile'];
            $user_birthdate = DateTime::createFromFormat('dmY', $_POST['birthdate']);
            $user_birthdate = $user_birthdate->format('Y-m-d');
            $birthdate = $user_birthdate;
            $tax_document_number = $_POST['cpf'];
            $companyname = $_POST['companyName'];
            $cnpj = $_POST['cnpj'];
            $process_id = $_POST['processId'] ?? null;
            $sale_id = $_POST['saleId'] ?? null;
            $user_id = $_POST['userId'] ?? null;
    
            $billing_address = [
                'street' => $address1,
                'number' => $address2,
                'neighborhood' => $neighborhood,
                'zipcode' => $zipcode,
                'city' => $city,
                'state' => $state_uf
            ];
            
            $juridical_person = [
                'corporate_name'=> $companyname,
                'cnpj'=> $cnpj
            ];
    
            // Dados do pagador (customer) — a API espera o customer dentro do payment/credit_card ou no root (varia por versão)
            $customer = [
                'name' => $card_holder_name,
                'cpf' => $tax_document_number,
                'email' => $email,
                'phone_number' => $phone                
            ];
    
            // Monta o body para ONE STEP CHARGE com cartão de crédito
            // Atenção: a estrutura pode variar levemente — se a API retornar erro, verifique o JSON de erro e ajuste.
            $body = [
                'items' => $items,
                'metadata' => [
                    'notification_url' => $this->env['GERENCIANET_NOTIFICATION_URL'] // webhook para cobranças (boleto/cartão). Se quiser diferenciar, use sua constante apropriada.
                ],
                'payment' => [
                    'credit_card' => [
                        'payment_token' => $payment_token,
                        'installments' => $installments,
						'billing_address' => $billing_address,
                        // 'capture' => true, // opcional: dependendo do fluxo, pode separar auth/capture. Na maioria dos casos, capture = true.
                        // 'statement_descriptor' => 'Memprega', // opcional
                        'customer' => [
                            'name' => $customer['name'],
                            // passe cpf ou cnpj caso tenha; exemplo abaixo usa cnpj se disponível:
                            'cpf' => $customer['cpf'],
                            'email' => $customer['email'],
                            'phone_number' => $customer['phone_number'],
                            //'address' => $billing_address,
                            'juridical_person' => $juridical_person
                        ]
                    ]
                ]
            ];
    
            // Chama o endpoint One-Step (cria a cobrança e tenta processar o cartão)
            $charge = $this->api->createOneStepCharge([], $body);
    
            // Exemplo de retorno esperado: charge_id, status, payment->card details...
            $charge_id = $charge['data']['charge_id'] ?? null;
            $status_api = $charge['data']['status'] ?? null;
            // dependendo do retorno, pode existir $charge['data']['payment']['credit_card']['status'] etc.
            
            // Salva no banco (ajuste tabela/campos conforme seu schema)
            $signature_status_text = 'Cobrança por cartão criada, aguardando confirmação do pagamento';
            // Agora insere em company_signatures
            
            $this->updateSignature(
                $userId,
                $plan_id,
                $plan_payment_id,
                $plan_payment_option_id,
                'CREDIT_CARD',
                null,
                'PENDING',
                $signature_status_text,
                $charge_id,
                $charge_id,
                null,
                'boosting',
                $payment_price,
                [ 'process_id' => $process_id, 'sale_id' => $sale_id, 'user_id' => $_POST['user_id'] ]
            );

            $this->updateCampaignProcessList($userId, $charge_id);
            
            return [
                'type' => 'OK',
                'data' => [
                    'id' => $charge_id
                ]
            ];
        } catch (\Exception $err) {
            return [ 'type' => 'ERROR', 'data' => $err->getMessage() ];
        }
    }

}