<?php

namespace App\Console;

use App\Helpers\Helpers;
use App\Helpers\Inspiring;
use App\Http\Controllers\SendmsgController;
use App\Http\Controllers\TransactionController;
use App\Models\Device;
use App\Models\Outbox;
use App\Models\Setting;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
  /**
   * Define the application's command schedule.
   *
   * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
   * @return void
   */
  protected function schedule(Schedule $schedule)
  {
    $schedule->call(function () {
      if (!empty(env('TEST_CRONJOB'))) {
        $adminSender = Device::where('user_id', 1)->where('status', '=', 'ONLINE')->value('sender');
        SendmsgController::sendMessage(env('TEST_CRONJOB'), 'This TEST MESSAGE will be sent per Minute. If you see this message, your cronjob is working properly.', $adminSender);
      }
    })
    ->everyMinute()// https://laravel.com/docs/10.x/scheduling#schedule-frequency-options
    ->name('TEST_CRONJOB');

    // WARMING_UP_DEVICES every 5 minutes
    $schedule->call(function () {
      if (Helpers::isEx()) {
        $users = User::where('billing_end', '>', Carbon::now())->orWhere('role', '=', 'admin')->get();
      } else {
        $users = User::where('banned', 0)->get();
      }
      foreach($users as $user) {
        $devices = $user->devices()->where('status', 'ONLINE')->where('warmingup', 1)->get();
        $count = count($devices);
        if ($count > 1) {
          $rand = rand(0, $count-1);
          $sender = $devices[$rand]->sender;
          $receivers = [];
          for($i=0;$i<$count;$i++) {
            if($i===$rand) continue;
            array_push($receivers, $devices[$i]->sender);
          }
          foreach($receivers as $receiver) {
            $msgtext = Inspiring::quote() . "\n\n" . '(warming up)';
            SendmsgController::sendMessage($receiver, $msgtext, $sender);
            sleep(2);
          }
        } else if ($count === 1 && $devices[0]->wu_receiver) {
          $wuReceiver = explode(',', $devices[0]->wu_receiver);
          foreach ($wuReceiver as $receiver) {
            $msgtext = Inspiring::quote() . "\n\n" . '(warming up)';
            SendmsgController::sendMessage($receiver, $msgtext, $devices[0]->sender);
            sleep(2);
          }
        }
      }
    })
    ->everyFiveMinutes()
    ->name('WARMING_UP_DEVICES');

    // GET_LATEST_VERSION_NUMBER every 30 minutes
    $schedule->call(function () {
      file_put_contents(base_path('storage/latest'), Helpers::curlGet(config('app.GET_VERSION') . '?id=' . config('app.id')));
    })
    ->everyThirtyMinutes()
    ->name('GET_LATEST_VERSION_NUMBER');

    // DELETE_OUTBOXES_OLDER_THAN_A_MONTH daily hour 00:00
    $schedule->call(function () {
      Outbox::where('recurring', null)->where('created_at', '<', Carbon::now()->subMonth())->delete();
      foreach (scandir(public_path('users')) as $userDir) {
        if ($userDir === '.' || $userDir === '..') {
          continue;
        }
        if (file_exists(public_path("users/{$userDir}/outbox"))) {
          foreach (glob(public_path("users/{$userDir}/outbox/*.*")) as $file) {
            if (Carbon::parse(filectime($file)) < Carbon::now()->subMonth() && !str_contains($file, '-recurring')) {
              unlink($file);
            }
          }
        }
      }
    })
    ->daily()
    ->timezone(config('app.timezone'))
    ->name('DELETE_OUTBOXES_OLDER_THAN_A_MONTH');

    // RESET_WELCOME_MSG_TIMER daily hour 00:00
    $schedule->call(function () {
      Device::where('status', 'ONLINE')->update(['welcome_cust' => '[]']);
    })
    ->daily()
    ->timezone(config('app.timezone'))
    ->name('RESET_WELCOME_MSG_TIMER');

    // AUTO_RENEW_MONTHLY monthly day 1 hour 00:00
    $schedule->call(function () {
      User::latest()->update(['current_sent' => 0]); // WARNING!! THIS WILL RESET CURRENT SENT TO 0
      sleep(5);
      $response = TransactionController::autoRenew();
    })
    // ->everyMinute()
    ->monthly()
    ->timezone(config('app.timezone'))
    ->name('AUTO_RENEW_MONTHLY');

    // SUBSCRIPTION_REMINDER Last day of the month at 09:00
    $schedule->call(function () {
      self::reminder();
    })
    ->lastDayOfMonth('09:00')
    ->timezone(config('app.timezone'))
    ->name('SUBSCRIPTION_REMINDER');

    // TODO_REMINDERS - Check every 5 minutes for todos that need reminders
    $schedule->command('todo:send-reminders')
      ->everyFiveMinutes()
      ->timezone(config('app.timezone'))
      ->name('TODO_REMINDERS');
  }

  private static function reminder()
  {
    if (!Helpers::isEx()) {
      return;
    }
    $adminSender = Device::where('user_id', 1)->where('status', '=', 'ONLINE')->value('sender');
    $users = User::where('role', '<>', 'admin')
      ->where('billing_end', '>', Carbon::now())
      ->get();
    foreach ($users as $user) {
      if ($user->transactions()->sum('amount') > $user->package->rate_monthly) {
        continue;
      }
      $outbox = new Outbox();
      $outbox->user_id = 1;
      $outbox->job_id = Carbon::now()->timestamp;
      $outbox->sender = $adminSender;
      $outbox->receiver = $user->phone;
      $outbox->rec_name = $user->name;
      $outbox->msgtext = str_ireplace(['{name}', '{appurl}', '{appname}'], [$user->name, rtrim(config('app.url'), '/'), config('app.name')], __('_MsgTopupReminder'));
      $outbox->schedule = Carbon::now();
      $outbox->msgdelay = rand(10, 15);
      $outbox->save();
    }
  }

  /**
   * Register the commands for the application.
   *
   * @return void
   */
  protected function commands()
  {
    $this->load(__DIR__ . '/Commands');

    require base_path('routes/console.php');
  }
}
