<?php

namespace App\Packages\User\Service;

use App\Packages\Capsule\Models\Capsule;
use App\Packages\Capsule\Models\CapsuleComment;
use App\Packages\User\Models\User;
use App\Packages\User\Models\UserMention;
use App\Packages\User\Models\UserNotification;
use App\Packages\User\Models\UserNotificationPush;
use App\Packages\User\Notifications\NotificationMentionCapsule;
use App\Packages\User\Notifications\NotificationMentionComment;
use App\Packages\User\Notifications\TypesNotification;
use App\Packages\User\Repository\UserMentionRepository;
use App\Packages\User\Repository\UserRepository;

/**
 * Class UserMentionService
 * @package App\Packages\User\Service
 */
class UserMentionService {

    /**
     * @param CapsuleComment $comment
     *
     * @return bool
     */
    public static function processComment(CapsuleComment $comment)
    {
        $old_mentioned = UserMentionRepository::init()->getAllFromComment($comment);
        UserMentionRepository::init()->deleteAllFromComment($comment);

        if ( empty($comment) ) {
            self::removeAllCommentNotifications($comment);
            return true;
        }

        $users = self::getUserUuidFromString($comment->content);

        if ( empty($users) ) {
            self::removeAllCommentNotifications($comment);
            return true;
        }

        foreach( $users as $user ) {
            $mention = new UserMention();
            $mention->user_uuid = $user->uuid;
            $mention->comment_id = $comment->id;
            $mention->save();

            if ($old_mentioned->isNotEmpty() && $old_mentioned->contains('user_uuid', $user->uuid)) {
                continue;
            } else {
                NotificationMentionComment::dispatch($comment, $user)
                    ->onQueue(TypesNotification::QUEUE_NOTIFICATIONS);
            }
        }

        return true;
    }

    /**
     * @param Capsule $capsule
     *
     * @return bool
     */
    public static function processCapsuleCaption(Capsule $capsule)
    {
        $old_mentioned = UserMentionRepository::init()->getAllFromCapsule($capsule);
        UserMentionRepository::init()->deleteAllFromCapsule($capsule);

        if ( empty($capsule->caption) ) {
            self::removeAllCapsuleNotifications($capsule);
            return true;
        }

        $users = self::getUserUuidFromString($capsule->caption);

        if ( empty($users) ) {
            self::removeAllCapsuleNotifications($capsule);
            return true;
        }

        foreach( $users as $user ) {
            $mention = new UserMention();
            $mention->user_uuid = $user->uuid;
            $mention->capsule_id = $capsule->id;
            $mention->save();

            if ($old_mentioned->isNotEmpty() && $old_mentioned->contains('user_uuid', $user->uuid)) {
                continue;
            } else {
                NotificationMentionCapsule::dispatch($capsule, $user)
                    ->onQueue(TypesNotification::QUEUE_NOTIFICATIONS);
            }
        }

        return true;
    }

    public static function removeAllCommentMention($comment)
    {
        UserMentionRepository::init()->deleteAllFromComment($comment);
        self::removeAllCommentNotifications($comment);

        return true;
    }

    public static function removeAllCapsuleMention($capsule)
    {
        UserMentionRepository::init()->deleteAllFromCapsule($capsule);
        self::removeAllCapsuleNotifications($capsule);

        return true;
    }

    public static function normalizeString($string)
    {
        preg_match_all(
            '/@{{[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}}}/',
            $string,
            $matches
        );

        if ( ! isset($matches[0][0]) ) return $string;

        foreach( $matches[0] as $match ) {
            $uuid = str_replace('@{{', '', $match);
            $uuid = str_replace('}}', '', $uuid);

            $user = UserRepository::init()->firstByUuid($uuid);
            if ( ! $user ) continue;

            $string = str_replace($match, '@'.$user->nickname, $string);
        }

        return $string;
    }

    private static function removeAllCommentNotifications($comment)
    {
        UserNotification::query()->where('type', TypesNotification::COMMENT_MENTION)
            ->where('comment_id', $comment->id)->delete();

        UserNotificationPush::query()->where('type', TypesNotification::COMMENT_MENTION)
            ->where('comment_id', $comment->id)->delete();
    }

    private static function removeAllCapsuleNotifications($capsule)
    {
        UserNotification::query()->where('type', TypesNotification::CAPSULE_MENTION)
            ->where('capsule_id', $capsule->id)->delete();

        UserNotificationPush::query()->where('type', TypesNotification::CAPSULE_MENTION)
            ->where('capsule_id', $capsule->id)->delete();
    }

    /**
     * @param string $text
     *
     * @return array
     */
    private static function getUserUuidFromString($text)
    {
        preg_match_all(
            '/@{{[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}}}/',
            $text,
            $matches
        );

        if ( ! isset($matches[0][0]) ) return [];

        $users = [];

        foreach( $matches[0] as $match ) {
            $uuid = str_replace('@{{', '', $match);
            $uuid = str_replace('}}', '', $uuid);

            $user = UserRepository::init()->firstByUuid($uuid);
            if ( ! $user ) continue;

            $users[] = $user;
        }

        return $users;
    }
}