<?php

namespace Shm\ShmChat\SchemaChat;

use Shm\Collection\Collection;
use Shm\Shm;
use Shm\ShmChat\ShmChat;
use Shm\ShmDB\mDB;
use Shm\ShmTypes\StructureType;

class ShmChannels extends Collection
{


    private static $joinablePipelineHandler = null;

    public static function setJoinablePipelineHandler(callable $pipelineHandler)
    {


        self::$joinablePipelineHandler = $pipelineHandler;
    }

    public static function hasJoinablePipelineHandler(): bool
    {


        return self::$joinablePipelineHandler !== null;
    }

    public static function getJoinablePipelineHandler(): array
    {

        if (self::$joinablePipelineHandler) {
            return (self::$joinablePipelineHandler)();
        }

        return [];
    }


    public function schema(): ?StructureType
    {
        $schema = Shm::structure([
            "space" => Shm::string(),
            "name" => Shm::string(),
            'lastMessage' => ShmChannelMessages::ID(),
            "payload" =>  Shm::structure([
                "*" => Shm::mixed()
            ]),
            'members' => Shm::arrayOf(Shm::structure([
                "owner" => Shm::ID(),
                "ownerCollection" => Shm::string(),
                "role" => Shm::enum([
                    "member" => "Участник",
                    "owner" => "Владелец",
                    "admin" => "Администратор",
                    "support" => "Поддержка",
                ])->default("member"),
            ])),
            'closed' => Shm::boolean()->default(false),

            'unreadCounts' => Shm::structure([
                '*' => Shm::int()
            ]),

            'type' => Shm::enum([
                'default' => 'Обычный чат',
                'support' => 'Поддержка',
                'supportSystem' => 'Поддержка системы',
            ])->default('default'),
        ]);



        return $schema;
    }

    public static function zeroUnreadCounts($channelId, $memberId)
    {
        $channel = ShmChannels::structure()->findOne(['_id' =>  mDB::id($channelId)]);
        if (!$channel) return;

        $unreadCounts =  $channel->unreadCounts ?? [];


        $unreadCounts = (array) $unreadCounts;

        $unreadCounts[(string) $memberId] = 0;

        ShmChannels::structure()->_updateOne(['_id' => mDB::id($channelId)], ['$set' => ['unreadCounts' => $unreadCounts]]);
    }


    public static function getTotalUnreadByOwner($ownerId)
    {

        $ownerId = mDB::id($ownerId);

        $result =  ShmChannels::structure()->aggregate(
            [
                [
                    '$match' => [
                        'members.owner' => $ownerId,
                        'closed' => ['$ne' => true]
                    ]
                ],
                [
                    '$project' => ['unreadCounts' => 1]
                ]
            ]
        )->toArray();

        $total = 0;

        foreach ($result as $channel) {
            $total += $channel->unreadCounts[(string) $ownerId] ?? 0;
        }

        return $total;
    }

    public static function updateUnreadCounts($channelId)
    {




        $channel = ShmChannels::structure()->findOne(['_id' => mDB::id($channelId)]);

        $members = $channel->members ?? [];
        $beforeUnreadCounts = $channel->unreadCounts ?? [];

        $unreadCounts = [];

        foreach ($members as $member) {

            $memberId = (string) $member->owner;
            $currentUnreadCount = $beforeUnreadCounts[$memberId] ?? 0;
            $newUnreadCount = $currentUnreadCount + 1;
            $unreadCounts[$memberId] = $newUnreadCount;
        }

        ShmChannels::structure()->_updateOne(['_id' => $channel->_id], ['$set' => ['unreadCounts' => $unreadCounts]]);
    }
}
