<?php

namespace App\Http\Services\V1_1;

use App\Generated\V1_1\DTOs\TimMessageDTO;
use App\Generated\V1_1\Messages\Im\MarkUserMessagesReadMessage;
use App\Generated\V1_1\Messages\Im\DeleteMessage;
use App\Generated\V1_1\Messages\Im\RevokeMessage;
use App\Generated\V1_1\Messages\Im\SendMessage;
use App\Generated\V1_1\Messages\Im\GetUsersLatestsMessage;
use App\Http\Controllers\Miniprogram\Auth;
use App\Managers\FriendManager;
use App\Managers\IMManager;
use App\Services\Pair\PairFirstMatch;
use App\Utils\ImUtil;
use Illuminate\Support\Arr;

class ImService
{
    protected $imUtil;
    protected $imManager;

    public function __construct(ImUtil $imUtil, IMManager $imManager)
    {
        $this->imUtil = $imUtil;
        $this->imManager = $imManager;
    }

    public function markUserMessagesRead(MarkUserMessagesReadMessage $message)
    {
        $timMessage = $message->getMessage();


        $msgRandom = $timMessage->getMsgRandom();
        $msgTimeStamp = $timMessage->getMsgTimeStamp();
        $msgSeq = $timMessage->getMsgSeq();

        $uid = Auth::auth();

        $map = $this->imManager->mapAccountToUserId([
            $fromAccount = $timMessage->getFromAccount(),
            $toAccount = $timMessage->getToAccount(),
        ]);

        $this->imManager->markMessageAsRead($uid, $map[$fromAccount] ?? 0, $map[$toAccount] ?? 0, $msgTimeStamp, $msgRandom, $msgSeq);

        $friendManager = new FriendManager();
        $friendManager->makeZeroUnreadMsg($uid, $map[$toAccount]);
    }

    public function delete(DeleteMessage $message)
    {
        $timMessage = $message->getMessage();


        $msgRandom = $timMessage->getMsgRandom();
        $msgTimeStamp = $timMessage->getMsgTimeStamp();
        $msgSeq = $timMessage->getMsgSeq();

        $uid = Auth::auth();

        $map = $this->imManager->mapAccountToUserId([
            $fromAccount = $timMessage->getFromAccount(),
            $toAccount = $timMessage->getToAccount(),
        ]);

        $this->imManager->deleteMessage($uid, $map[$fromAccount] ?? 0, $map[$toAccount] ?? 0, $msgTimeStamp, $msgRandom, $msgSeq);
    }

    public function revoke(RevokeMessage $message)
    {
        $timMessage = $message->getMessage();


        $msgRandom = $timMessage->getMsgRandom();
        $msgTimeStamp = $timMessage->getMsgTimeStamp();
        $msgSeq = $timMessage->getMsgSeq();

        $uid = Auth::auth();

        $map = $this->imManager->mapAccountToUserId([
            $fromAccount = $timMessage->getFromAccount(),
            $toAccount = $timMessage->getToAccount(),
        ]);

        $this->imManager->revokeMessage($uid, $map[$toAccount] ?? 0, $msgTimeStamp, $msgRandom, $msgSeq);
    }

    public function send(SendMessage $message)
    {
        $pairFirstMatch = new PairFirstMatch(1);
        $pairFirstMatch->run();
    }

    public function getUsersLatests(GetUsersLatestsMessage $message)
    {
        $uids = $message->getUids();

        $uid = Auth::auth();

        $timMessages = $this->imManager->getUserLatestMessages($uid, $uids);
        $timMessages->map(function (&$item) {
            $content = json_decode($item->content, true);
            $item->fromAccount = Arr::get($content, 'From_Account');
            $item->toAccount = Arr::get($content, 'To_Account');
            $item->msgSeq = $item->seq;
            $item->msgRandom = $item->msg_random;
            $item->msgTimeStamp = $item->msg_time_stamp;
            return $item;
        });
        $message->setResponse(TimMessageDTO::initFromModels($timMessages->toArray()));
    }
}
