<?php

namespace App\Packages\v4\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\v4\User\Notifications\NotificationMentionCapsule;
use App\Packages\v4\User\Notifications\NotificationMentionComment;
use App\Packages\v4\User\Notifications\TypesNotification;
use App\Packages\v4\User\Repository\UserMentionRepository;
use App\Packages\v4\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) ) return true;

        $res = self::getUserNicknameFromString($comment->content);

        if ( empty($res['users']) ) return true;

        foreach( $res['users'] as $user ) {
            /** @var User $user */
            $mention = new UserMention();
            $mention->user_uuid = $user->uuid;
            $mention->nickname = $user->nickname;
            $mention->comment_id = $comment->id;
            $mention->save();

            if ($old_mentioned->isNotEmpty() && $old_mentioned->contains('user_uuid', $user->uuid)) {
                /** if this user existed in mention, dont send notification again */
                continue;
            } else {
                NotificationMentionComment::dispatch($comment, $user)
                    ->onQueue(TypesNotification::QUEUE_NOTIFICATIONS);
            }
        }

        $comment->content = $res['text'];
        $comment->save();

        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) ) return true;

        $res = self::getUserNicknameFromString($capsule->caption);

        if ( empty($res['users']) ) return true;

        foreach( $res['users'] as $user ) {
            /** @var User $user */
            $mention = new UserMention();
            $mention->user_uuid = $user->uuid;
            $mention->nickname = $user->nickname;
            $mention->capsule_id = $capsule->id;
            $mention->save();

            if ($old_mentioned->isNotEmpty() && $old_mentioned->contains('user_uuid', $user->uuid)) {
                /** if this user existed in mention, dont send notification again */
                continue;
            } else {
                NotificationMentionCapsule::dispatch($capsule, $user)
                    ->onQueue(TypesNotification::QUEUE_NOTIFICATIONS);
            }
        }

        $capsule->caption = $res['text'];
        $capsule->save();

        return true;
    }

    public static function normalizeString($string, $mentions)
    {
        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);

            $nickname = 'Removed';

            $mention = $mentions->where('user_uuid', $uuid)->first();
            if ( $mention && !empty($mention->nickname) ) {
                $nickname = $mention->nickname;
            } else {
                $user = UserRepository::init()->firstByUuid($uuid);
                if ( $user ) $nickname = $user->nickname;
            }

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

        return $string;
    }

    private static function getUserNicknameFromString($text)
    {
        preg_match_all(
            '/@[a-zA-Z0-9_\-.]+/',
            $text,
            $matches
        );

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

        $users = [];

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

            $user = UserRepository::init()->firstByNickname($nickname);
            if ( ! $user ) continue;

            $text = str_replace($match, '@{{'.$user->uuid.'}}', $text);

            $users[] = $user;
        }

        return [
            'users' => $users,
            'text' => $text
        ];
    }

    /**
     * @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;
    }
}