<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Libs\Database\Eloquent\ContentTypeModel;
use App\Libs\Services\FcmService;
use App\Services\FcmMessageDataService;
use App;
use Illuminate\Support\Facades\Log;

/**
 * Sends FCM notifications to topics associated with a model
 */
class SendFcmMessageToTopic
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;


    protected $item;
    protected $topic;
    protected $titleEmoticon;
    public const QUEUE = 'topic_notifications';

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(ContentTypeModel $item, string $topic)
    {
        $this->item  = $item;
        $this->topic = $topic;
        $this->onQueue(static::QUEUE);
    }

    /**
     * Execute the job.
     *
     * @param FcmService $fcmService
     * @return void
     */
    public function handle(FcmService $fcmService, FcmMessageDataService $fcmMessageDataService): void
    {

        if ($this->item->status !== 'published') {
            Log::warning('An atempt was made to send a topic FCM message on an unpublished item (' . $this->item->title . ')');
            return;
        }


        $langsInfo  = getAvailableLanguages();
        $langCodes  = array_keys($langsInfo);
        $dataToSend = [
            'id'    => $this->item->id,
            'topic' => $this->topic,
        ];


        $fcmContentType = $this->getFcmContentType();
        if ($fcmContentType) {
            $dataToSend['type'] = $fcmContentType;
        }


        //generate the various language topics and handling the content in the correct lang
        foreach ($langCodes as $langCode) {
            $topic = $this->topic . '_' . $langCode;

            //adjust the locale for the correct application of the language for tranalations
            App::setLocale($langCode);

            $title = $this->getTitle();
            $body  = $this->getBody();

            $messageStructure = $fcmService->getTopicMessageStructure($topic, $title, $body, $dataToSend);

            $resSend = $fcmService->sendMessageToTopic($messageStructure);
            //store the result in the FCM Messages table
            if ($resSend) {
                $fcmMessageDataService->addFcmTopicMessage($this->topic, $resSend, $messageStructure, $this->item);
            }
        }
    }


    /**
     * Gets the body of the notification
     */
    private function getBody()
    {

        switch ($this->topic) {
            case  FcmService::TOPIC_NEW_NEWS_ITEM:
                $wordGender    = $this->item->category->word_gender;
                $wordWrittenBy = trans('fcm.strings.written_' . $wordGender);
                $wordComplete  = trans('fcm.strings.complete_' . $wordGender);

                $params = [
                    'title'         => $this->item->title,
                    'written'       => $wordWrittenBy,
                    'author'        => $this->item->author,
                    'category'      => $this->item->category->title,
                    'completeToUse' => $wordComplete,
                ];
                return trans('fcm.topics.' . $this->topic . '.body', $params);;

            case FcmService::TOPIC_NEW_EXHIBITIONS:
                $artist = $this->item->artists->count() > 0 ? $this->item->artists->first() : null;
                $artistName = $artist ? $artist->title : '';
                $params = [
                    'artistName' => $artistName,
                    'name'       => $this->item->title,
                    'spaceName'  => '',
                    'location'   => $this->item->location->title,
                    'cityName'   => $this->item->location->city->title,
                    'startDate'  => date('d.m.Y', strtotime($this->item->date_from)),
                    'endDate'    => date('d.m.Y', strtotime($this->item->date_to))
                ];
                return trans('fcm.topics.' . $this->topic . '.body', $params);;
            default:
                return trans('fcm.topics.' . $this->topic . '.body', ['name' => $this->item->title]);
        }
    }

    /**
     * Gets the title of the notification
     */
    private function getTitle()
    {

        if ($this->topic ===  FcmService::TOPIC_NEW_NEWS_ITEM) {
            $wordGender = $this->item->category->word_gender;
            $wordNew    = trans('fcm.strings.new_' . $wordGender);
            $params     = [
                'articleToUse' => $wordNew,
                'category'     => $this->item->category->title,
            ];
            $title =  trans('fcm.topics.' . $this->topic . '.title', $params);
            $title = "\u{1F4D6}" . ' ' . $title;
            return $title;
        }


        $title = trans('fcm.topics.' . $this->topic . '.title');
        $title = "\u{1F44D}" . ' ' . $title;
        return $title;
    }

    /**
     * Gets the app FCM notification content type
     * @return ?string
     */
    private function getFcmContentType()
    {

        //get the type for the FCM message
        switch (get_class($this->item)) {
            case 'App\Models\NewsItem':
                $fcmContentType = 'atualidade';
                break;
            case 'App\Models\NewsItem':
                $fcmContentType = 'atualidade';
                break;
            case 'App\Models\Exhibition':
                $fcmContentType = 'exposicao';
                break;
            case 'App\Models\Location':
                $fcmContentType = 'espaco';
                break;
            case 'App\Models\Collection':
                $fcmContentType = 'colecao';
                break;
            case 'App\Models\Artist':
                $fcmContentType = 'artista';
                break;
            default:
                $fcmContentType = null;
        }

        return $fcmContentType;
    }
}
