<?php

namespace App\Modules\Workflow\Actions;

use Carbon\Carbon;
use App\Modules\Workflow\ScheduledEmail;
use App\Seraph\Services\GlobalMailerService;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;

class SendEmailAction extends WorkflowBaseAction
{
    /**
     * User friendly name for this action.
     *
     * @var string
     */
    protected $name = 'Send Email';

    /**
     * Validation rules.
     *
     * @var array
     */
    protected $rules = [
        'to'                    => 'required',
        'subject'               => 'required',
        'template'              => 'required',
        'scheduled_measurement' => 'required_with:scheduled',
        'scheduled_custom_date' => 'required_if:scheduled_measurement,custom',
    ];

    /**
     * Executes all actions assigned to the event.
     *
     * @return
     */
    public function fire()
    {
        // Do something...
        Log::info('Fired Send Email action. Nice one!');
        Log::info($this->getData());

        // We now need to replace variables in the message body with real values...
        if (! $this->validate()) {
            Log::error('Validation failed!');
            Log::error($this->validator->messages());

            return false;
        }

        // Retrieve the action settings
        // Each action can have custom settings for each event
        // The variables in these settings will already be replaced
        $settings = $this->getSettings();

        if ($settings['scheduled']) {
            // The email needs to be scheduled
            $result = $this->scheduleEmail();
        } else {
            // This is an instant email, no need to schedule it
            // We are now sending the email out using GlobalMailerService (no CC/BCC for system workflows)
            GlobalMailerService::send('emails.dbtemplate', ['template' => $settings['template']], function ($message) use ($settings) {
                $message->to($settings['to'])->subject($settings['subject']);
            });
        }
    }

    /**
     * Schedules the email for a further date.
     *
     * @return null
     */
    protected function scheduleEmail()
    {
        $data = $this->getData()->toArray();
        $settings = $this->getSettings();

        // Building the method name that will be called on carbon
        // for example: addDays, addMonths, addYears
        $addMeasurement = 'add'.ucwords($settings['scheduled_measurement']);

        // Check when the email should go out
        $send_on = ($settings['scheduled_measurement'] == 'custom')
                    ? Carbon::parse($settings['scheduled_custom_date'])->toDateString() : Carbon::now()->{$addMeasurement}($settings['scheduled_unit'])->toDateString();

        // Store the scheduled email in the database
        // Also determines if it is part of a task
        // and grabs the task_id and the client details
        $schedule = ScheduledEmail::create([
            'event'       => $this->event->description,
            'to'          => $settings['to'],
            'settings'    => $settings,
            'task_id'     => isset($data['labour']) ? $data['id'] : null,
            'client_id'   => isset($data['client_id']) ? $data['client_id'] : null,
            'client_type' => isset($data['client_type']) ? $data['client_type'] : null,
            'send_on'     => $send_on,
        ]);

        if (! $schedule->exists) {
            Log::warning($schedule->errors->all());
        }

        return $schedule->exists;
    }
}
