<?php

namespace GriffinForms\Includes\MergeTokens\Resolvers;

use GriffinForms\Includes\MergeTokens\ResolverInterface;

class FieldResolver implements ResolverInterface
{
    public function resolve(array $token, array $context): ?string
    {
        $attr = strtolower((string) ($token['attr'] ?? ''));
        $field_id = isset($token['item_id']) ? (int) $token['item_id'] : 0;
        if ($field_id <= 0) {
            return null;
        }

        $field = null;
        if (class_exists('\\GriffinForms\\Items\\Field')) {
            $field = new \GriffinForms\Items\Field();
            $field->loadItem($field_id);
        }

        if ($attr === 'id') {
            return (string) $field_id;
        }

        if ($field) {
            if ($attr === 'name') {
                return (string) ($field->getProp('name') ?? '');
            }
            if ($attr === 'label') {
                $label = $field->getProp('label');
                if ($label === null || $label === '') {
                    $label = $field->getProp('heading');
                }
                return (string) ($label ?? '');
            }
            if ($attr === 'description') {
                $desc = $field->getProp('description');
                if ($desc === null || $desc === '') {
                    $desc = $field->getProp('helptext');
                }
                return (string) ($desc ?? '');
            }
        }

        if ($attr === 'value' || $attr === 'answer_count') {
            $values = $this->getFieldValues($context, $field_id);
            if ($attr === 'answer_count') {
                return (string) count($values);
            }
            return implode(', ', $values);
        }

        return null;
    }

    /**
     * Flatten all submitted values for a field.
     *
     * @param array $context
     * @param int $field_id
     * @return array<int,string>
     */
    protected function getFieldValues(array $context, int $field_id): array
    {
        $values = [];
        $submission = $context['submission'] ?? [];
        $submission_data = $submission['submission'] ?? $context['submission_data'] ?? [];

        if (!is_array($submission_data)) {
            return [];
        }

        foreach ($submission_data as $page_fields) {
            if (!is_array($page_fields)) {
                continue;
            }
            if (!array_key_exists($field_id, $page_fields)) {
                continue;
            }
            $values = array_merge($values, $this->flattenValue($page_fields[$field_id]));
        }

        $values = array_map('trim', $values);
        $values = array_filter($values, static function ($value) {
            return $value !== '';
        });

        return array_values($values);
    }

    /**
     * @param mixed $value
     * @return array<int,string>
     */
    protected function flattenValue($value): array
    {
        if (is_array($value)) {
            $out = [];
            foreach ($value as $entry) {
                $out = array_merge($out, $this->flattenValue($entry));
            }
            return $out;
        }

        if (is_scalar($value)) {
            return [(string) $value];
        }

        return [];
    }
}
