<?php

namespace App\Controller\Member;

use App\Controller\Member\AppMemberController;
use Cake\Network\Http\Client;
use Cake\Event\Event;
use Cake\Routing\Router;
use Cake\Network\Exception\NotFoundException;

class CampaignsController extends AppMemberController
{

    public function initialize()
    {
        parent::initialize();
    }

    public function beforeFilter(Event $event)
    {
        parent::beforeFilter($event);
        if (in_array($this->request->action, ['ipn'])) {
            $this->eventManager()->off($this->Csrf);
            $this->eventManager()->off($this->Security);
        }
        $this->Auth->allow(['ipn']);
    }

    public function isAuthorized($user = null)
    {
        // All registered users can add articles
        if ($this->request->action === 'add') {
            return true;
        }

        // The owner of an article can edit and delete it
        if (in_array($this->request->action, ['pay', 'pause', 'resume'])) {
            $id = (int) $this->request->params['pass'][0];
            return $this->Campaigns->isOwnedBy($id, $user['id']);
        }

        return parent::isAuthorized($user);
    }

    public function view($id = null)
    {
        if (!$id) {
            throw new NotFoundException(__('Invalid campaign'));
        }

        $campaign = $this->Campaigns->findById($id)
            ->contain(['CampaignItems'])
            ->where(['user_id' => $this->Auth->user('id')])
            ->first();
        if (!$campaign) {
            throw new NotFoundException(__('Campaign Not Found'));
        }

        $this->set('campaign', $campaign);
    }

    public function index()
    {
        $query = $this->Campaigns->find()
            ->contain(['CampaignItems'])
            ->where(['user_id' => $this->Auth->user('id')]);
        $campaigns = $this->paginate($query);

        $this->set('campaigns', $campaigns);
    }

    public function create()
    {
        $campaign = $this->Campaigns->newEntity(null, ['associated' => ['CampaignItems']]);
        if ($this->request->is('post')) {
            $campaign->user_id = $this->Auth->user('id');
            $campaign->ad_id = 1;
            $campaign->status = 'Pending Payment';

            $this->request->data['price'] = 0;

            foreach ($this->request->data['campaign_items'] as $key => $value) {
                if (empty($value['purchase'])) {
                    unset($this->request->data['campaign_items'][$key]);
                    continue;
                }
                $this->request->data['price'] += $value['purchase'] * $value['advertiser_price'];
            }

            $campaign = $this->Campaigns->patchEntity($campaign, $this->request->data);

            if ($this->Campaigns->save($campaign)) {
                $this->Flash->success(__('Your campaign has been added. After payiny, we will review it and it will appear on the website.'));
                $return_url = Router::url(['controller' => 'Campaigns', 'action' => 'create'], true);
                $paymentData = [
                    'business' => get_option('paypal_email'),
                    'cmd' => '_xclick',
                    'currency_code' => get_option('currency_code'),
                    'amount' => $campaign->price,
                    'item_name' => get_option('site_name') . ' Advertising Campaign #' . $campaign->id,
                    'item_number' => $campaign->id,
                    'page_style' => 'paypal',
                    'return' => $return_url,
                    'rm' => '0',
                    'cancel_return' => $return_url,
                    'custom' => $campaign->id,
                    'no_shipping' => 1,
                    'lc' => 'US'
                ];
                $query = http_build_query($paymentData, '&amp;');

                $paypalURL = 'https://www.sandbox.paypal.com/cgi-bin/webscr?';

                if (get_option('paypal_sandbox', 'no') == 'no') {
                    $paypalURL = 'https://www.paypal.com/cgi-bin/webscr?';
                }

                return $this->redirect($paypalURL . $query);
                //return $this->redirect( ['action' => 'create' ] );
            } else {
                $this->Flash->error(__('Unable to create your campaign.'));
            }
        }
        $this->set('campaign', $campaign);
    }

    public function pay($id)
    {
        $this->request->allowMethod(['post', 'put']);

        $campaign = $this->Campaigns->findById($id)
            ->where(['user_id' => $this->Auth->user('id')])
            ->where(['status' => 'Pending Payment'])
            ->first();

        if (!$campaign) {
            $this->Flash->success(__('Campaign not found'));
            return $this->redirect(['action' => 'view', $id]);
        }


        $return_url = Router::url(['controller' => 'Campaigns', 'action' => 'view', $id], true);
        $paymentData = [
            'business' => get_option('paypal_email'),
            'cmd' => '_xclick',
            'currency_code' => get_option('currency_code'),
            'amount' => $campaign->price,
            'item_name' => get_option('site_name') . ' Advertising Campaign #' . $campaign->id,
            'item_number' => $campaign->id,
            'page_style' => 'paypal',
            'return' => $return_url,
            'rm' => '0',
            'cancel_return' => $return_url,
            'custom' => $campaign->id,
            'no_shipping' => 1,
            'lc' => 'US'
        ];
        $query = http_build_query($paymentData, '&amp;');

        $paypalURL = 'https://www.sandbox.paypal.com/cgi-bin/webscr?';

        if (get_option('paypal_sandbox', 'no') == 'no') {
            $paypalURL = 'https://www.paypal.com/cgi-bin/webscr?';
        }

        return $this->redirect($paypalURL . $query);
    }

    public function pause($id)
    {
        $this->request->allowMethod(['post', 'put']);

        $campaign = $this->Campaigns->findById($id)
            ->where(['user_id' => $this->Auth->user('id')])
            ->where(['status' => 'Active'])
            ->first();

        if (!$campaign) {
            $this->Flash->success(__('Campaign not found'));
            return $this->redirect(['action' => 'index']);
        }

        $campaign->status = 'Paused';
        $this->Campaigns->save($campaign);

        return $this->redirect(['action' => 'index']);
    }

    public function resume($id)
    {
        $this->request->allowMethod(['post', 'put']);

        $campaign = $this->Campaigns->findById($id)
            ->where(['user_id' => $this->Auth->user('id')])
            ->where(['status' => 'Paused'])
            ->first();

        if (!$campaign) {
            $this->Flash->success(__('Campaign not found'));
            return $this->redirect(['action' => 'index']);
        }

        $campaign->status = 'Active';
        $this->Campaigns->save($campaign);

        return $this->redirect(['action' => 'index']);
    }

    public function ipn()
    {
        $this->autoRender = false;
        
        $message = '';

        if (!empty($this->request->data)) {
            $http = new Client();

            $this->request->data['cmd'] = '_notify-validate';

            // https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNTesting/?mark=IPN%20troubleshoot#invalid

            $paypalURL = 'https://www.sandbox.paypal.com/cgi-bin/webscr?';

            if (get_option('paypal_sandbox', 'no') == 'no') {
                $paypalURL = 'https://www.paypal.com/cgi-bin/webscr?';
            }

            $response = $http->post($paypalURL, $this->request->data);
            $res = $response->body;

            $campaign_id = (int) $this->request->data['custom'];
            $campaign = $this->Campaigns->get($campaign_id);

            if (strcmp($res, "VERIFIED") == 0) {
                // PAYMENT VALIDATED & VERIFIED!


                switch ($this->request->data['payment_status']) {
                    case 'Refunded':
                        $campaign->status = 'Refunded';
                        break;
                    default: // Completed
                        $campaign->status = 'Under Review';
                        break;
                }

                $campaign->transaction_id = $this->request->data['txn_id'];
                $campaign->transaction_details = serialize($this->request->data);
                $this->Campaigns->save($campaign);
                $message = 'VERIFIED';
            } elseif (strcmp($res, "INVALID") == 0) {
                // PAYMENT INVALID & INVESTIGATE MANUALY!
                $campaign->status = 'Invalid Payment';
                $this->Campaigns->save($campaign);
                $message = 'INVALID';
            }
        }

        $this->set('message', $message);
    }
}
