<?php
/**
 * MembersBasket Trait.
 * @version 13/11/16
 * @author Martins Fridenbergs <martins.fridenbergs@mtcmedia.co.uk>
 */

namespace Mtc\Modules\Members\Classes;

use App\Events\MemberCreatedEvent;
use App\Events\MemberUpdatedEvent;
use Basket;
use Carbon\Carbon;
use Illuminate\Support\Facades\Event;
use Mtc\Modules\Members\Models\Member;
use Mtc\Plugins\NewsletterSignup\Classes\Newsletter;

/**
 * MembersBasket Trait.
 * Implements the functionality that bridges member and basket
 *
 * @version 13/11/16
 * @author Martins Fridenbergs <martins.fridenbergs@mtcmedia.co.uk>
 */
trait MembersBasket
{
    /**
     * Method will attempt to join current basket with basket linked to member
     *
     * @param Member $member Current member
     * @param int $members_basket_id
     */
    private function getMemberBasket(Member $member, $member_basket_id = 0) {
        if (MEMBERS_BASKET === true && !Basket::isPaid($member_basket_id)) {
            $this->addPreLoginItemsToMemberBasket($member_basket_id);
            if ($member_basket_id > 0) {
                $_SESSION['basket_id'] = $member_basket_id;
            } elseif ($_SESSION['basket_id'] > 0) {
                $this->setMemberBasket($member, $_SESSION['basket_id']);
            }
        }
    }

    /**
     * Method will link a basket to this member
     *
     * @param Member $member Current member
     * @param int $basket_id
     */
    private function setMemberBasket(Member $member, $basket_id) {
        if (MEMBERS_BASKET === true) {
            Member::where('id', $member->id)
                ->update([
                    'basket_id' => $basket_id
                ]);
        }
    }

    /**
     * Unlink basket from member.
     */
    public static function unsetMemberBasket($member_id) {
        Member::where('id', $member_id)
            ->update([
                'basket_id' => 0
            ]);
        if (isset($_SESSION['basket_id'])) {
            unset($_SESSION['basket_id']);
        }
    }

    /**
     * Method will join up ongoing pre login basket with member basket to avoid
     * loss of items.
     *
     * @param int $members_basket_id
     */
    private function addPreLoginItemsToMemberBasket($member_basket_id) {
        if (MEMBERS_BASKET_ADD_PRE_LOGIN && $_SESSION['basket_id'] > 0 && !$_SESSION['member_id']) {
            $pre_login_basket = new Basket();
            $pre_login_basket->Go_Basket();
            if (is_array($pre_login_basket->items)) {
                $members_basket = new Basket($member_basket_id);
                foreach ($pre_login_basket->items as $lineItem) {
                    $members_basket->Add_Item(array(
                            'id' => $lineItem['item_id'],
                            'size' => $lineItem['size'],
                            'size_id' => $lineItem['sizeid'],
                            'alias' => $lineItem['alias'],
                            'quantity' => $lineItem['quantity'],
                            'PLU' => $lineItem['PLU'],
                            'assessment_id' => $lineItem['assessment_id'] ?? null)
                    );
                }
            }
        }
    }

    /**
     * Handle user registration on basket page
     *
     * @access public
     * @param Member $member current user
     * @param Basket $basket current users basket
     * @return array errors experienced
     */
    public function registerFromBasket(Member $member, Basket $basket, $password)
    {
        // Check if member already doesn't exist
        if ($member->where('email', $basket->info['email'])->count() > 0) {
            return [
                'errors' => [
                    'email' => 'The Email address given has already been used for a member account. 
                        Click the SIGN IN button above to sign in',
                ],
                'error_field' => 'info',
            ];
        }

        if (empty($password)) {
            return [
                'errors' => 'Please enter the password',
                'error_field' => 'cardholder_password',
            ];
        }

        // Validate password
        if (!MemberManager::sufficientPasswordStrength($password)) {
            return [
                'errors' => 'Please enter a password of at least 8 characters using letters as well as numbers.',
                'error_field' => 'cardholder_password',
            ];
        }

        // Register member
        $member = Member::query()->create([
            'email' => $basket->info['email'],
            'contact_no' => $basket->info['contact_no'],
            'first_login' => new Carbon(),
            'phone_prefix' => $basket->info['phone_prefix'],
            'dob' => $basket->info['dob'],
            'doctor_surgery' => $_SESSION['health_profile']['doctor_surgery'] ?? '',
            'gender' => $basket->address['billing']['gender'],
        ]);

        $member->setMedications($_SESSION['health_profile']['medications'] ?? []);
        $member->setAllergies($_SESSION['health_profile']['allergies'] ?? []);
        $member->setConditions($_SESSION['health_profile']['conditions'] ?? []);
        $member->save();

        $member->setPassword($password);
        $member->save();
        $member->addresses()->create($basket->address['billing']);

        $member->setMemberBasket($member, $basket->id);
        $basket->Set_Member($member->id);

        Event::dispatch(MemberCreatedEvent::class, new MemberCreatedEvent($member));

        Auth::login($basket->info['email'], $password);

        return [];
    }

    /**
     * Updates member details from basket
     *
     * @param Member $member
     * @param Basket $basket
     * @return void
     */
    public function updateFromBasket(Member $member, Basket $basket): void
    {
        $oldMember = clone $member;
        $oldMember->load('addresses');
        // Update member addresses
        foreach (['billing', 'shipping'] as $type) {
            $address = $member->addresses()->firstOrNew(['type' => $type]);
            $address->fill($basket->address[$type]);
            $address->save();
        }

        // Update member prefix
        $member->phone_prefix = $basket->info['phone_prefix'];
        $member->dob = $basket->info['dob'];
        $member->gender = $basket->address['billing']['gender'];

        if ($member->emptyPassword()) {
            if (!MemberManager::sufficientPasswordStrength($_POST['cardholder_password'])) {
                $errors['cardholder_password'] = 'Please enter a password of at least 8 characters using letters as well as numbers.';
            } else {
                $member->setPassword($_POST['cardholder_password']);
            }
        }

        if (!empty($basket->info['newsletter'])) {
            Newsletter::signUp($basket->info['email'], [
                'first_name' => $basket->address['billing']['firstname'],
                'last_name' => $basket->address['billing']['lastname'],
                'skip_double_opt_in' => true,
            ]);
        } else {
            Newsletter::unsubscribe($basket->info['email']);
        }

        $member->save();
        Event::dispatch(MemberUpdatedEvent::class, new MemberUpdatedEvent($oldMember, $member));
    }
}
