<?php

namespace Inside\DESK\Console;

use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Queue;
use Inside\Content\Models\Contents\Users;
use Inside\DESK\Jobs\SendNewsletter;
use Inside\LHG\Facades\RightApi;

class SendNewsletters extends Command
{
    /**
     * @var string
     */
    protected $name = 'desk:send-newsletters';

    /*
   * @var string
   */
    protected $signature = 'desk:send-newsletters {--email=} {--batchsize=} {--test} {--start=}';

    /**
     * @var string
     */
    protected $description = 'Send newsletters';

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Import users
     */
    public function handle(): void
    {
        $newslettersEnabled = setting('desk', 'send_newsletters', 1);

        if (!$newslettersEnabled && !$this->option('test')) {
            return;
        }

        $users = Users::query();


        $users->where('status', 1)
            ->whereIn('right_notification', [RightApi::NEWSLETTER, RightApi::BOTH]);

        $totalUsersCount = Users::where('status', 1)
            ->whereIn('right_notification', [RightApi::NEWSLETTER, RightApi::BOTH])
            ->count();

        $alreadySentCount = 0;
        $salveCount = 0;

        $email = $this->option('email');

        /** @var string|null $startDate */
        $startDate = $this->option('start');

        if (!$startDate) {
            /** @var string $startDate */
            $startDate = date('Y-m-d');
        }

        $slackUsers = [];

        if ($email) {
            $users->where('email', $email);
        } else {
            if ($this->option('test')) {
                $recipients = explode(',', env('DESK_NEWSLETTER_TEST_RECIPIENTS', ''));

                $emails = [];

                foreach ($recipients as $recipient) {
                    $recipient = explode('|', $recipient);

                    $emails[] = $recipient[0];

                    if (count($recipient) === 2) {
                        $slackUsers[] = $recipient[1];
                    }
                }

                if (empty($emails)) {
                    return;
                }

                $users->whereIn('email', $emails);
            } else {
                $batchSize = (int)$this->option('batchsize');

                if ($batchSize && $batchSize > -1) {
                    /** @var string $batchStart */
                    $batchStart = env('DESK_NEWSLETTERS_BATCH_START', '12:00');
                    $today = $startDate.' '.$batchStart.':00';
                    $alreadySent = DB::table('desk_newsletters_sent')->where('date_sent', $today)->pluck('user_uuid')->toArray();
                    $alreadySentCount = count($alreadySent);

                    $chunks = array_chunk($alreadySent, 300);

                    foreach ($chunks as $chunk) {
                        $users->whereNotIn('uuid', $chunk);
                    }

                    $users->limit($batchSize);
                }
            }
        }

        $users = $users->get();
        $salveCount = $users->count();

        Log::info(sprintf(
            "Newsletters send : Already Send (%s) - Sending (%s)  - Total to be send (%s)",
            $alreadySentCount,
            $salveCount,
            $totalUsersCount
        ));

        foreach ($users as $user) {
            if ($this->option('test')) {
                DB::table('desk_newsletters_sent')->where([
                    'user_uuid' => $user->uuid,
                ])->delete();
            }

            Queue::push(new SendNewsletter($user, $startDate, (bool)$this->option('test')), '', env('DESK_NEWSLETTERS_QUEUE', 'desk_newsletters'));
        }

        if ($this->option('test')) {
            $this->sendSlackNotification($slackUsers);
        }
    }

    protected function sendSlackNotification(array $slackUsers): void
    {
        if (empty($slackUsers)) {
            return;
        }

        if (empty(env('DESK_SLACK_TOKEN'))) {
            return;
        }

        $client = new Client([
            'headers' => [
                'Authorization' => 'Bearer '.env('DESK_SLACK_TOKEN'),
                'Content-Type' => 'application/json',
            ],
        ]);

        $message = ':mailbox_with_mail: Un test de newsletter vient d\'être envoyé ';

        foreach ($slackUsers as $slackUser) {
            $message .= '<@'.$slackUser.'> ';
        }

        $formData = [
            'form_params' => [
                'channel' => 'projet-desk',
                'text' => trim($message),
                'link_names' => true,
            ],
        ];


        try {
            $client->post('https://slack.com/api/chat.postMessage', $formData)->getBody()->getContents();
        } catch (\Exception $e) {
            return;
        }
    }
}
