<?php

namespace App\Packages\v4\Phone\Service;

use App\Packages\v4\Core\Exceptions\RecordNotExistsException;
use App\Packages\User\Models\SmsLog;
use App\Packages\User\Models\UserPhoneConfirm;
use Aws\Sns\Exception\SnsException;
use libphonenumber\PhoneNumber;

/**
 * Class SmsService
 * @package App\Packages\User\Transformer
 */
class VerificationCodeService
{
    /** @var AmazonSmsService */
    private $amazonSms;

    /** @var PhoneParseService */
    private $phoneParseService;

    public function __construct(AmazonSmsService $amazonSms, PhoneParseService $phoneParseService)
    {
        $this->amazonSms = $amazonSms;
        $this->phoneParseService = $phoneParseService;
    }

    /**
     * @param $phoneCode
     * @param $phoneNumber
     */
    public function startVerify($phoneCode, $phoneNumber)
    {
        $phoneString = $phoneCode . $phoneNumber;
        $swissNumberProto = $this->phoneParseService->parseNumber($phoneString, $phoneCode);

        $smsLog = SmsLog::createLog($phoneCode, $phoneNumber);

        $phoneIsValid = false;
        if ($swissNumberProto instanceof PhoneNumber) {
            $phoneIsValid = $this->phoneParseService->isValidNumber($swissNumberProto);
        }

        $smsLog->setIsValid($phoneIsValid);

        if ($phoneIsValid) {
            $confirmRecord = UserPhoneConfirm::createPhoneConfirm($phoneCode, $phoneNumber);
            $smsLog->setConfirmationCode($confirmRecord->code);

            try {
                $this->amazonSms->sendVerificationNumber(
                    $confirmRecord->code,
                    $swissNumberProto->getCountryCode(),
                    $swissNumberProto->getNationalNumber()
                );
                $smsLog->acceptSent();
            } catch (SnsException $exception) {
                $smsLog->declineSend($exception->getAwsErrorMessage());
            }
        }
    }

    /**
     * @param string $verifyCode
     *
     * @return UserPhoneConfirm
     *
     * @throws RecordNotExistsException
     */
    public function completeVerify($verifyCode)
    {
        /** @var UserPhoneConfirm $phoneConfirm */
        $phoneConfirm = UserPhoneConfirm::findPhoneCode($verifyCode);

        /** Check code */
        if (!$phoneConfirm) {
            throw new RecordNotExistsException('Code does not exists');
        }

        $phoneConfirmRecord = $phoneConfirm;
        $phoneConfirm->delete();

        return $phoneConfirmRecord;
    }

}