<?php

define('ALC_API', '1');

require '../api.php';

if(!class_exists('AwesomeLiveChat_API')) die('-1');

if(class_exists('AwesomeLiveChat_API_Visitor')) die('-1');

class AwesomeLiveChat_API_Visitor extends AwesomeLiveChat_API
{
    public function __construct()
    {
        $method = strtolower($_SERVER['REQUEST_METHOD']);
        $request = isset($_GET['r'])
            ? trim($_GET['r'], '/')
            : '';
        // dont authenticate if form is submitted.
        $do_auth = !(preg_match('/^auth\.?/', $request) && $method == 'post');
        parent::__construct('json', $do_auth);
    }

    private function suspicion()
    {
        // Block if suspicious ip
        $Block = explode(',', $this->_->settings('block'));
        if(in_array($_SERVER['REMOTE_ADDR'], $Block))
            $this->response(
                $token ? 'Blocked IP' : 'Permission denied',
                $this->HTTP->HTTP_UNAUTHORIZED
            );
    }

    private function ping($sleep)
    {
        if($sleep % 10) return false;
        return $this->_->visitorPing($this->auth_id);
    }

    private function auth($token)
    {
        $Visitor = $this->_->getAVisitor($token);
        $Return = array();
        if($Visitor)
        {
            $status = $Visitor->status;
            if($status == 'waiting' || $status == 'busy')
                $Return = $Visitor;
        }
        $this->response($Return, $this->HTTP->HTTP_OK);
    }

    protected function authenticate()
    {
        $this->suspicion();

        $token = false;
        if($this->auth_token)
        {
            $this->auth_id = $this->_->visitorID($this->auth_token);
            $token = true;
        }
        if(!$this->auth_id)
            $this->response(
                $token ? 'Invalid token' : 'Permission denied',
                $this->HTTP->HTTP_UNAUTHORIZED
            );
        return true;
    }

    public function post_auth()
    {
        $this->suspicion();

        $token = $this->get('token');
        if($token)
        {
            $this->auth($token);
            return false;
        }

        if(!check_ajax_referer('awesome-live-chat', 'nonce', false))
        {
            $this->response(
                'Invalid nonce',
                $this->HTTP->HTTP_BAD_REQUEST
            );
        }

        $name       = $this->post('name');
        $email      = is_email(sanitize_email($this->post('email')));
        $department = $this->_->getDepartment(
            'id', 'id', (int) $this->post('department')
        );
        $website    = $this->post('website');
        $uri        = get_bloginfo('wpurl'); //$this->post('uri');

        $message    = $this->post('message');

        $Errors = array();
        if(!$name)       $Errors[] = '#alc_input_name';
        $email_field = $this->_->settings('general', 'email_field');
        if(!$email && ($email_field == 'required' || $message !== null))
            $Errors[] = '#alc_input_email';
        else if(!$email && $this->post('email') && $email_field == 'optional')
            $Errors[] = '#alc_input_email';
        else if(!$email) $email = '';
        if(!$department)
        {
            if($this->_->settings('general', 'hide_dept') == 'yes')
            {
                $Departments = $this->_->getAllDepartments(true);
                if(count($Departments) == 1)
                {
                    $D = array_shift($Departments);
                    $department = $D->id;
                }
                else $Errors[] = '#alc_input_department';
            }
            else $Errors[] = '#alc_input_department';
        }
        if($message !== null && !$message)
            $Errors[] = '#alc_input_message';

        if($Errors)
        {
            $Response['errors'] = $Errors;
            $this->response(
                $Response,
                $this->HTTP->HTTP_OK
            );
        }
        if($message === null)
        {
            do_action('awesome_live_chat-new_visitor', array(
                'name' => $name,
                'email' => $email,
                'department' => $department,
                'website' => $website,
                'uri' => $uri
            ));
            $this->response(
                $this->_->createVisitor(
                    (string) $name,
                    (string) $email,
                    (int) $department,
                    (string) $website,
                    (string) $uri
                ), $this->HTTP->HTTP_OK
            );
        }
        else // offline message
        {
            $this->response(
                $this->_->sendOfflineMessage(
                    (string) $name,
                    (string) $email,
                    (int) $department,
                    (string) $website,
                    (string) $uri,
                    (string) $message
                ), $this->HTTP->HTTP_OK
            );
        }
    }

    public function get_operator()
    {
        $quick = $this->get('quick', false);
        settype($quick, 'bool');

        $raw = $this->get('raw', false);
        settype($raw, 'bool');

        $did = $this->_->getVisitor(
            'department',
            'id',
            (int) $this->auth_id
        );

        $oid = 0;
        $sleep = 0;
        $end = false;
        $this->ping(10);
        do {
            if($sleep++) sleep(1);
            if($this->timeout < $sleep)
                break;
            $this->ping($sleep);
            $oid = $this->_->visitorOperator($this->auth_id);
            $this->_->touchSettings();
            $end = !$this->_->isOnline($did);
            if($quick) break;
        } while (!$oid && !$end);

        $Response = array();
        if($oid)
        {
            $Operator = get_userdata($oid);
            $Response = array(
                'name'     => $Operator->display_name,
                'gravatar' => $this->_->gravatarOperator($oid, $Operator->user_email)
            );
        }
        else if($end && !$raw)
        {
            $this->_->setVisitor(
                'status',
                'id',
                (int) $this->auth_id,
                'done'
            );
            $this->response(
                array('end' => true),
                $this->HTTP->HTTP_OK
            );
        }

        $this->response($Response, $this->HTTP->HTTP_OK);
    }

    public function get_chat()
    {
        $quick = $this->get('quick', false);
        settype($quick, 'bool');

        $raw = $this->get('raw', false);
        settype($raw, 'bool');

        $oid = $this->_->visitorOperator($this->auth_id);

        $Chat = array();
        $end = false;
        $this->ping(10);
        $sleep = 0;
        do {
            if($sleep++) sleep(1);
            if($this->timeout < $sleep)
                break;
            $this->ping($sleep);
            $Chat = $this->_->visitorChat(
                $this->auth_id, array('busy'), $this->get('offset', 0)
            );
            $status = $this->_->getVisitor(
                'status',
                'id',
                (int) $this->auth_id
            );
            $this->_->touchSettings();
            $end = $status == 'done';// || !$this->_->isOperatorOnline($oid);
            if($quick) break;
        } while (!$Chat && !$end);

        $Response = array();
        if($Chat) $Response['chat'] = $Chat;
        else if($end && !$raw)
        {
            $this->_->setVisitor(
                'status',
                'id',
                (int) $this->auth_id,
                'done'
            );
            $Response['end']  = true;
        }

        $this->response($Response, $this->HTTP->HTTP_OK);
    }

    public function post_message()
    {
        $message = $this->post('message');
        $guid = $this->post('guid', '');
        if(empty($message))
        {
            $this->response(
                'Message can not be empty',
                $this->HTTP->HTTP_BAD_REQUEST
            );
        }
        $this->response(
            array($this->_->postChat(
                $this->auth_id,
                $this->_->getVisitor('operator_id', 'id', $this->auth_id),
                (strip_tags($message)),
                0, // not operator
                $guid // backbonejs id
            )), $this->HTTP->HTTP_OK
        );
    }

    public function post_end()
    {
        $this->_->setVisitor(
            'status',
            'id',
            (int) $this->auth_id,
            (string) 'done'
        );
        $this->response(array(true), $this->HTTP->HTTP_OK);
    }

    public function get_transcript()
    {
        $this->response(
            $this->_->sendTranscript($this->auth_id),
            $this->HTTP->HTTP_OK
        );
    }

    // for socket
    public function post_ping()
    {
        $this->response($this->ping(10), $this->HTTP->HTTP_OK);
    }
}

new AwesomeLiveChat_API_Visitor();

exit;