<?php 
/**
 * @package    Proxim
 * @author     Davison Pro <davisonpro.coder@gmail.com | https://davisonpro.dev>
 * @copyright  2019 Proxim
 * @version    1.0.0
 * @since      File available since Release 1.0.0
 */

namespace Proxim;

use Db;
use Proxim\Database\DbQuery;
use Proxim\Route;
use Proxim\Configuration;
use Proxim\Tools;
use Proxim\Validate;
use Proxim\Currency;
use Proxim\Mail;
use Proxim\Site\Site;
use Proxim\User\Employee;
use Proxim\Order\Order;
use Proxim\User\Customer;
use Proxim\Order\PayPalPayment;
use Proxim\Order\AdditionalService;
use Proxim\Util\DateUtils;
use Proxim\Util\ArrayUtils;

class PaypalCheckout extends Route {

    public function verifyPayment() {
        global $globals;
		$app = $this->app;
        $payload = $app->request->post();
        $user = $app->container->user;

        $options = array();

        $handle = ArrayUtils::get($payload, 'handle');
        $nodeId = ArrayUtils::get($payload, 'nodeId');
        $paymentId = ArrayUtils::get($payload, 'paymentId');
        $payerId = ArrayUtils::get($payload, 'payerId');

        switch( $handle ) {
            case 'order':
                try {
                    $order = new Order( (int) $nodeId);

                    if (!Validate::isLoadedObject($order)) {
                        return $app->response([
                            'success' => false
                        ]);
                    }

                    $currency = $order->currency;

                    $options['currency'] = array(
                        'symbol' => $currency->symbol,
                        'rate' => $currency->conversion_rate
                    );

                    $paypalPayment = new PayPalPayment();
                    $paypalPayment->status_id = PayPalPayment::STATE_COMPLETE;
                    $paypalPayment->node_type = PayPalPayment::TYPE_ORDER;
                    $paypalPayment->node_id = $order->id;
                    $paypalPayment->amount = $order->total;
                    $paypalPayment->add();

                    $order->total_paid = $order->total_paid + $order->total;
                    $old_status = $order->status_id;

                    if ( 
                        $old_status == Order::FAKE || 
                        $old_status == Order::FREE_INQUIRY || 
                        $old_status == Order::INQUIRY
                    ) {
                        $customer_deadline = time() + ($order->hrs_customer*60*60);
                        $writer_deadline = time() + ($order->hrs_writer*60*60);
                        $order->customer_deadline = DateUtils::date($customer_deadline);
                        $order->writer_deadline = DateUtils::date($writer_deadline);

                        if ($order->progressive_delivery) {
                            $order->status_id = Order::NEW_PAID;
                        } else {
                            $order->status_id = Order::ORDER_PUBLISHED;
                        }

                        $order->is_paid = 1;
                        $order->paid_at = DateUtils::now();
                    }

                    $order->update();

                    if ( 
                        $old_status == Order::FAKE || 
                        $old_status == Order::FREE_INQUIRY || 
                        $old_status == Order::INQUIRY
                    ) {
                        $customer = new Customer( (int) $order->customer_id );
                        if(Validate::isLoadedObject($customer)) {
                            $customer->total_spent = $customer->total_spent + $order->total;
                            $customer->update();

                            /** process affiliates */
                            if ( $customer->referrer_id && !$customer->affiliate_used ) {
                                $app->processAffiliates( $customer->id, $customer->referrer_id );
                            }

                            $site = new Site( (int) $customer->site_id );
                            if( Validate::isLoadedObject($site) ) {
                                $site->orders = $site->orders+1;       
                                $site->payments = $site->payments + $order->total;
                                $site->update();
                            }

                            try {
                                $mailParams = array(
                                    'order_id' => $order->id,
                                    'title' => $order->title,
                                    'pages' => $order->pages,
                                    'payment_method' => Tools::ucfirst($order->payment_method),
                                    'paid_at' => DateUtils::date( strtotime($order->paid_at) , null, 'M jS, Y \\a\\t g:i A'),
                                    'paid_amount' => formatPrice($order->total, $options),
                                    'type' => 'order',
                                    'admin_site_name' => Configuration::get('SITE_NAME', PROX_ADMIN_SITE_ID, null),
                                    'admin_order_url' => Configuration::get('SITE_DOMAIN', PROX_ADMIN_SITE_ID, $app->base_uri) . '/order/' . (int) $order->id,
                                    'order_url' => $app->base_uri . '/dashboard/order/' . (int) $order->id,
                                );

                                Mail::Send(
                                    'payment',
                                    'Payment confirmation for order #' . $order->id,
                                    $mailParams,
                                    $customer->email
                                );

                                $receivers = array();
                                $receivers[] = Configuration::get('SITE_EMAIL', PROX_ADMIN_SITE_ID, null);

                                $sql = new DbQuery();
                                $sql->select('e.email');
                                $sql->from('employee', 'e');
                                $sql->where('employee_group = ' . (int) Employee::GROUP_WRITER);
                                $sql->where('is_started = 1');
                                $sql->where('is_banned = 0');
                                $result = Db::getInstance(PROX_USE_SQL_SLAVE)->executeS($sql);

                                foreach ($result as $writer) {
                                    if( ArrayUtils::has($writer, 'email') && Validate::isEmail(ArrayUtils::get($writer, 'email')) ) {
                                        $receivers[] = ArrayUtils::get($writer, 'email');
                                    }
                                }

                                foreach ($receivers as $receiver) {
                                    Mail::Send(
                                        'new_order',
                                        'New Order #' . $order->id . ' available',
                                        $mailParams,
                                        $receiver,
                                        null,
                                        null,
                                        null,
                                        null,
                                        null,
                                        null,
                                        null,
                                        null,
                                        null,
                                        null,
                                        PROX_ADMIN_SITE_ID
                                    );
                                }
                            } catch(\Exception $e) {

                            }
                        }
                    }

                    return $app->response([
                        'success' => true
                    ]);
                } catch(\Exception $e) {	
                    return $app->response([
                        'success' => false
                    ]);
                }
                break;

            case 'add-payment':
                try {
                    $addPayment = new AdditionalService( (int) $nodeId);
                    if (!Validate::isLoadedObject($addPayment)) {
                        return $app->response([
                            'success' => false
                        ]);
                    }
        
                    $order = new Order( (int) $addPayment->order_id );
                    if (!Validate::isLoadedObject($order)) {
                        return $app->response([
                            'success' => false
                        ]);
                    }

                    if (!$addPayment->is_paid) {
                        // pages
                        if($addPayment->pages) $order->pages = $order->pages + $addPayment->pages;
        
                        // charts
                        if($addPayment->charts) $order->charts = $addPayment->charts + $addPayment->charts;
        
                        // slides
                        if($addPayment->slides) $order->slides = $addPayment->slides + $addPayment->slides;
        
                        // writer samples
                        if($addPayment->writer_samples) $order->writer_samples = 1;
        
                        // used sources
                        if($addPayment->used_sources) $order->used_sources = 1;
        
                        // expert proofreading
                        if($addPayment->expert_proofreading) $order->expert_proofreading = 1;
        
                        // progressive delivery
                        if($addPayment->progressive_delivery) $order->progressive_delivery = 1;
        
                        // writer category 
                        if($addPayment->writer_category_id) $order->writer_category_id = $addPayment->writer_category_id;
        
                        // shorten deadline
                        if($addPayment->tariff_id) {
                            $tariff = ArrayUtils::get($globals['deadlines'], $addPayment->tariff_id);
                            if ( $tariff ) {
                                $price_per_page = (float) ArrayUtils::get($tariff, 'pricePerPage');
                                $hrs_customer = (int) ArrayUtils::get($tariff, 'hrs');
                                $hrs_writer = (int) ArrayUtils::get($tariff, 'hrsWriter');
                                $customer_deadline = time() + ($hrs_customer*60*60);
                                $writer_deadline = time() + ($hrs_writer*60*60);
        
                                $order->tariff_id = $addPayment->tariff_id;
                                $order->price_per_page = $price_per_page;
                                $order->hrs_customer = $hrs_customer;
                                $order->hrs_writer = $hrs_writer;
                                $order->customer_deadline = DateUtils::date($customer_deadline);
                                $order->writer_deadline = DateUtils::date($writer_deadline);
                            }
                        } 
        
                        $order->update();
        
                        $addPayment->is_paid = 1;
                        $addPayment->paid_at = DateUtils::now();
                        $addPayment->update();
        
                        $customer = new Customer( (int) $order->customer_id );
                        if(Validate::isLoadedObject($customer)) {
                            $customer->total_spent = $customer->total_spent + $addPayment->total;
                            $customer->update();
        
                            $site = new Site( (int) $customer->site_id );
                            if( Validate::isLoadedObject($site) ) {
                                $site->payments = $site->payments + $addPayment->total;
                                $site->update();
                            }
                        }
                    }
        
                    return $app->response([
                        'success' => true
                    ]);
                } catch(\Exception $e) {	
                    return $app->response([
                        'success' => false
                    ]);
                }
                break;

            default:
                return $app->response([
                    'success' => false
                ]);
                break;
        }

    }
}