<?php

include('../include/functions.php');

ini_set('max_execution_time', 600);
ini_set('memory_limit', '2048M');

$security = 'PNhVNhgCw7dn8KwK';

$token = filter_input(INPUT_GET, 'token');
$command = filter_input(INPUT_GET, 'command');
$since = filter_input(INPUT_GET, 'since');

$body = file_get_contents("php://input");

$key = pack('H*', substr($salt, 64));

if (!empty($token) && $token == $security) {
    $output = fopen('php://output', 'w');
    switch ($command) {
        case 'abgleich':
            outputAbgleichs();
            break;
        case 'users':
            outputUsers($since);
            break;
        case 'user_create':
            $data = json_decode($body, true);
            if (array_key_exists('user', $data)) {
                createUser($data['user']);
            }
            break;
        case 'user_set_password':
            $data = json_decode($body, true);
            if (array_key_exists('user', $data)) {
                changeUserPassword($data['user']);
            }
            break;
        case 'user_unlock':
            $data = json_decode($body, true);
            if (array_key_exists('user', $data)) {
                unlockUser($data['user']);
            }
            break;
        case 'kontobewegungen':
            outputKontobewegungen($since);
            break;
        case 'kontobewegungen_add':
            $data = json_decode($body, true);
            if (array_key_exists('kontobewegungen', $data)) {
                addKontobewegungen($data['kontobewegungen']);
            }
            break;
        case 'categories':
            outputCategories();
            break;
        case 'subcategories':
            outputSubcategories();
            break;
    }
    fclose($output);
} else {
    header('HTTP/1.1 401 Unauthorized');
}

function outputAbgleichs()
{
    global $output;
    $query = 'SELECT id, versnummerneu, vorname, name FROM abgleich WHERE 1';
    $abgleichs = dbQuery($query);
    if ($abgleichs) {
        fputcsv($output, [
            'id',
            'versnummerneu',
            'vorname',
            'name'
        ]);
        while ($abgleich = dbFetchRow($abgleichs)) {
            fputcsv($output, [
                $abgleich['id'],
                cryptValue($abgleich['versnummerneu']),
                cryptValue($abgleich['vorname']),
                cryptValue($abgleich['name'])
            ]);
        }
    }
}

function outputUsers($since = null)
{
    global $output;
    $query = 'SELECT userId, vorname, name, versnummerneu, email, geburtsdatum, passwort, passwort_hash, freigeschaltet, rausfaller, deaktiviert, status FROM users WHERE freigeschaltet=1';
    if (!is_null($since)) {
        $time = new DateTime();
        $time1 = $time->modify('-18 year')->format('Y-m-d');
        $time->setTimestamp($since);
        $time2 = $time->modify('-18 year')->format('Y-m-d');
        $query .= ' AND (aenderungsdatum >= ' . $since . ' OR geburtsdatum BETWEEN "' . $time2 . '" AND "' . $time1 . '")';
    }
    $users = dbQuery($query);
    if ($users) {
        fputcsv($output, [
            'userId',
            'vorname',
            'name',
            'vorname_hash',
            'name_hash',
            'versnummerneu',
            'geburtsdatum',
            'email',
            'u18',
            'passwort',
            'passwort_hash',
            'disable'
        ]);
        while ($user = dbFetchRow($users)) {
            fputcsv($output, [
                $user['userId'],
                encryptValue($user['vorname']),
                encryptValue($user['name']),
                cryptValue($user['vorname']),
                cryptValue($user['name']),
                cryptValue($user['versnummerneu']),
                cryptValue($user['geburtsdatum']),
                $user['email'],
                time() < strtotime($user['geburtsdatum'] . " +18 years") ? '1' : '0',
                $user['passwort'],
                $user['passwort_hash'],
                $user['deaktiviert']
            ]);
        }
    }
}

function createUser($user)
{
    global $output;

    $user['erstellungsdatum'] = time();
    $user['aenderungsdatum'] = date('Y-m-d', time());
    $user['passwort'] = cryptValue($user['passwort']);
    $keys = implode(',', array_keys($user));
    $values = implode('","', array_values($user));
    $query = 'INSERT INTO users (' . $keys . ') VALUES ("' . $values . '")';
    if (dbQuery($query)) {
        $id = dbInsertId();
        $query = 'SELECT userId, versnummerneu, email, geburtsdatum, passwort, passwort_hash, freigeschaltet, rausfaller, status FROM users WHERE userId=' . $id;

        $users = dbQuery($query);
        if ($users) {
            fputcsv($output, [
                'userId',
                'versnummerneu',
                'email',
                'u18',
                'passwort',
                'passwort_hash'
            ]);
            while ($user = dbFetchRow($users)) {
                fputcsv($output, [
                    $user['userId'],
                    cryptValue($user['versnummerneu']),
                    $user['email'],
                    time() < strtotime($user['geburtsdatum'] . " +18 years") ? '1' : '0',
                    $user['passwort'],
                    $user['passwort_hash']
                ]);
            }
        }
    }
}

function changeUserPassword($user)
{
    global $output;
    $updateUserQuery = 'UPDATE users SET passwort="' . $user['password'] . '", passwort_hash="", aenderungsdatum=' . time() . ' WHERE userId=' . $user['userId'];
    if (dbQuery($updateUserQuery)) {
        fputcsv($output, [
            'userId',
            'passwort'
        ]);
        fputcsv($output, [
            $user['userId'],
            $user['password']
        ]);
    }
}

function unlockUser($user)
{
    global $output;
    $updateUserQuery = 'UPDATE users SET freigeschaltet=1 WHERE userId=' . $user['userId'];
    if (dbQuery($updateUserQuery)) {
        fputcsv($output, [
            'userId'
        ]);
        fputcsv($output, [
            $user['userId']
        ]);
    }
}

function addKontobewegungen($kontobewegungen)
{
    global $output;
    $ids = [];
    $headerSetted = false;
    if ($kontobewegungen) {
        foreach ($kontobewegungen as $kontobewegung) {
            $query = 'SELECT vorname, name, strasse, plz, ort, versnummer, versnummerneu, email  FROM users WHERE userId=' . $kontobewegung['userId'];
            $users = dbQuery($query);
            if ($users && $user = dbFetchRow($users)) {
                $kontobewegung['datum'] = time();
                $kontobewegung['zeitstempel'] = time();
                $kontobewegung['datumerwerb'] = date('Y-m-d', time());
                $keys = implode(',', array_keys($kontobewegung));
                $values = implode('","', array_values($kontobewegung));
                $query = 'INSERT INTO kontobewegungen (' . $keys . ') VALUES ("' . $values . '")';
                if (dbQuery($query)) {
                    $ids[] = dbInsertId();
                    $updateUserQuery = 'UPDATE users SET aenderungsdatum=' . time() . ' WHERE userId=' . $kontobewegung['userId'];
                    dbQuery($updateUserQuery);
                    sendAddKontobewegungenMail(array_merge($user, ['praemienname' => $kontobewegung['beschreibung']]));
                }
            } else {
                header("HTTP/1.1 404 Not Found");
                exit();
            }
        }
    }
    if ($ids) {
        foreach ($ids as $id) {
            $query = 'SELECT kontobewegungen.pkey, kontobewegungen.userId, kontobewegungen.kategorie, kontobewegungen.unterkategorie, kontobewegungen.beschreibung, kontobewegungen.datum, kontobewegungen.datumerwerb, kontobewegungen.wert, kontobewegungen.geloescht FROM kontobewegungen WHERE kontobewegungen.pkey=' . $id;
            $kontobewegungen = dbQuery($query);
            if ($kontobewegungen) {
                while ($kontobewegung = dbFetchRow($kontobewegungen)) {
                    if (!$headerSetted) {
                        fputcsv($output, array_keys($kontobewegung));
                        $headerSetted = true;
                    }
                    outputKontobewegung($kontobewegung);
                }
            }
        }
    }
}

function sendAddKontobewegungenMail($data)
{
    $message = 'Ein Teilnehmer hat eine Praemie bestellt:

Vorname:  $vorname$
Name:     $name$
Strasse:  $strasse$
Ort:      $plz$ $ort$
Email:    $email$
Versnr:   $versnummer$
Versnrneu: $versnummerneu$

Folgende Praemie wurde bestellt:

$praemienname$

Die Praemie wurde bereits vom Konto des Benutzers abgebucht.';

    foreach ($data as $key => $value) {
        $message = str_replace('$' . $key . '$', $value, $message);
    }

    $headers = "From: noreply@healthmiles.de" . "\n";

    $headers .= "X-Mailer: PHP\n";
    $headers .= "Mime-Version: 1.0\n";
    $headers .= "Content-Type: text/plain; charset=ISO-8859-15\n";
    $headers .= "Content-Transfer-Encoding: quoted-printable\n";
    $headers .= "Content-Disposition: inline\n";

    $message = qp_enc(utf8_decode($message));

    if (!$result = mail('securvita@healthmiles.de', 'Healthmiles - Praemienbestellung', $message,
        $headers)) {
        return false;
    }

    return true;
}


function outputKontobewegungen($since = null)
{
    global $output;
    $headerSetted = false;
    $query = 'SELECT kontobewegungen.pkey, kontobewegungen.userId, kontobewegungen.kategorie, kontobewegungen.unterkategorie, kontobewegungen.beschreibung, kontobewegungen.datum, kontobewegungen.datumerwerb, kontobewegungen.wert, kontobewegungen.geloescht  FROM kontobewegungen ';
    if (is_null($since)) {
        $query .= 'WHERE kontobewegungen.geloescht != 1';
    } else {
        $query .= 'JOIN users ON (users.userId=kontobewegungen.userId) WHERE kontobewegungen.wert != 0 AND users.freigeschaltet = 1 AND (kontobewegungen.datum >= ' . $since . ' OR  kontobewegungen.zeitstempel >= ' . $since . ')';
    }

    $kontobewegungen = dbQuery($query);
    if ($kontobewegungen) {
        while ($kontobewegung = dbFetchRow($kontobewegungen)) {
            if (!$headerSetted) {
                fputcsv($output, array_keys($kontobewegung));
                $headerSetted = true;
            }
            outputKontobewegung($kontobewegung);
        }
    }
}

function outputKontobewegung($kontobewegung)
{
    global $output;
    if ($kontobewegung['wert'] >= 0) {
        // Warum wird bei wert > 0 die Beschreibung gelöscht??
	    // @TODO 16.08.2021 = wird mit Frau Hoyer geklärt
    	// $kontobewegung['beschreibung'] = '';
    }
    fputcsv($output, [
        $kontobewegung['pkey'],
        $kontobewegung['userId'],
        $kontobewegung['kategorie'],
        $kontobewegung['unterkategorie'],
        $kontobewegung['beschreibung'],
        $kontobewegung['datum'],
        max(0, strtotime($kontobewegung['datumerwerb'])),
        $kontobewegung['wert'],
        $kontobewegung['geloescht'],
    ]);
}

function outputCategories()
{
    global $output;
    $query = 'SELECT pkey, beschreibung FROM kategorie WHERE 1';
    $categories = dbQuery($query);
    if ($categories) {
        fputcsv($output, [
            'pkey',
            'beschreibung'
        ]);
        while ($category = dbFetchRow($categories)) {
            fputcsv($output, [
                $category['pkey'],
                $category['beschreibung']
            ]);
        }
    }
}

function outputSubcategories()
{
    global $output;
    $query = 'SELECT pkey, kategorie, name, beschreibung FROM unterkategorie WHERE 1';
    $subcategories = dbQuery($query);
    if ($subcategories) {
        fputcsv($output, [
            'pkey',
            'kategorie',
            'name',
            'beschreibung'
        ]);
        while ($subcategory = dbFetchRow($subcategories)) {
            fputcsv($output, [
                $subcategory['pkey'],
                $subcategory['kategorie'],
                $subcategory['name'],
                $subcategory['beschreibung']
            ]);
        }
    }
}

function cryptValue($value)
{
    global $salt;
    return hash('sha512', $value . $salt);
}


function encryptValue($value)
{
    if (function_exists('mcrypt_get_iv_size')) {
        global $key;
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $value, MCRYPT_MODE_CBC, $iv);
        $ciphertext = $iv . $ciphertext;
        return base64_encode($ciphertext);
    }
    return $value;
}
