<?php
/**
 * Basket AJAX functionality file
 * Used to handle basket requests
 *
 * @author Martins Fridenbergs <martins.fridenbergs@mtcmedia.co.uk>
 * @version 0.1 30/07/16
 */

use App\Events\MemberUpdatedEvent;
use Illuminate\Support\Facades\Event;
use Mtc\Core\Models\CountryState;
use Mtc\Modules\BlackList\Classes\BlackList;
use Mtc\Modules\Members\Classes\MemberManager;
use Mtc\Modules\Members\Models\Member;
use Mtc\Plugins\NewsletterSignup\Classes\Newsletter;
use Mtc\Shop\Events\BasketAjaxAction;

if (!isset($_REQUEST['ajax']) || empty($_REQUEST['action'])) {
    http_response_code(400);
    exit();
}


$path = '../../';
require_once $path . 'core/includes/header.inc.php';
header('Content-Type: application/json');
$__basketAjaxStart = microtime(true);
$__emitBasketAjaxTiming = static function () use ($__basketAjaxStart) {
    if (config('app.debug')) {
        header('X-BasketAjax-Execution-Time: ' . number_format((microtime(true) - $__basketAjaxStart), 4));
    }
};

/** @var Member $member */

$basket = new Basket();
$basket->Go_Basket();



$errors = [];
$messages = [];
$action = !empty($_REQUEST['action']) ? $_REQUEST['action'] : false;


if ($action === 'get_basket') {
    /*
     * Basket is initialized & loaded in shop/includes/header.inc.php
     * Additionally check if user isn't reloading page with Address already set to have country with state
     */
    $basket_state_list = $basket->getBasketStateList();

    $basket_has_postcodes = $basket->getBasketHasPostcodes();

    $basket_placeholder_image = false;
    if (!empty($placeholder_images['item_small']['value'])) {
        $basket_placeholder_image = '/' . $image_folders['product_folders']['thumbs']['path']
            . '/' . $placeholder_images['item_small']['value'];
    }

    // Checkout config settings - passed via AJAX to avoid exposing data in page source
    $checkout_config = [
        'termsShow' => defined('TERMS_SHOW') ? TERMS_SHOW : true,
        'orderNotesEnabled' => defined('ORDER_NOTES_ENABLED') ? ORDER_NOTES_ENABLED : false,
        'orderNotesMaxLength' => defined('ORDER_NOTES_MAX_LENGTH') ? ORDER_NOTES_MAX_LENGTH : 500,
        'membersSection' => defined('MEMBERS_SECTION') ? MEMBERS_SECTION : false,
        'memberId' => isset($member) && $member->id ? $member->id : 0,
        'memberIsVerified' => isset($member) && $member->is_verified ? $member->is_verified : false,
        'membersBasket' => defined('MEMBERS_BASKET') ? MEMBERS_BASKET : false,
        'couponEnabled' => defined('COUPON_ENABLED') ? COUPON_ENABLED : true,
        'basketShowVat' => defined('BASKET_SHOW_VAT') ? BASKET_SHOW_VAT : true,
        'vatEnabled' => defined('VAT_ENABLED') ? VAT_ENABLED : true,
        'vatRate' => defined('VAT_RATE') ? VAT_RATE : 20,
        'allowAlternateDelivery' => isset($basket->allow_alternate_delivery) ? (bool)$basket->allow_alternate_delivery : true,
        'howDidYouHearEnabled' => defined('BASKET_HOW_DID_YOU_HEAR_ABOUT_US_ENABLED') ? BASKET_HOW_DID_YOU_HEAR_ABOUT_US_ENABLED : false,
        'itemsSizes' => defined('ITEMS_SIZES') ? ITEMS_SIZES : true,
        'site' => defined('SITE') ? SITE : 'default',
        'themePath' => defined('THEME_PATH') ? THEME_PATH : '/sites/default',
    ];

    $__emitBasketAjaxTiming();
    echo json_encode([
        'status' => 'ok',
        'basket' => $basket,
        'titles' => Member::$titles,
        'genders' => Member::$genders,
        'countries' => $basket_countries,
        'currencies' => $GLOBALS['enabled_currencies'],
        'state_list' => $basket_state_list,
        'has_postcodes' => $basket_has_postcodes,
        'basket_placeholder_image' => $basket_placeholder_image,
        'how_did_you_hear_about_us_choices' => explode("\n", BASKET_HOW_DID_YOU_HEAR_ABOUT_US_CHOICES),
        'config' => $checkout_config,
    ]);
    exit();
}

if ($action === 'get_basket_item_qty' && !empty($_REQUEST['id'])) {
    foreach ($basket->items as $item) {
        if ($item['id'] == $_REQUEST['id']) {
            $__emitBasketAjaxTiming();
            echo json_encode([
                'status' => 'ok',
                'quantity' => $item['quantity'],
            ]);
            exit();
        }
    }
    // Prevent returning other buyers basket item data
    http_response_code(400);
    exit();
}

if ($action === 'update_qty' && !empty($_POST['basket']['items'])) {
    if (!empty($_POST['basket'])) {
        $basket->updateQuantities($_POST['basket']['items']);
        $basket->saveDetails($_POST['basket']);
    }
    $basket = new Basket();
    $basket->Go_Basket();
    $__emitBasketAjaxTiming();
    echo json_encode([
        'status' => 'ok',
        'basket' => $basket
    ]);
    exit();
}

if ($action === 'validate_coupon' && !empty($_POST['basket']['coupon_code'])) {
    if (!empty($_POST['basket'])) {
        $basket->saveDetails($_POST['basket']);
    }
    if (!$basket->Set_Coupon($_POST['basket']['coupon_code'])) {
        $errors['coupon_error'] = "Sorry, the coupon code you have entered is not valid. " . $basket->coupon_error;
    } else {
        $messages['coupon_success'] = "Your coupon code has been set.";
    }
    $basket = new Basket();
    $basket->Go_Basket();
    $__emitBasketAjaxTiming();
    echo json_encode([
        'status' => 'ok',
        'basket' => $basket,
        'errors' => $errors,
        'messages' => $messages
    ]);
    exit();
}

if ($action === 'clear_coupon') {
    if (!empty($_POST['basket'])) {
        $basket->saveDetails($_POST['basket']);
    }
    $basket->removeCoupon();
    $basket = new Basket();
    $basket->Go_Basket();
    echo json_encode([
        'status' => 'ok',
        'basket' => $basket,
        'errors' => $errors,
        'messages' => $messages
    ]);
    exit();
}


// Checkbox "Ship to this address" was ticked
if ($action === 'change_shipping_state' && isset($_POST['basket']['billing_address_used'])) {
    $basket->updateBillingAddressUsed($_POST['basket']['billing_address_used']);
    if (!empty($_POST['basket'])) {
        $basket->saveDetails($_POST['basket']);
    }
    $basket = new Basket();
    $basket->Go_Basket();
    echo json_encode([
        'status' => 'ok',
        'basket' => $basket,
        'errors' => $errors,
        'messages' => $messages
    ]);
    exit();
}

if ($action === 'store_details') {
    /*
     * At this point only store user details that have been input
     * Validation will be handled upon proceeding to basket_overview via try_checkout event
     * Data storing needed to ensure that no info is lost when info is returned via JSON
     */
    $basket->updateBillingAddressUsed($_POST['basket']['billing_address_used']);

    if (!empty($_POST['basket'])) {
        unset($_POST['basket']['info']['id_type']);
        unset($_POST['basket']['info']['id_number']);
        $basket->saveDetails($_POST['basket']);
    }

    $basket_state_list = $basket->getBasketStateList();
    $basket_has_postcodes = $basket->getBasketHasPostcodes();

    $basket = new Basket();
    $basket->Go_Basket();
    $__emitBasketAjaxTiming();
    echo json_encode([
        'status' => 'ok',
        'basket' => $basket,
        'state_list' => $basket_state_list,
        'has_postcodes' => $basket_has_postcodes,
    ]);
    exit();
}

// Do checkout
if ($action === 'try_checkout' && !empty($_POST['basket'])) {
    // If the cascade values are set we need to save them in session and clear
    if (!empty($basket->require_id_check_cascade)) {
        $_SESSION['ID_CHECK_TYPE'] = $_POST['basket']['info']['id_type'];
        $_SESSION['ID_CHECK_NUMBER'] = $_POST['basket']['info']['id_number'];
    }

    // T79986 - Capitalize first and last names
    foreach (['billing', 'shipping'] as $address_type) {
        foreach (['firstname', 'middle_name', 'lastname'] as $name) {
            $_POST['basket']['address'][$address_type][$name] = ucwords($_POST['basket']['address'][$address_type][$name]);
        }
    }

    // Only save details if the correct member is being saved
    if (!$errors = $basket->validateMemberSession($_POST['basket']['member'] ?? null)) {
        unset($_POST['basket']['info']['id_type']);
        unset($_POST['basket']['info']['id_number']);
        $basket->saveDetails($_POST['basket']);

        $basket = new Basket();
        $basket->Go_Basket();
        $errors = $basket->validate($_POST, $basket_countries, CountryState::getCountryStateList());
    }

    if (!empty($errors)) {
        $__emitBasketAjaxTiming();
        echo json_encode([
            'status' => 'failed',
            'errors' => $errors,
        ]);
        exit();
    }

    $blacklist = new BlackList();
    $blacklist_flag_type = $blacklist->isBlacklisted([
        'telephone' => $_POST['basket']['info']['contact_no'],
        'email' => $_POST['basket']['info']['email'],
        'address' => $_POST['basket']['address']['billing']['postcode']
    ]);

    if($blacklist_flag_type > 0) {
        $basket->addBasketFlag($blacklist_flag_type);
    }

    if ($blacklist_flag_type === BlackList::HARD_BLACKLIST_FLAG) {
        $errors['terms'] = "We're sorry we are unable to process this order due to suspected account misuse. If you think this is an error, please contact us";
    }

    if (!empty($errors)) {
        $__emitBasketAjaxTiming();
        echo json_encode([
            'status' => 'failed',
            'errors' => $errors,
        ]);
        exit();
    }

    if (!empty($_POST['newsletter'])) {
        $basket->subscribeToNewsletter();
    }

    // Handle member registration from basket
    if (empty($member->id)) {
        if ($duplicate = Member::memberHasDuplicates([
            'info' => $basket->info,
            'address' => $basket->address['billing'],
        ])) {
            if ($duplicate === 'address') {
                $errors['address']['billing']['address1'] = 'Your address is in use on another account. If you can’t remember the e-mail address you previously used to register, please contact us, and we can provide or reset your registered e-mail details.';
            } elseif ($duplicate === 'phone') {
                $errors['info']['contact_no'] = 'Another account already exists with this phone number. Please log in with your existing account, or contact us if you think this is an error';
            }
        } else {
            $member_register_errors = $member->registerFromBasket($member, $basket, $_POST['cardholder_password']);
            if (!empty($member_register_errors)) {
                $errors[$member_register_errors['error_field']] = $member_register_errors['errors'];
            }
        }
    } else {
        $member->updateFromBasket($member, $basket);
    }

    if (!empty($errors)) {
        $__emitBasketAjaxTiming();
        echo json_encode([
            'status' => 'failed',
            'errors' => $errors,
        ]);
        exit();
    } else {
        $__emitBasketAjaxTiming();
        echo json_encode([
            'status' => 'proceed',
            'data' => [
                'url' => '/shop/checkout/basket_overview.php'
            ]
        ]);
        exit();
    }
}

$responses = array_filter(Event::dispatch(new BasketAjaxAction($basket, $_POST)));
if (!empty($responses)) {
    $__emitBasketAjaxTiming();
    echo json_encode(reset($responses));
    exit();
}

http_response_code(400);
$__emitBasketAjaxTiming();
exit();
