<?php

namespace App;

use App\Traits\Server6UssdDatabase;
use Illuminate\Database\Eloquent\Model;

class UssdService extends Model
{

    use Server6UssdDatabase;


    /**
     * Constants for ussd service purchase status
     */
    const USSD_SERVICE_PURCHASE_STATUS_TRIAL = 'trial';
    const USSD_SERVICE_PURCHASE_STATUS_PAID = 'paid';
    const USSD_SERVICE_PURCHASE_STATUS_DEACTIVATED = 'deactivated';

    /**
     * @var array
     */
    protected $fillable = [
      'name', 'code', 'description', 'ussd_service_type_id', 'purchase_status', 'sms_username', 'sms_password','keyword'
    ];

    /**
     * USSD Service subscriptions include one of the types of the ussd service
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function ussd_service_type() {
        return $this->belongsTo(UssdServiceType::class);
    }


    /**
     * A service has questions for the service type been subscribed to, ie survey
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function ussd_question() {
        return $this->hasMany(UssdQuestion::class);
    }


    /**
     * Ussd service has a payment subscription renewed monthly
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function ussd_payment(){
        return $this->hasOne(UssdPayment::class);
    }


    /**
     * Identify if a service is a Survey
     * @return bool
     */
    public function isSurvey() {
        return $this->ussd_service_type->id == UssdServiceType::USSD_SURVEY_ID;
    }

    /**
     * Identify if a service is a Collection
     * @return bool
     */
    public function isCollection() {
        return $this->ussd_service_type->id == UssdServiceType::USSD_COLLECTION_ID;
    }


    /**
     * Generates unique code for ussd service
     * Uses the possible row id of the Ussd service to be stored in the database
     * @return string
     */
    static public function generateUssdCode() {
        //base ussd code
        $prefix = '*899*';
        $suffix = '#';

        //generate the extension
        $extension = self::generateExtension();

        //concatenate prefix, extension and $suffix ie *889*334#
        return  $prefix . $extension . $suffix;
    }

    /**
     * Generates extension for the service
     * @return int|mixed
     */
    static private function generateExtension() {
        //establish connection to server 6
        $connection = (new UssdService)->ussdLiveDBConnection();
        //query to run
        $sql = "SELECT extension FROM services";
        //save the result
        $result = mysqli_query($connection, $sql);

        //store extensions on server 6 here
        $extensions = []; //ie [4,5,2334, 4563, 6654] etc

        if (mysqli_num_rows($result) > 0) {
            while($row = mysqli_fetch_assoc($result)) {
                array_push($extensions, $row['extension']);
            }
        }

        //convert extensions array into collections
        $extensions = Collect($extensions);

        //find the maximum/largest extension -- been the last extension
        $lastExtension = $extensions->max();
        //generate the new extension - add 1
        $newExtension = $lastExtension + 1;
        //ensure the new extension is not a multiple of 10, ie 10, 20 etc
        //if it is, increment count to generate a new one
        $extension = static::isAMultipleOfTen($newExtension) ? $newExtension + 1 : $newExtension;

        //close connection
        mysqli_close($connection);
        return $extension;
    }

    /**
     * Identifies if a number is a multiple of 10, ie 0, 10, 20, 30 etc.
     * The modulus of the multiples of 10 is 0,
     * (similar, remainder of a number which is a multiple of 10 divided by 10 is 0)
     * @param $number
     * @return bool
     */
    private static function isAMultipleOfTen($number) {
        return ($number % 10) == 0;
    }

    /**
     * Generate new question's number
     * @param $id
     * @return int
     */
    static public function getNewQuestionNumber($id) {
        //automatically assign numbering to question
        //get the count of questions in the database for the specific ussd service
        $count = self::find($id)->ussd_question()->count();

        //increment count as it will be assigned as the new question's number
        $count++;

        return $count;
    }

    /**
     * Get if payment for service has failed
     * @return bool
     */
    public function paymentHasFailed() {
        return $this->ussd_payment->status === 'failed';
    }


    /**
     * Get if service has expired
     * @return mixed
     */
    public function paymentHasExpired() {
        return $this->ussd_payment->has_expired;
    }


}
