<?php

$main_class = 'UsersExport';

/**
 * Class UserExport.
 */
class UsersExport
{
    /**
     * @var array
     */
    private $args = [];

    /**
     * @var array
     */
    protected $field_names = [
        'newsletter_logout_link' => 'unsubscribe_link',
        'name' => 'salutation_firstname',
        'surname' => 'salutation_lastname',
    ];

    public function run()
    {
        $this->checkAuth();

        $this->prepareArgs();

        $query = $this->loadData();

        $this->procesData($query);
    }

    public function prepareArgs()
    {
        $this->parseArgsFields();
    }

    public function parseArgsFields()
    {
        $this->args['fields'] = [];

        $fields = getVal('fields', null, '');

        $fields = explode(',', $fields);

        if (empty($fields)) {
            $this->throwErr(204);
        }

        $db_fields = array_flip($this->field_names);

        foreach ($fields as $field) {
            $this->args['fields'][] = !empty($db_fields[$field]) ? $db_fields[$field] : $field;
        }

        $this->args['fields'] = array_merge(['email'], $this->args['fields']);
    }

    /**
     * @return \Doctrine\DBAL\Driver\Statement|int
     */
    public function loadData()
    {
        $qb = sqlQueryBuilder()
            ->select($this->args['fields'])
            ->from('users', 's')->where('s.get_news="Y"');

        try {
            return $qb->execute();
        } catch (Exception $e) {
            if ($e instanceof Doctrine\DBAL\Exception\InvalidFieldNameException) {
                switch ($e->getErrorCode()) {
                    case '1054':
                        $msg = explode('1054', $e->getMessage());
                        $this->setRespCode(406);
                        exit(end($msg));
                    default:
                        throw $e;
                }
            } else {
                throw $e;
            }
        }
    }

    /**
     * @return string
     */
    public function procesData($query)
    {
        while (ob_get_level()) {
            ob_end_flush();
        }

        header('Content-type: application/json');

        echo '[';

        $count = sqlNumRows($query) - 1;

        foreach ($query as $i => $row) {
            // TODO: divnej link na odhlaseni?
            $row['newsletter_logout_link'] = '/launch.php?s=mailing&acn=emailUnsubscribed&email='.$row['email'];

            echo json_encode($this->formatRow($row)).(($i < $count) ? ',' : '');

            if ($i % 1000 == 0) {
                flush();
            }
        }

        echo ']';
    }

    /**
     * @return array
     */
    public function formatRow($row)
    {
        $data = [];

        foreach ($row as $key => $value) {
            if ($key == 'email' || $key == 'passw') {
                continue;
            }

            if (!empty($this->field_names[$key])) {
                $data[] = [$this->field_names[$key], $value];
            } else {
                $data[] = [$key, $value];
            }
        }

        return [
            'email' => $row['email'],
            'tags' => $data,
        ];
    }

    public function setRespCode($number)
    {
        http_response_code($number);
    }

    public function throwErr($number)
    {
        $this->setRespCode($number);
        exit;
    }

    public function checkAuth()
    {
        if (empty($_SERVER['PHP_AUTH_USER']) || empty($_SERVER['PHP_AUTH_PW'])) {
            $this->throwErr(401);
        }

        $login = $_SERVER['PHP_AUTH_USER'];
        $password = $_SERVER['PHP_AUTH_PW'];

        $user = sqlFetchArray(sqlQuery('SELECT * FROM admins WHERE login=:login', ['login' => $login]));

        if (!password_verify($password, $user['password'])) {
            $this->throwErr(403);
        }

        return true;
    }
}
