<?php
namespace Api\Controllers\V1;

use Api\Core\Config;
use Api\Core\Request;
use Api\Core\Response;
use ElixForms\Auth\ElixFormsApiClient;
use ElixForms\Auth\ElixFormsAuthenticationClient;
use ElixForms\Exceptions\ElixFormsException;

class ElixFormsController
{
    private ElixFormsAuthenticationClient $authenticationClient;
    private ElixFormsApiClient $apiClient;
    private Config $config;

    public function __construct(
        ElixFormsAuthenticationClient $authenticationClient,
        ElixFormsApiClient $apiClient,
        Config $config
    ) {
        $this->authenticationClient = $authenticationClient;
        $this->apiClient = $apiClient;
        $this->config = $config;
    }

    public function searchInstances(Request $req, Response $res)
    {
        $query = $req->query();
        $moduleTag = $this->requiredString($query, 'moduleTag');
        $fieldName = $this->requiredString($query, 'fieldName');
        $fieldValue = $this->requiredString($query, 'fieldValue');
        $exportGroup = $this->optionalNonEmptyString($query, 'exportGroup', 'API');

        if ($moduleTag === null || $fieldName === null || $fieldValue === null || $exportGroup === null) {
            return $res->json([
                'error' => 'moduleTag, fieldName e fieldValue sono obbligatori; exportGroup, se specificato, deve essere una stringa non vuota.'
            ], 400);
        }

        $username = $this->config->secret('elixforms_api_username');
        $password = $this->config->secret('elixforms_api_password');

        if (!is_string($username) || trim($username) === '' || !is_string($password) || $password === '') {
            throw new ElixFormsException('Credenziali elixForms non configurate.');
        }

        $token = $this->authenticationClient->login($username, $password);
        $instances = $this->apiClient->lookupByStatus($moduleTag, $token, $username);
        $matchingInstances = [];

        foreach ($instances as $instance) {
            if (!\is_array($instance)) {
                continue;
            }

            $requestId = $this->requestId($instance);
            if ($requestId === null) {
                continue;
            }

            $exportTags = $this->apiClient->getExportTags(
                $requestId,
                $moduleTag,
                $token,
                $username,
                $exportGroup
            );

            $exportTagsByName = array_column($exportTags, null, 'name');
            if (!\array_key_exists($fieldName, $exportTagsByName)) {
                continue;
            }

            $exportTag = $exportTagsByName[$fieldName];
            $value = isset($exportTag['value']) ? (string) $exportTag['value'] : '';

            if (stripos($value, $fieldValue) !== false) {
                $matchingInstances[] = $instance;
            }
        }

        return $res->json($matchingInstances);
    }

    private function requiredString(array $values, string $key): ?string
    {
        if (!isset($values[$key]) || !is_string($values[$key])) {
            return null;
        }

        $value = trim($values[$key]);

        return $value === '' ? null : $value;
    }

    private function optionalNonEmptyString(array $values, string $key, string $default): ?string
    {
        if (!array_key_exists($key, $values)) {
            return $default;
        }

        if (!is_string($values[$key])) {
            return null;
        }

        $value = trim($values[$key]);

        return $value === '' ? null : $value;
    }

    private function requestId(array $instance)
    {
        foreach (['idDomanda', 'requestId', 'idRequest'] as $key) {
            if (isset($instance[$key]) && (is_int($instance[$key]) || is_string($instance[$key]))) {
                return $instance[$key];
            }
        }

        return null;
    }
}
