<?php

/**
 * @author: Uldis Zvirbulis <uldis.zvirbulis@mtcmedia.co.uk>
 * @version: 01.08.2018
 */

namespace Mtc\Core;

use App\Casts\OptionalEncrypted;
use Exception;
use Illuminate\Database\Eloquent\Model;

class EmailsQueued extends Model
{
    /**
     * @var string Model table name
     */
    protected $table = 'emails_queued';

    protected $guarded = ['id'];

    protected $casts = [
        'email' => OptionalEncrypted::class,
        'content' => OptionalEncrypted::class,
    ];

    /**
     * Sends out queued emails
     *
     * @return void
     * @throws Exception
     */
    public static function send(): void
    {
        // Max execution time in seconds after cron is killed (in cases it gets stuck)
        // Give 1 hour for the process to complete, then kill it
        $lock_kill_age = 60 * 60;
        $lock_name = 'emails_queued_cron.lock';
        // If lock file exists
        if (file_exists($lock_name)) {
            // Determine how old it is
            $lock_age = time() - filemtime($lock_name);

            // This indicates the previous cron is still running
            if ($lock_age < $lock_kill_age) {
                echo 'Previous cron still running';

                return;
            }
            // If the lock age exceeds limit, we remove it
            unlink($lock_name);
        }
        // Create new lock file
        touch($lock_name);

        echo 'Deleting old emails (1 month or older)...'.PHP_EOL;

        // Remove any emails sent that are older than 1 month
        EmailsQueued::query()
            ->whereNotNull('sent_at')
            ->where(
                'sent_at',
                '<',
                (new \Carbon\Carbon)
                    ->subMonth()
                    ->format('Y-m-d 00:00:00'),
            )
            ->delete();

        echo 'Sending queued emails...'.PHP_EOL;

        // Go through the emails that are queued, send out and update as sent
        EmailsQueued::query()
            ->whereNull('sent_at')
            ->get()
            ->each(static function ($queued_email): void {
                /** @var EmailsQueued $queued_email */
                // Dump all values in params as the keys match
                echo 'Sending email: '.$queued_email->email.PHP_EOL;
                $params = $queued_email->toArray();
                if ($sent = email($queued_email->email, $queued_email->subject, $queued_email->content, $params)) {
                    $queued_email->sent_at = \Carbon\Carbon::now();
                    $queued_email->save();
                }
            });

        echo 'Queued email send complete.'.PHP_EOL;
        // Remove lock file when the scheduled process is complete.
        unlink($lock_name);
    }
}
