<?php
/**
 * Created by PhpStorm.
 * User: ep
 * Date: 12/23/15
 * Time: 6:17 PM
 */

namespace IMATHUZH\Qfq\Api;

require_once(__DIR__ . '/../../vendor/autoload.php');

use IMATHUZH\Qfq\Core\Exception\ErrorHandler;
use IMATHUZH\Qfq\Core\Exception\GenericException;
use IMATHUZH\Qfq\Core\Helper\Support;
use IMATHUZH\Qfq\Core\Helper\SyncByRule;
use IMATHUZH\Qfq\Core\Helper\SyncByRuleValidationException;
use IMATHUZH\Qfq\Core\QuickFormQuery;
use IMATHUZH\Qfq\Core\Store\Store;


/**
 * Return JSON encoded answer
 *
 * status: success|error
 * message: <message>
 * redirect: client|url|no
 * redirect-url: <url>
 * field-name: <field name>
 * field-message: <message>
 * form-data: [ fieldname1 => value1, fieldname2 => value2, ... ]
 * form-control: [ fieldname1 => status1, fieldname2 => status2, ... ]  status: show|hide, enabled|disabled,
 * readonly|readwrite
 *
 * Description:
 *
 * Save successful. Button 'close', 'new'. Form.forward: 'auto'. Client logic decide to redirect or not. Show message
 * if no redirect. status = 'success' message = <message> redirect = 'client'
 *
 * Save successful. Button 'close': Form.forward: 'page'. Client redirect to url.
 *  status = 'success'
 *  message = <message>
 *  redirect = 'url'
 *  redirect-url = <URL>
 *
 * Save failed: Button: any. Show message and set 'alert' on _optional_ specified form element. Bring 'pill' of
 * specified form element to front. status = 'error' message = <message> redirect = 'no' Optional: field-name = <field
 * name> field-message = <message appearing as tooltip (or similar) near the form element>
 */

// Detect API calls if this is defined. Do not try use "const QFQ_API 'Api call'" in Constanst.php : this will break detection of API Calls
define('QFQ_API', 'Api call');

$answer = array();

$answer[API_REDIRECT] = API_ANSWER_REDIRECT_NO;
$answer[API_STATUS] = API_ANSWER_STATUS_ERROR;
$answer[API_MESSAGE] = '';

try {
    try {
        ErrorHandler::useAsPhpErrorHandler();
        $qfq = new QuickFormQuery([T3DATA_BODYTEXT => ''], isApi: true);
        $mode = Store::getVar(API_MODE, STORE_SIP);
        switch ($mode) {
            case CHAT_MODE_LOAD:
            case CHAT_MODE_TOOLBAR_LOAD:
                $data = $qfq->updateChat($mode);
                $answer[API_CHAT_UPDATE] = $data;
                break;
            case RECORD_HISTORY_LOAD:
                $data = $qfq->loadRecordHistory();
                $answer[API_RECORD_HISTORY_DATA] = $data;
                break;
            case INPUT_FILTER_COUNT_MODE:
                // Get filter counts for faceted filtering (batch mode)
                $requestData = json_decode(file_get_contents('php://input'), true) ?? [];
                $answer[API_INPUT_FILTER_COUNTS] = $qfq->getFilterCountsBatch($requestData);
                break;
            case SYNC_BY_RULE_EXPORT:
            case SYNC_BY_RULE_IMPORT:
                if ($mode === SYNC_BY_RULE_EXPORT) {
                    $content = Store::getVar(SYNC_BY_RULE_VALUE, STORE_SIP);
                    // If empty, check for dynamic rule selection (container mode with checkboxes)
                    if (empty($content)) {
                        $requestData = json_decode(file_get_contents('php://input'), true);
                        $ruleSips = $requestData[SYNC_BY_RULE_SIPS] ?? null;

                        if (!empty($ruleSips) && is_array($ruleSips)) {
                            // Decrypt each SIP and merge the rule definitions
                            $content = SyncByRule::mergeRuleSips($ruleSips);
                        }
                    }

                    $syncByRule = New SyncByRule($content);
                    $data = $syncByRule->handleExport();
                } else {
                    $requestData = json_decode(file_get_contents('php://input'), true);
                    $content = $requestData[SYNC_BY_RULE_JS_JSON_DATA] ?? null;
                    $syncByRule = New SyncByRule($content);
                    $overrideContent = Store::getVar(SYNC_BY_RULE_VALUE, STORE_SIP);
                    $data = $syncByRule->handleImport($overrideContent);
                }
                $answer[API_SYNC_BY_RULE_DATA] = $data;
                break;
            default:
                $data = $qfq->updateForm();
                $answer[API_FORM_UPDATE] = $data[API_FORM_UPDATE];
                $answer[API_ELEMENT_UPDATE] = $data[API_ELEMENT_UPDATE] ?? '';
        }

        $answer[API_STATUS] = API_ANSWER_STATUS_SUCCESS;
        $answer[API_MESSAGE] = 'load: success';

    } catch (SyncByRuleValidationException $e) {
        // Handle SyncByRule validation errors with specific error type
        $answer[API_MESSAGE] = $e->getMessage();
        $answer[API_SYNC_BY_RULE_ERROR_TYPE] = $e->getErrorType();
        $answer[API_SYNC_BY_RULE_ERROR_MESSAGE] = $e->getMessage();

    } catch (\UserFormException $e) {
        $answer[API_MESSAGE] = $e->formatMessage();

        $val = Store::getVar(SYSTEM_FORM_ELEMENT, STORE_SYSTEM);
        if ($val !== false)
            $answer[API_FIELD_NAME] = $val;

        $val = Store::getVar(SYSTEM_FORM_ELEMENT_MESSAGE, STORE_SYSTEM);
        if ($val !== false)
            $answer[API_FIELD_MESSAGE] = $val;

    } catch (\CodeException $e) {
        $answer[API_MESSAGE] = $e->formatMessage();
    } catch (\DbException $e) {
        $answer[API_MESSAGE] = $e->formatMessage();
    }

} catch (\Throwable $e) {
    $wrapped = Support::wrapUnexpectedException($e);
    try {
        $answer[API_MESSAGE] = $wrapped->formatException();
    } catch (\Throwable $exception) {
        $answer[API_MESSAGE] = 'An unexpected error occurred.';
    }
}

header("Content-Type: application/json");
echo json_encode($answer);