<?php

$app->get('/', function ($request, $response, $args) {
    if ($this->session->exists('user_id')) {
        $args['loggedIn'] = true;
        $api = new Api($this);
        $args['admin'] = $api->CheckAdmin();
        $args['jenuPublication'] = $this->jenuPublication;
        return $this->renderer->render($response, 'index.phtml', $args);
    }

    return $response->withRedirect($this->router->pathFor('autentificare'), 303);
})->setName('home');

$app->get('/contul-meu', function ($request, $response, $args) {
    if ($this->session->exists('user_id')) {
        $api = new Api($this);
        $params = $request->getQueryParams();
        $quotes = $api->GetUserQuotes($params);
        $args["quotes"] = $quotes["quotes"];
        $args["total"] = $quotes["total"];
        $args["loggedIn"] = true;
        $args["statuses"] = $api->QuoteStatuses();
        $args["adTypes"] = $api->AdTypes();
        $args['admin'] = $api->CheckAdmin();

        return $this->renderer->render($response, 'cotatii.phtml', $args);
    }

    return $response->withRedirect($this->router->pathFor('home'), 303);
})->setName('profile');

$app->get('/admin/cotatii', function ($request, $response, $args) {
    if ($this->session->exists('user_id')) {
        $api = new Api($this);
        $isAdmin = $api->CheckAdmin();
        if ($isAdmin) {
            $params = $request->getQueryParams();
            $quotes = $api->GetAdminQuotes($params);
            $args["quotes"] = $quotes["quotes"];
            $args["total"] = $quotes["total"];
            $args["loggedIn"] = true;
            $args["statuses"] = $api->QuoteStatuses();
            $args["adTypes"] = $api->AdTypes();
            $args['admin'] = $api->CheckAdmin();

            return $this->renderer->render($response, 'cotatii-admin.phtml', $args);
        }

        return $response->withRedirect($this->router->pathFor('home'), 303);
    }

    return $response->withRedirect($this->router->pathFor('home'), 303);
})->setName('profile');

$app->post('/quote/{id}/update', function ($request, $response, $args) {
    if ($this->session->exists('user_id')) {
        $api = new Api($this);
        $params = $request->getParsedBody();
        $fields = [
            "id" => $request->getAttribute('id'),
            "status" => 2
        ];

        if (!empty($params["price"])) {
            $fields["price"] = $params["price"];
        }

        if (!empty($params["status"])) {
            $fields["status"] = $params["status"];
        }

        if (!empty($params["adText"])) {
            $fields["adText"] = $params["adText"];
        }

        $fields["fromUser"] = true;

        $updated = $api->UpdateQuote($fields);

        if ($updated) {
            return $response->withJson(['success' => 'Updated']);
        }

        return $response->withJson(['error' => 'Failed']);
    }

    return $response->withJson(['error' => 'Unauthenticated']);
});

$app->get('/uploads/{id}', function ($request, $response, $args) {
    if ($this->session->exists('user_id')) {
        $api = new Api($this);
        $quote = $api->GetQuote($request->getAttribute('id'));
        if ($quote) {
            $file = __DIR__ . '/../uploads/' . $quote['file'];
            $fh = fopen($file, 'rb');

            if ($fh) {
                $stream = new \Slim\Http\Stream($fh); // create a stream instance for the response body

                return $response->withHeader('Content-Type', 'application/force-download')
                    ->withHeader('Content-Type', 'application/octet-stream')
                    ->withHeader('Content-Type', 'application/download')
                    ->withHeader('Content-Description', 'File Transfer')
                    ->withHeader('Content-Transfer-Encoding', 'binary')
                    ->withHeader('Content-Disposition', 'attachment; filename="' . basename($file) . '"')
                    ->withHeader('Expires', '0')
                    ->withHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
                    ->withHeader('Pragma', 'public')
                    ->withBody($stream); // all stream contents will be sent to the response
            }
            return $response->withRedirect($this->router->pathFor('profile'), 303);
        }


        return $response->withRedirect($this->router->pathFor('profile'), 303);
    }

    return $response->withRedirect($this->router->pathFor('home'), 303);
});

$app->delete('/quotation/{id}', function ($request, $response, $args) {
    if ($this->session->exists('user_id')) {
        $api = new Api($this);

        $quoteDeleted = $api->DeleteQuote($request->getAttribute('id'));

        if ($quoteDeleted) {
            return $response->withJson(['success' => true]);
        }

        return $response->withJson(['error' => false]);
    }

    return $response->withJson(['error' => 'not logged in']);
});

$app->post('/quotation', function ($request, $response, $args) {
    if ($this->session->exists('user_id')) {
        $params = $request->getParsedBody();
        $files = $request->getUploadedFiles();

        if (empty($files['quoteFile'])) {
            throw new Exception('Image file expected');
        }

        $api = new Api($this);
        // print_r($params);
        // die();
        $quoteSaved = $api->AddQuote($params, $files["quoteFile"]);

        return $response->withJson(['success' => true]);
    }

    return $response->withJson(['error' => 'not logged in']);
});

$app->get('/logout', function ($request, $response, $args) {
    if ($this->session->exists("user_id")) {
        $this->session->delete('user_id');
        return $response->withRedirect($this->router->pathFor('autentificare'), 303);
    }

    return $response->withRedirect($this->router->pathFor('home'), 303);
});

$app->get('/users/profile', function ($request, $response, $args) {
    if ($this->session->exists('user_id')) {
        $api = new Api($this);
        $profile = $api->FetchUserProfile();

        return $response->withJson($profile);
    }

    return $response->withJson(['error' => 'not logged in']);
});

$app->get('/autentificare', function ($request, $response, $args) {
    if (!$this->session->exists('user_id')) {
        $args["errors"] = $this->flash->getMessages();
        return $this->renderer->render($response, 'autentificare.phtml', $args);
    }

    return $response->withRedirect($this->router->pathFor('home'), 303);

})->setName('autentificare');

$app->get('/inregistrare', function ($request, $response, $args) {
    if (!$this->session->exists('user_id')) {
        $args["errors"] = $this->flash->getMessages();
        return $this->renderer->render($response, 'inregistrare.phtml', $args);
    }

    return $response->withRedirect($this->router->pathFor('home'), 303);

})->setName('inregistrare');


$app->get('/verificare-cont/', function ($request, $response, $args) {
    if (!$this->session->exists('user_id')) {
        $params = $request->getQueryParams();

        if (!empty($params)) {
            $api = new API($this);
            $resp = $api->VerifyAccount($params);
            // TODO check why the messages are not working on auth page
            if ($resp) {
                $this->flash->addMessage("success", "Verificarea contului a fost efectuata.");
            } else {
                $this->flash->addMessage("error", "Verificarea contului a esuat.");
            }
        }

        return $response->withRedirect($this->router->pathFor('autentificare'), 303);
    }

    return $response->withRedirect($this->router->pathFor('home'), 303);

})->setName('verificare-cont');

$app->post('/inregistrare', function ($request, $response, $args) {
    if (!$this->session->exists('user_id')) {
        $api = new API($this);

        if (empty($args)) {
            $args = array();
        }

        $params = $request->getParsedBody();


        if (!empty($params)) {
            $res = $api->RegisterUser($params);
            if (!empty($res)) {
                if ($res['info']['http_code'] !== 200) {
                    $this->flash->addMessage("error", "Inregistrarea a esuat");
                    return $response->withRedirect($this->router->pathFor('inregistrare'), 303);
                } else {
                    return $response->withRedirect($this->router->pathFor('autentificare'), 303);
                }
            }
        }
    }

    return $response->withRedirect($this->router->pathFor('home'), 303);

})->setName('inregistrare');

$app->post('/autentificare', function ($request, $response, $args) {
    $api = new API($this);

    if (empty($args)) {
        $args = array();
    }

    $params = $request->getParsedBody();

    if (!empty($params)) {
        $res = $api->AuthenticateUser($params);
        if (!empty($res)) {
            if ($res['info']['http_code'] !== 200) {
                $this->flash->addMessage("error", "Credentiale invalide");
                return $response->withRedirect($this->router->pathFor('autentificare'), 303);
            } else {
                return $response->withRedirect($this->router->pathFor('home'), 303);
            }
        }
    }
});

$app->post('/confirm-payment', function ($request, $response, $args) {
    require_once 'Mobilpay/Payment/Request/Abstract.php';
    require_once 'Mobilpay/Payment/Request/Card.php';
    require_once 'Mobilpay/Payment/Request/Notify.php';
    require_once 'Mobilpay/Payment/Invoice.php';
    require_once 'Mobilpay/Payment/Address.php';
    $errorCode = 0;
    $errorType = Mobilpay_Payment_Request_Abstract::CONFIRM_ERROR_TYPE_NONE;
    $errorMessage = '';
    if (strcasecmp($_SERVER['REQUEST_METHOD'], 'post') == 0) {
        if (isset($_POST['env_key']) && isset($_POST['data'])) {
            #calea catre cheia privata
            #cheia privata este generata de mobilpay, accesibil in Admin -> Conturi de comerciant -> Detalii -> Setari securitate
            $params = $request->getParsedBody();

            global $settings;
            $paymentSettings = $settings['settings']['payments'];

            $privateKeyFilePath = $paymentSettings["privateCertificate"];
            try {
                $objPmReq = Mobilpay_Payment_Request_Abstract::factoryFromEncrypted($params['env_key'], $params['data'], $privateKeyFilePath);
                #uncomment the line below in order to see the content of the request
                // print_r($objPmReq);
                $rrn = $objPmReq->objPmNotify->rrn;

                $api = new API($this);
                $id = $objPmReq->params["ad"];
                if (!empty($objPmReq->params["quote"])) {
                    $quoteId = $objPmReq->params["quote"];
                }
                $amount = $objPmReq->invoice->amount;
                $transaction = $objPmReq->orderId;

                // action = status only if the associated error code is zero
                if ($objPmReq->objPmNotify->errorCode == 0) {
                    switch ($objPmReq->objPmNotify->action) {
                        #orice action este insotit de un cod de eroare si de un mesaj de eroare. Acestea pot fi citite folosind $cod_eroare = $objPmReq->objPmNotify->errorCode; respectiv $mesaj_eroare = $objPmReq->objPmNotify->errorMessage;
                        #pentru a identifica ID-ul comenzii pentru care primim rezultatul platii folosim $id_comanda = $objPmReq->orderId;
                        case 'confirmed':
                            #cand action este confirmed avem certitudinea ca banii au plecat din contul posesorului de card si facem update al starii comenzii si livrarea produsului
                            //update DB, SET status = "confirmed/captured"
                            $api->MarkPayment($id, $amount, $transaction);
                            if (isset($quoteId)) {
                                $api->UpdateQuote([
                                    "status" => 4,
                                    "id" => $quoteId,
                                    "payment" => true
                                ]);
                            }
                            $errorMessage = $objPmReq->objPmNotify->errorMessage;
                            break;
                        case 'confirmed_pending':
                            #cand action este confirmed_pending inseamna ca tranzactia este in curs de verificare antifrauda. Nu facem livrare/expediere. In urma trecerii de aceasta verificare se va primi o noua notificare pentru o actiune de confirmare sau anulare.
                            //update DB, SET status = "pending"
                            $errorMessage = $objPmReq->objPmNotify->errorMessage;
                            break;
                        case 'paid_pending':
                            #cand action este paid_pending inseamna ca tranzactia este in curs de verificare. Nu facem livrare/expediere. In urma trecerii de aceasta verificare se va primi o noua notificare pentru o actiune de confirmare sau anulare.
                            //update DB, SET status = "pending"
                            $errorMessage = $objPmReq->objPmNotify->errorMessage;
                            break;
                        case 'paid':
                            #cand action este paid inseamna ca tranzactia este in curs de procesare. Nu facem livrare/expediere. In urma trecerii de aceasta procesare se va primi o noua notificare pentru o actiune de confirmare sau anulare.
                            //update DB, SET status = "open/preauthorized"
                            $errorMessage = $objPmReq->objPmNotify->errorMessage;
                            break;
                        case 'canceled':
                            #cand action este canceled inseamna ca tranzactia este anulata. Nu facem livrare/expediere.
                            //update DB, SET status = "canceled"
                            $errorMessage = $objPmReq->objPmNotify->errorMessage;
                            $api->CancelDraft($id);
                            if (isset($quoteId)) {
                                $api->UpdateQuote([
                                    "status" => 8,
                                    "id" => $quoteId,
                                    "payment" => true
                                ]);
                            }
                            break;
                        case 'credit':
                            #cand action este credit inseamna ca banii sunt returnati posesorului de card. Daca s-a facut deja livrare, aceasta trebuie oprita sau facut un reverse.
                            //update DB, SET status = "refunded"
                            $errorMessage = $objPmReq->objPmNotify->errorMessage;
                            break;
                        default:
                            $errorType = Mobilpay_Payment_Request_Abstract::CONFIRM_ERROR_TYPE_PERMANENT;
                            $errorCode = Mobilpay_Payment_Request_Abstract::ERROR_CONFIRM_INVALID_ACTION;
                            $errorMessage = 'mobilpay_refference_action paramaters is invalid';
                            break;
                    }
                } else {
                    //update DB, SET status = "rejected"
                    $api->CancelDraft($id);
                    if (isset($quoteId)) {
                        $api->UpdateQuote([
                            "status" => 5,
                            "id" => $quoteId,
                            "payment" => true
                        ]);
                    }
                    $errorMessage = $objPmReq->objPmNotify->errorMessage;
                }
            } catch (Exception $e) {
                $errorType = Mobilpay_Payment_Request_Abstract::CONFIRM_ERROR_TYPE_TEMPORARY;
                $errorCode = $e->getCode();
                $errorMessage = $e->getMessage();
            }
        } else {
            $errorType = Mobilpay_Payment_Request_Abstract::CONFIRM_ERROR_TYPE_PERMANENT;
            $errorCode = Mobilpay_Payment_Request_Abstract::ERROR_CONFIRM_INVALID_POST_PARAMETERS;
            $errorMessage = 'mobilpay.ro posted invalid parameters';
        }
    } else {
        $errorType = Mobilpay_Payment_Request_Abstract::CONFIRM_ERROR_TYPE_PERMANENT;
        $errorCode = Mobilpay_Payment_Request_Abstract::ERROR_CONFIRM_INVALID_POST_METHOD;
        $errorMessage = 'invalid request metod for payment confirmation';
    }
    header('Content-type: application/xml');
    echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
    if ($errorCode == 0) {
        echo "<crc>{$errorMessage}</crc>";
    } else {
        echo "<crc error_type=\"{$errorType}\" error_code=\"{$errorCode}\">{$errorMessage}</crc>";
    }
});

$app->map(array('GET', 'POST'), '/finalizare', function ($request, $response, $args) {
    if (empty($args)) {
        $args = array();
    }
    $args['ok'] = true;

    $api = new API();

    $params = array();
    $params = $request->getQueryParams();

    if (empty($params)) {
        $args['ok'] = false;
        $api->CancelDraft($params['ad']);
    }

    // $id = $params['ad'];
    // $amount = $params['Amount'];
    // $transaction = $params['RefNo'];

    // if (empty($api->MarkPayment($id, $amount, $transaction))) {
    //     $args['ok'] = false;
    //     $api->CancelDraft($id);
    // }

    return $this->renderer->render($response, 'finalizare.phtml', $args);
});

$app->post('/payment-quote', function ($request, $response, $args) {
    $api = new API();

    $params = $request->getParsedBody();
    if (empty($params['ad_id'])) {
        throw new Exception('Must provide ad id');
    }

    if (empty($params['quote_id'])) {
        throw new Exception('Must provide quote id');
    }

    $data = $api->GetAd($params['ad_id']);
    if (empty($data['data'])) {
        throw new Exception('Could not get ad');
    }

    if (empty($data['data']['id'])) {
        throw new Exception('Could not get ad id');
    }
    $order = $data['data']['id'];

    if (empty($data['data']['invoiceValue']['total'])) {
        throw new Exception('Could not get ad price');
    }

    $amount = $data['data']['invoiceValue']['total'];

    if (empty($data['data']['contact'])) {
        throw new Exception('Could not get ad contact');
    }
    $contact = $data['data']['contact'];

    global $settings;
    $paymentSettings = $settings['settings']['payments'];

    $billing = array(
        'billFName' => $contact['firstName'],
        'billLName' => $contact['lastName'],
        'billEmail' => $contact['email'],
        'billPhone' => $contact['phone'],
        'billAddress1' => $contact['address'],
        'billCountryCode' => 'RO'
    );

    if ($contact['type'] == 2) {
        $billing['billCompany'] = $contact['name'];
        $billing['billFiscalCode'] = $contact['vat'];
        $billing['billRegNumber'] = $contact['crn'];
        $billing['billBank'] = $contact['bank'];
        $billing['billBankAccount'] = $contact['iban'];
    } else {
        $billing['billCNP'] = $contact['nin'];
    }

    $data = array(
        'paymentSettings' => $paymentSettings,
        // 'debug' => false,
        // 'language' => 'ro',
        'billing' => $billing,
        'order' => array(
            'date' => date('Y-m-d H:i:s'),
            'name' => sprintf('Publicare anunt %d', $order),
            'reference' => $order,
            'amount' => $amount,
        )
    );

    if (!empty($params['quote_id'])) {
        $data['order']['quote_id'] = $params['quote_id'];
    }

    $args['data'] = $data;
    return $this->renderer->render($response, 'payment.phtml', $args);
});

$app->post('/payment', function ($request, $response, $args) {
    $api = new API();

    $params = $request->getParsedBody();
    if (empty($params['ad_id'])) {
        throw new Exception('Must provide ad id');
    }

    $data = $api->GetAd($params['ad_id']);
    if (empty($data['data'])) {
        throw new Exception('Could not get ad');
    }

    if (empty($data['data']['id'])) {
        throw new Exception('Could not get ad id');
    }
    $order = $data['data']['id'];

    if (empty($data['data']['invoiceValue']['total'])) {
        throw new Exception('Could not get ad price');
    }

    $amount = $data['data']['invoiceValue']['total'];

    if (empty($data['data']['contact'])) {
        throw new Exception('Could not get ad contact');
    }
    $contact = $data['data']['contact'];

    global $settings;
    $paymentSettings = $settings['settings']['payments'];

    $billing = array(
        'billFName' => $contact['firstName'],
        'billLName' => $contact['lastName'],
        'billEmail' => $contact['email'],
        'billPhone' => $contact['phone'],
        'billAddress1' => $contact['address'],
        'billCountryCode' => 'RO'
    );

    if ($contact['type'] == 2) {
        $billing['billCompany'] = $contact['name'];
        $billing['billFiscalCode'] = $contact['vat'];
        $billing['billRegNumber'] = $contact['crn'];
        $billing['billBank'] = $contact['bank'];
        $billing['billBankAccount'] = $contact['iban'];
    } else {
        $billing['billCNP'] = $contact['nin'];
    }

    $data = array(
        'paymentSettings' => $paymentSettings,
        // 'debug' => false,
        // 'language' => 'ro',
        'billing' => $billing,
        'order' => array(
            'date' => date('Y-m-d H:i:s'),
            'name' => sprintf('Publicare anunt %d', $order),
            'reference' => $order,
            'amount' => $amount,
        )
    );

    $args['data'] = $data;
    return $this->renderer->render($response, 'payment.phtml', $args);
});

$app->get('/listing', function ($request, $response, $args) {
    $api = new API();

    $pubs = $api->GetPublications();
    return $response->withJson($pubs['data'], $pubs['info']['http_code']);
});

$app->get('/columns/{id}', function ($request, $response) {
    $api = new API();

    $pubs = $api->GetPublicationsExt($request->getAttribute('id'));
    return $response->withJson($pubs['data'], $pubs['info']['http_code']);
});

$app->post('/summary', function ($request, $response, $args) {
    $api = new API();

    $price = $api->GetPrice($request->getParsedBody());
    return $response->withJson($price['data'], $price['info']['http_code']);
});

$app->post('/createDraft', function ($request, $response, $args) {
    $api = new API();

    $data = $api->CreateDraft($request->getParsedBody());
    if (empty($data['data']['id'])) {
        throw new Exception('Could not create ad');
    }

    $ret = array('ad_id' => $data['data']['id']);
    return $response->withJson($ret, $data['info']['http_code']);
});

$app->post('/uploadImage', function ($request, $response, $args) {
    $id = $request->getParam('id', false);
    if (empty($id)) {
        throw new Exception('Ad id expected');
    }

    $files = $request->getUploadedFiles();
    if (empty($files['file'])) {
        throw new Exception('Image file expected');
    }

    $file = $files['file'];
    $path = '/tmp/' . uniqid('', true) . '_' . $file->getClientFilename();
    $file->moveTo($path);

    $curlFile = curl_file_create($path,
        $file->getClientMediaType(), $file->getClientFilename());

    $api = new API();
    $resp = $api->UploadImage($id, ['file' => $curlFile,
        'readyDTP' => 'false']);

    unlink($path);
    return $response->withJson($resp['data'], $resp['info']['http_code']);
});
