<?php declare(strict_types=1);
namespace openvk\VKAPI\Handlers;
use openvk\Web\Models\Entities\User;
use openvk\Web\Models\Repositories\Users as UsersRepo;
use openvk\Web\Models\Entities\Club;
use openvk\Web\Models\Repositories\Clubs as ClubsRepo;
use openvk\Web\Models\Entities\Video as VideoEntity;
use openvk\Web\Models\Repositories\Videos as VideosRepo;
use openvk\Web\Models\Entities\Comment;
use openvk\Web\Models\Repositories\Comments as CommentsRepo;

final class Video extends VKAPIRequestHandler
{
    function get(int $owner_id = 0, string $videos = "", string $fields = "", int $offset = 0, int $count = 30, int $extended = 0): object
    {
        $this->requireUser();

        if(!empty($videos)) {
            $vids = explode(',', $videos);
            $profiles = [];
            $groups = [];
            foreach($vids as $vid) {
                $id    = explode("_", $vid);
                $items = [];
    
                $video = (new VideosRepo)->getByOwnerAndVID(intval($id[0]), intval($id[1]));
                if($video && !$video->isDeleted()) {
                    $out_video = $video->getApiStructure($this->getUser())->video;
                    $items[] = $out_video;
                    if($out_video['owner_id']) {
                        if($out_video['owner_id'] > 0) 
                            $profiles[] = $out_video['owner_id'];
                        else
                            $groups[] = abs($out_video['owner_id']);
                    }
                }
            }

            if($extended == 1) {
                $profiles = array_unique($profiles);
                $groups   = array_unique($groups);
    
                $profilesFormatted = [];
                $groupsFormatted   = [];
    
                foreach($profiles as $prof) {
                    $profile = (new UsersRepo)->get($prof);
                    $profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields);
                }
    
                foreach($groups as $gr) {
                    $group = (new ClubsRepo)->get($gr);
                    $groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields);
                }
    
                return (object) [
                    "count" => sizeof($items),
                    "items" => $items,
                    "profiles" => $profilesFormatted,
                    "groups" => $groupsFormatted,
                ];
            }
    
            return (object) [
                "count" => count($items),
                "items" => $items
            ];
        } else {
            if ($owner_id > 0) 
                $user = (new UsersRepo)->get($owner_id);
            else
                $this->fail(1, "Not implemented");
            
            if(!$user || $user->isDeleted())
                $this->fail(14, "Invalid user");

            if(!$user->getPrivacyPermission('videos.read', $this->getUser()))
                $this->fail(21, "This user chose to hide his videos.");

            $videos = (new VideosRepo)->getByUserLimit($user, $offset, $count);
            $videosCount = (new VideosRepo)->getUserVideosCount($user);
            
            $items = [];
            $profiles = [];
            $groups = [];
            foreach($videos as $video) {
                $video   = $video->getApiStructure($this->getUser())->video;
                $items[] = $video;
                if($video['owner_id']) {
                    if($video['owner_id'] > 0) 
                        $profiles[] = $video['owner_id'];
                    else
                        $groups[] = abs($video['owner_id']);
                }
            }

            if($extended == 1) {
                $profiles = array_unique($profiles);
                $groups   = array_unique($groups);
    
                $profilesFormatted = [];
                $groupsFormatted   = [];
    
                foreach($profiles as $prof) {
                    $profile = (new UsersRepo)->get($prof);
                    $profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields);
                }
    
                foreach($groups as $gr) {
                    $group = (new ClubsRepo)->get($gr);
                    $groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields);
                }
    
                return (object) [
                    "count" => $videosCount,
                    "items" => $items,
                    "profiles" => $profilesFormatted,
                    "groups" => $groupsFormatted,
                ];
            }
    
            return (object) [
                "count" => $videosCount,
                "items" => $items
            ];
        }
    }

    function search(string $q = '', int $sort = 0, int $offset = 0, int $count = 10, bool $extended = false, string $fields = ''): object 
    {
        $this->requireUser();

        $params = [];
        $db_sort = ['type' => 'id', 'invert' => false];
        $videos = (new VideosRepo)->find($q, $params, $db_sort);
        $items  = iterator_to_array($videos->offsetLimit($offset, $count));
        $count  = $videos->size();

        $return_items = [];
        $profiles = [];
        $groups = [];
        foreach($items as $item) {
            $return_item = $item->getApiStructure($this->getUser());
            $return_item = $return_item->video;
            $return_items[] = $return_item;

            if($return_item['owner_id']) {
                if($return_item['owner_id'] > 0) 
                    $profiles[] = $return_item['owner_id'];
                else
                    $groups[] = abs($return_item['owner_id']);
            }
        }

        if($extended) {
            $profiles = array_unique($profiles);
            $groups   = array_unique($groups);

            $profilesFormatted = [];
            $groupsFormatted   = [];

            foreach($profiles as $prof) {
                $profile = (new UsersRepo)->get($prof);
                $profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields);
            }

            foreach($groups as $gr) {
                $group = (new ClubsRepo)->get($gr);
                $groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields);
            }

            return (object) [
                "count" => $count,
                "items" => $return_items,
                "profiles" => $profilesFormatted,
                "groups" => $groupsFormatted,
            ];
        }

        return (object) [
            "count" => $count,
            "items" => $return_items,
        ];
    }
}