<?php

namespace dokuwiki\plugin\swarmwebhook\webhooks;

use dokuwiki\plugin\struct\meta\Schema;

class Zapier extends AbstractWebhook
{
    public function run($json)
    {
        global $conf, $INPUT;

        if ($conf['allowdebug']) {
            dbglog($_SERVER);
        }

        /** @var null|\helper_plugin_swarmwebhook $helper */
        $helper = plugin_load('helper', 'swarmwebhook');
        if (!$helper) {
            http_status(422, 'swarmwebhook plugin not active at this server');
            return;
        }
        if ($helper->getConf('service') !== 'Zapier') {
            http_status(422, 'This service is deactivated in the plugin configuration.');
            return;
        }
        /*
        @FIXME unfotunately Zapier fails to send the respective header, even when configured correctly
        @FIXME until this is resolved by Zapier, this security check is useless 😕
        $storedSecret = $helper->getConf('hook_secret');
        if (!empty($storedSecret)) {
            $requestSecret = $INPUT->server->str('X_HOOK_SECRET');
            if (empty($requestSecret)) {
                http_status(401, 'Header X_HOOK_SECRET missing!');
                return;
            }

            if ($requestSecret !== $storedSecret) {
                http_status(403, 'Header X_HOOK_SECRET not identical with configured secret!');
                return;
            }
        }
        */

        $ok = $this->handleWebhookPayload($json);

        if ($ok) {
            http_status(202);
        }
    }

    /**
     * Stores the webhook's payload to the struct table
     *
     * FIXME: don't set http status here
     *
     * @param string $json the original webhooks payload as json
     *
     * @return bool false if there was an error, http status has already been set, true if everything was ok
     */
    protected function handleWebhookPayload($json)
    {
        /** @var null|\helper_plugin_struct $struct */
        $struct = plugin_load('helper', 'struct');
        if (!$struct) {
            http_status(422, 'struct plugin not active at this server');
            return false;
        }

        /** @var \helper_plugin_swarmwebhook $helper */
        $helper = plugin_load('helper', 'swarmwebhook');

        $lookupData = $this->extractDataFromPayload(json_decode($json, true));
        $lookupData['json'] = $json;

        try {
            $schemas = Schema::getAll('lookup');
            if (!in_array('swarm', $schemas)) {
                $helper->createNewSwarmSchema();
            }

            $helper->deleteCheckinFromLookup($lookupData['checkinid']);
            $helper->saveDataToLookup($lookupData);
        } catch (\Exception $e) { // FIXME: catch more specific exceptions!
            $errorMessage = $e->getMessage();
            dbglog($errorMessage);
            http_status(500, $errorMessage);
            return false;
        }

        return true;
    }



    /**
     * Extract the data to be saved from the payload
     *
     * @param array $data
     *
     * @return array
     */
    protected function extractDataFromPayload(array $data)
    {
        $checkinID = $data['id'];
        $locationName = $data['venue']['name'];

        /** @var \helper_plugin_swarmwebhook $helper */
        $helper = plugin_load('helper', 'swarmwebhook');
        $dateTime = $helper->getDateTimeInstance($data['createdAt'], $data['timeZoneOffset']);

        $lookupData = [
            'date' => $dateTime->format('Y-m-d'),
            'time' => $dateTime->format(\DateTime::ATOM),
            'checkinid' => $checkinID,
            'locname' => $locationName,
            'service' => 'Zapier',
        ];
        if (!empty($data['shout'])) {
            $lookupData['shout'] = $data['shout'];
        }
        return $lookupData;
    }
}
