<?php

namespace App\Jobs;

use App\Exceptions\CampaignPausedException;
use App\Models\Campaigns;
use App\Models\Contacts;
use App\Models\JobMonitor;
use Illuminate\Bus\Batchable;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class SendMessage implements ShouldQueue
{
    use Batchable, Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $contact;
    protected $campaign;
    protected $server;

    /**
     * Create a new job instance.
     */
    public function __construct($campaign, Contacts $contact, $server)
    {
        $this->campaign = $campaign;
        $this->contact  = $contact;
        $this->server   = $server;
    }

    /**
     * Execute the job.
     *
     * @throws CampaignPausedException
     */
    public function handle(): void
    {
        if ($this->batch()->cancelled()) {
            return;
        }


        if ($this->campaign->user->customer->getOption('sms_max') != '-1' && $this->campaign->user->sms_unit <= 0) {
            $this->setPaused(sprintf('Campaign `%s` (%s) halted for insufficient sms unit', $this->campaign->campaign_name, $this->campaign->uid));
        }

        if ($this->campaign->user->customer->overQuota()) {
            $this->setPaused(sprintf('Campaign `%s` (%s) halted, user exceeds plan maximum sending limit', $this->campaign->campaign_name, $this->campaign->uid));
        }

        if ($this->server->overQuota()) {
            $this->setPaused(sprintf('Campaign `%s` (%s) halted, user exceeds server sending limit', $this->campaign->campaign_name, $this->campaign->uid));
        }

        $sent = $this->campaign->send($this->contact);

        $this->campaign->track_message($sent, $this->contact, $this->server);
    }

    private function setPaused($reason = null)
    {
        $this->batch()->cancel();
        JobMonitor::where('subject_name', Campaigns::class)->where('subject_id', $this->campaign->id)->delete();
        $this->campaign->update([
                'status' => Campaigns::STATUS_PAUSED,
                'reason' => $reason,
        ]);
        sleep(60);
    }
}
