<?php

namespace Shm\ShmChat\ShmChatBlueprints;

use Shm\Shm;
use Shm\ShmAuth\Auth;
use Shm\ShmChat\ListQueryInput;
use Shm\ShmChat\Member;
use Shm\ShmChat\SchemaChat\ShmChannelMessages;
use Shm\ShmChat\SchemaChat\ShmChannelMessagesField;
use Shm\ShmChat\SchemaChat\ShmChannels;
use Shm\ShmChat\SchemaChat\ShmFastAnswers;
use Shm\ShmChat\SchemaChat\ShmFastAnswersField;
use Shm\ShmChat\ShmChatService;
use Shm\ShmDB\mDB;
use Shm\ShmRPC\ShmRPC;
use Shm\ShmUtils\I18n;

class ShmChatBlueprintsClientRPC extends ShmChatBlueprintsBaseRPC
{


    public static function init(array $authStructures = [])
    {


        $methods =  [

            "auth" => ShmRPC::auth()->email()->auth($authStructures),

            "authEnabled" => ShmRPC::lazy(function () use ($authStructures) {
                return [
                    'type' => Shm::bool(),
                    'resolve' => function ($rootValue, array $args) use ($authStructures) {
                        return count($authStructures) > 0;
                    }
                ];
            }),

            'profileInfo' => ShmRPC::lazy(function () use ($authStructures) {
                return [
                    'type' => Shm::structure([
                        "profileID" => Shm::string(),
                        "authEnabled" => Shm::bool(),

                    ]),
                    'resolve' => function ($rootValue, array $args) use ($authStructures) {

                        Auth::authenticateOrThrow();

                        return [
                            "profileID" => (string) Auth::getAuthID(),
                            "authEnabled" => count($authStructures) > 0,
                        ];
                    }
                ];
            }),

            'channelInfo' => ShmRPC::lazy(function () {

                return [

                    'type' =>  ShmChannels::structure(),

                    'args' => Shm::structure([
                        'channel' => Shm::ID(),

                    ]),
                    'resolve' => function ($rootValue, array $args) {


                        if (!isset($args['channel'])) {
                            Shm::error(I18n::get('channel_not_found'));
                        }


                        self::accessValidator($args['channel']);

                        return self::runChat(function () use ($args) {
                            return ShmChatService::requireChannel($args['channel']);
                        });
                    }
                ];
            }),

            'joinChannel' => ShmRPC::lazy(function () {
                return [
                    'type' => Shm::bool(),
                    'args' => [
                        "channel" =>  Shm::nonNull(Shm::ID()),
                    ],
                    'resolve' => function ($rootValue, array $args) {
                        Auth::authenticateOrThrow();

                        self::accessValidator($args['channel']);

                        return self::runChat(function () use ($args) {
                            return ShmChatService::addMember($args['channel'], Member::fromAuth());
                        });
                    }
                ];
            }),


            'joinChannelList' => ShmRPC::lazy(function () {
                return [
                    'type' => Shm::structure([
                        'data' => Shm::arrayOf(ShmChannels::structure()),
                        'hash' => Shm::string()
                    ]),
                    'args' => [
                        "limit" => Shm::int()->default(50)->title("Количество сообщений"),
                        "offset" => Shm::int()->default(0)->title("Смещение"),
                        "onlyHash" => Shm::bool()->default(false)->title("Только хэш"),
                    ],
                    'resolve' => function ($rootValue, array $args) {
                        Auth::authenticateOrThrow();

                        return self::runChat(function () use ($args) {
                            return ShmChatService::listJoinableChannels(
                                Member::fromAuth(),
                                ListQueryInput::fromRpcArgs($args),
                            );
                        });
                    }
                ];
            }),

            "closedChannelList" => ShmRPC::lazy(function () {
                return [
                    'type' => Shm::structure([
                        'data' => Shm::arrayOf(ShmChannels::structure()),
                        'hash' => Shm::string()
                    ]),
                    'args' => [
                        "limit" => Shm::int()->default(50)->title("Количество сообщений"),
                        "offset" => Shm::int()->default(0)->title("Смещение"),
                        "onlyHash" => Shm::bool()->default(false)->title("Только хэш"),
                    ],
                    'resolve' => function ($rootValue, array $args) {
                        Auth::authenticateOrThrow();
                        return self::runChat(function () use ($args) {
                            return ShmChatService::listClosedChannels(
                                Member::fromAuth(),
                                ListQueryInput::fromRpcArgs($args),
                            );
                        });
                    }
                ];
            }),



            'fastAnswers' => ShmRPC::lazy(function () {
                return [
                    'type' => Shm::arrayOf(ShmFastAnswers::structure()),
                    'resolve' => function ($rootValue, array $args) {
                        Auth::authenticateOrThrow();

                        return ShmFastAnswers::find([
                            ShmFastAnswersField::OWNER => Auth::getAuthID(),
                            ShmFastAnswersField::OWNER_COLLECTION => Auth::getAuthCollection(),
                        ]);
                    }
                ];
            }),
            'mFastAnswers' => ShmRPC::lazy(function () {
                return [
                    'type' => Shm::bool(),
                    'args' => [
                        'id' => Shm::ID(),
                        'delete' => Shm::bool()->title("Удалить"),
                        'name' => Shm::string()->title("Название"),
                        'text' => Shm::string()->title("Текст"),
                    ],
                    'resolve' => function ($rootValue, array $args) {
                        Auth::authenticateOrThrow();

                        if (isset($args['id'])) {

                            $delete = $args['delete'] ?? false;
                            if ($delete) {
                                ShmFastAnswers::structure()->deleteOne([
                                    ShmFastAnswersField::_ID => mDB::id($args['id']),
                                    ShmFastAnswersField::OWNER => Auth::getAuthID(),
                                    ShmFastAnswersField::OWNER_COLLECTION => Auth::getAuthCollection(),
                                ]);
                                return true;
                            }

                            $name = $args['name'] ?? '';
                            $text = $args['text'] ?? '';

                            $set = [];

                            if ($name) {
                                $set[ShmFastAnswersField::NAME] = $name;
                            }
                            if ($text) {
                                $set[ShmFastAnswersField::TEXT] = $text;
                            }

                            if (count($set) > 0) {
                                ShmFastAnswers::structure()->updateOne([
                                    ShmFastAnswersField::_ID => mDB::id($args['id']),
                                    ShmFastAnswersField::OWNER => Auth::getAuthID(),
                                    ShmFastAnswersField::OWNER_COLLECTION => Auth::getAuthCollection(),
                                ], ['$set' => $set]);
                            }

                            return true;
                        } else {

                            $name = $args['name'] ?? '';
                            $text = $args['text'] ?? '';

                            if (!$name || !$text) {
                                Shm::error(I18n::get('name_and_text_are_required'));
                            }

                            $insert = ShmFastAnswers::structure()->insertOne([
                                ShmFastAnswersField::OWNER => Auth::getAuthID(),
                                ShmFastAnswersField::OWNER_COLLECTION => Auth::getAuthCollection(),
                                ShmFastAnswersField::NAME => $name,
                                ShmFastAnswersField::TEXT => $text,
                            ]);

                            return true;
                        }
                    }
                ];
            }),

            'channelList' => ShmRPC::lazy(function () {
                return [
                    'type' => Shm::structure([
                        'data' => Shm::arrayOf(ShmChannels::structure()),
                        'hash' => Shm::string()
                    ]),
                    'args' => [
                        "limit" => Shm::int()->default(50)->title("Количество сообщений"),
                        "offset" => Shm::int()->default(0)->title("Смещение"),
                        "onlyHash" => Shm::bool()->default(false)->title("Только хэш"),
                    ],
                    'resolve' => function ($rootValue, array $args) {
                        Auth::authenticateOrThrow();

                        return self::runChat(function () use ($args) {
                            return ShmChatService::listChannelsForMember(
                                Member::fromAuth(),
                                ListQueryInput::fromRpcArgs($args),
                            );
                        });
                    }
                ];
            }),
            'channelSendMessage' => ShmRPC::lazy(function () {
                return [

                    'type' => ShmChannelMessages::structure(),
                    'args' => [
                        'clientMessageId' => Shm::string(),
                        "channel" => Shm::nonNull(Shm::ID()),
                        'reply' => Shm::ID(),
                        "text" => Shm::string()->title("Текст сообщения"),
                        "attachments" => Shm::arrayOf(Shm::fileDocument())->title("Вложения"),
                        'voice' => Shm::fileAudio(),
                        "payload" => Shm::structure([
                            '*' => Shm::mixed()
                        ]),
                    ],
                    'resolve' => function ($rootValue, $args) {

                        self::accessValidator($args['channel']);

                        return self::runChat(function () use ($args) {
                            return ShmChatService::sendMessage(
                                (string) $args['channel'],
                                Member::fromAuth(),
                                $args['text'] ?? '',
                                isset($args['reply']) ? (string) $args['reply'] : null,
                                $args['attachments'] ?? [],
                                $args['voice'] ?? null,
                                $args['payload'] ?? null,
                                $args['clientMessageId'] ?? null,
                            );
                        });
                    },


                ];
            }),




            'channelClose' => ShmRPC::lazy(function () {
                return [
                    'type' => Shm::bool(),
                    'args' => [
                        "channel" => Shm::ID(),
                    ],
                    'resolve' => function ($rootValue, array $args) {
                        self::accessValidator($args['channel']);

                        return self::runChat(function () use ($args) {
                            return ShmChatService::closeChannel($args['channel'], Member::fromAuth());
                        });
                    }
                ];
            }),


            'channelMarkRead' => ShmRPC::lazy(function () {
                return [
                    'type' => Shm::bool(),
                    'args' => [
                        'channel' => Shm::nonNull(Shm::ID()),
                        'lastReadMessageId' => Shm::ID(),
                    ],
                    'resolve' => function ($rootValue, array $args) {
                        self::accessValidator($args['channel']);

                        return self::runChat(function () use ($args) {
                            ShmChatService::markRead(
                                $args['channel'],
                                Member::fromAuth(),
                                isset($args['lastReadMessageId']) ? (string) $args['lastReadMessageId'] : null,
                            );

                            return true;
                        });
                    },
                ];
            }),

            'channelMessages' => ShmRPC::lazy(function () {
                return [
                    'type' => Shm::structure([
                        'data' => Shm::arrayOf(ShmChannelMessages::structure()),
                        'hash' => Shm::string()
                    ]),
                    'args' => [
                        "channel" => Shm::string(),
                        "limit" => Shm::int()->default(50)->title("Количество сообщений"),
                        "offset" => Shm::int()->default(0)->title("Смещение"),
                        "onlyHash" => Shm::bool()->default(false)->title("Только хэш"),
                    ],
                    'resolve' => function ($rootValue, array $args) {


                        if (!isset($args['channel'])) {
                            Shm::error(I18n::get('channel_not_found'));
                        }

                        self::accessValidator($args['channel']);

                        return self::runChat(function () use ($args) {
                            return ShmChatService::listMessages(
                                $args['channel'],
                                ListQueryInput::fromRpcArgs($args),
                            );
                        });
                    }
                ];
            }),

            'pinnedMessage' => ShmRPC::lazy(
                function () {
                    return [
                        'type' => Shm::bool(),
                        'args' => [
                            "message" => Shm::ID(),
                        ],
                        'resolve' => function ($rootValue, array $args) {
                            if (!isset($args['message'])) {
                                Shm::error(I18n::get('message_not_found'));
                            }

                            return self::runChat(function () use ($args) {
                                return ShmChatService::togglePinnedMessage(
                                    $args['message'],
                                    Member::fromAuth(),
                                );
                            });
                        }
                    ];
                }
            ),
            'channelReaction' => ShmRPC::lazy(function () {
                return [
                    'type' => Shm::bool(),
                    'args' => [
                        "message" => Shm::ID(),
                        "channel" => Shm::ID(),
                        "reaction" => Shm::enum(ShmChannelMessagesField::REACTIONS__TYPE_ENUM_ALL_KEYS_VALUES)
                    ],
                    'resolve' => function ($rootValue, array $args) {

                        if (!isset($args['channel']) || !isset($args['message']) || !isset($args['reaction'])) {
                            Shm::error(I18n::get('channel_message_reaction_not_found'));
                        }

                        return self::runChat(function () use ($args) {
                            return ShmChatService::toggleReaction(
                                $args['channel'],
                                $args['message'],
                                $args['reaction'],
                                Member::fromAuth(),
                            );
                        });
                    }
                ];
            }),



            'channelDeleteMessage' => ShmRPC::lazy(function () {
                return [
                    'type' => Shm::bool(),
                    'args' => [
                        "channel" => Shm::ID(),
                        "message" => Shm::ID(),
                    ],
                    'resolve' => function ($rootValue, array $args) {
                        if (!isset($args['channel']) || !isset($args['message'])) {
                            Shm::error(I18n::get('channel_or_message_not_found'));
                        }

                        self::accessValidator($args['channel']);

                        return self::runChat(function () use ($args) {
                            return ShmChatService::deleteMessage(
                                $args['channel'],
                                $args['message'],
                                Member::fromAuth(),
                            );
                        });
                    }
                ];
            }),

            'channelDocumentUpload' => ShmRPC::fileUpload()->document(),
            'channelVoiceUpload' => ShmRPC::fileUpload()->audio(),
        ];




        ShmRPC::init($methods);
    }
}
