<?php declare(strict_types=1);
namespace openvk\ServiceAPI;
use Chandler\MVC\Routing\Router;
use openvk\Web\Models\Entities\User;
use openvk\Web\Models\Exceptions\{AlreadyVotedException, InvalidOptionException, PollLockedException};
use openvk\Web\Models\Repositories\Polls as PollRepo;
use UnexpectedValueException;

class Polls implements Handler
{
    protected $user;
    protected $polls;
    
    function __construct(?User $user)
    {
        $this->user  = $user;
        $this->polls = new PollRepo;
    }
    
    private function getPollHtml(int $poll): string
    {
        return Router::i()->execute("/poll$poll", "SAPI");
    }
    
    function vote(int $pollId, string $options, callable $resolve, callable $reject): void
    {
        $poll = $this->polls->get($pollId);
        if(!$poll) {
            $reject("Poll not found");
            return;
        }
        
        try {
            $options = explode(",", $options);
            $poll->vote($this->user, $options);
        } catch(AlreadyVotedException $ex) {
            $reject("Poll state changed: user has already voted.");
            return;
        } catch(PollLockedException $ex) {
            $reject("Poll state changed: poll has ended.");
            return;
        } catch(InvalidOptionException $ex) {
            $reject("Foreign options passed.");
            return;
        } catch(UnexpectedValueException $ex) {
            $reject("Too much options passed.");
            return;
        }
        
        $resolve(["html" => $this->getPollHtml($pollId)]);
    }
    
    function unvote(int $pollId, callable $resolve, callable $reject): void
    {
        $poll = $this->polls->get($pollId);
        if(!$poll) {
            $reject("Poll not found");
            return;
        }
        
        try {
            $poll->revokeVote($this->user);
        } catch(PollLockedException $ex) {
            $reject("Votes can't be revoked from this poll.");
            return;
        }
    
        $resolve(["html" => $this->getPollHtml($pollId)]);
    }
}