<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputArgument;
use App\Modules\Bookings\Repair;
use Carbon\Carbon;

class RepairsReminder extends Command
{
    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'repairs:reminder';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Sends a reminder to every techician that has a job open for a long period of time and also notifies the manager.';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function fire()
    {
        //Mail::pretend();

        $date = Carbon::now()->subDays(3)->toDateTimeString();
        $now = Carbon::now()->toDateTimeString();
        $log = '['.$now.'] [RepairsReminder]';

        $this->info($log.' Calculating repairs that have not been touched since '.$date);

        //If the option summary = all, send reminder even for tasks marked as exclude_notifications
        if ($this->option('summary') == 'all') {
            $tasks = Repair::repairs()->with('user')->whereNotNull('tasks.assigned_to')->where('completed', 0)->where('updated_at', '<', $date)->groupBy('assigned_to')->get();
        }

        //If the option summary = standard, send reminder just for the tasks marked with an open status which is not maked as exlude_notifcations
        else {
            $tasks = Repair::repairs()->with('user')->whereNotNull('tasks.assigned_to')->whereHas('status', function ($q) {
                $q->where('exclude_notifications', 0);
            })->where('completed', 0)->where('updated_at', '<', $date)->groupBy('assigned_to')->get();
        }

        if (count($tasks) > 0) {
            $counter = 0;
            $technicians = [];

            foreach ($tasks as $task) {
                $this->info($log.' Task: '.$task->id);
                if (! $task->user->email || ! filter_var($task->user->email, FILTER_VALIDATE_EMAIL)) {
                    $this->error($log.' '.$task->user->name.' does not have an email address');
                    continue;
                }

                // Check for comments
                if ($task->comments()->where('created_at', '>', $date)->count() > 0) {
                    continue;
                }

                // Check for re-assignments
                if ($task->assigned_changes()->where('created_at', '>', $date)->count() > 0) {
                    continue;
                }

                // Now we can count actual technicians
                $counter++;

                // Retrieve all the tasks that have been merged
                if ($this->option('summary') == 'all') {
                    $technician_tasks = Repair::repairs()->where('completed', 0)->where('updated_at', '<', $date)->where('assigned_to', $task->assigned_to)->get();
                } else {
                    $technician_tasks = Repair::repairs()->where('completed', 0)->where('updated_at', '<', $date)->where('assigned_to', $task->assigned_to)->whereHas('status', function ($q) {
                        $q->where('exclude_notifications', 0);
                    })->get();
                }

                // Pushing all the technician tasks onto this array to build the summary
                $technicians[$task->user->name] = $technician_tasks;

                Mail::send('emails.alerts.repairs-reminder', ['tasks' => $technician_tasks, 'user' => $task->user], function ($message) use ($task) {
                    $message->to($task->user->email)->subject('[Seraph3] What is going on with these jobs?')->priority(1);
                });

                // Send an email to the technician
                $this->info($log.' Sending an email to '.$task->user->name.' who has '.count($technician_tasks).' job reminders.');
            }

            $this->info($log.' Found '.$counter.' technicians that need to be notified');

            Mail::send('emails.alerts.repairs-reminder-summary', ['technicians' => $technicians, 'user' => User::where('email', Config::get('emails.managers.repairs'))->first()], function ($message) use ($task, $now) {
                $message->to(Config::get('emails.managers.repairs'))->cc(Config::get('emails.managers.repairs_cc'))->subject('[Seraph3] A summary of all the jobs that have not been touched in 72 hours ['.$now.']')->priority(1);
            });

            // Send an email to the manager
            $this->info($log.' Sending an email containing a summary to '.Config::get('emails.managers.repairs').' who is the manager of repairs.');
        } else {
            $this->info($log.' No repair notifications to be sent out at this moment.');
        }
    }

    /**
     * Get the console command arguments.
     *
     * @return array
     */
    protected function getArguments()
    {
        return [

        ];
    }

    /**
     * Get the console command options.
     *
     * @return array
     */
    protected function getOptions()
    {
        return [
            ['summary','s', InputArgument::OPTIONAL, 'Indicate if the remainder is a standar or all one. The possible modes are:\n
				-standard, the notifications will be send for all the open tasks not marked as eclude from notifications.
				-all, the notifications will be send for all the open tasks', 'standard'],
        ];
    }

    protected function remote_get_contents($url)
    {
        if (function_exists('curl_get_contents') and function_exists('curl_init')) {
            return $this->curl_get_contents($url);
        } else {
            // A litte slower, but (usually) gets the job done
            return file_get_contents($url);
        }
    }

    protected function curl_get_contents($url)
    {
        // Initiate the curl session
        $ch = curl_init();

        // Set the URL
        curl_setopt($ch, CURLOPT_URL, $url);

        // Removes the headers from the output
        curl_setopt($ch, CURLOPT_HEADER, 0);

        // Set the timeout
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);

        // Return the output instead of displaying it directly
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        // Execute the curl session
        $output = curl_exec($ch);

        // Close the curl session
        curl_close($ch);

        // Return the output as a variable
        return $output;
    }
}
