<?php

namespace GriffinForms\Includes\Pipelines;

use GriffinForms\Config;
use GriffinForms\Traits\Singleton;

class SubmissionContextBuilder
{
    use Singleton;

    /** @var string */
    protected $submission_table;

    /** @var string */
    protected $form_table;

    /** @var \wpdb */
    protected $wpdb;

    protected function setSubmissiontable(): void
    {
        $config = Config::getInstance();
        $this->submission_table = $config->getTable('submission');
    }

    protected function setFormtable(): void
    {
        $config = Config::getInstance();
        $this->form_table = $config->getTable('form');
    }

    protected function setWpdb(): void
    {
        global $wpdb;
        $this->wpdb = $wpdb;
    }

    public function build(int $submission_id): array
    {
        $context = [
            'submission_id'  => $submission_id,
            'submission'     => null,
            'submission_meta'=> null,
            'form'           => null,
            'form_meta'      => null,
            'field_values'   => [],
        ];

        if ($submission_id <= 0) {
            return $context;
        }

        $submission = $this->wpdb->get_row(
            $this->wpdb->prepare("SELECT * FROM {$this->submission_table} WHERE id = %d", $submission_id),
            ARRAY_A
        );

        if (!$submission) {
            return $context;
        }

        $submission['submission'] = maybe_unserialize($submission['submission'] ?? null);
        $context['submission'] = $submission;
        $context['submission_meta'] = [
            'id'          => (int) ($submission['id'] ?? 0),
            'form_id'     => (int) ($submission['form_id'] ?? 0),
            'status'      => (int) ($submission['status'] ?? 0),
            'public_token'=> $submission['public_token'] ?? '',
            'submission_edit_count' => isset($submission['submission_edit_count']) ? (int) $submission['submission_edit_count'] : 0,
            'current_revision_id' => isset($submission['current_revision_id']) ? (int) $submission['current_revision_id'] : 0,
            'author'      => isset($submission['author']) ? (int) $submission['author'] : 0,
            'created'     => $submission['created'] ?? '',
        ];
        $form_id = isset($submission['form_id']) ? (int) $submission['form_id'] : 0;
        $context['form_id'] = $form_id;

        if ($form_id > 0) {
            $form = $this->wpdb->get_row(
                $this->wpdb->prepare("SELECT id, name, description, integration_settings FROM {$this->form_table} WHERE id = %d", $form_id),
                ARRAY_A
            );
            if ($form) {
                $context['form'] = $form;
                $context['form_meta'] = [
                    'id'          => (int) ($form['id'] ?? 0),
                    'name'        => $form['name'] ?? '',
                    'description' => $form['description'] ?? '',
                    'integration_settings' => $form['integration_settings'] ?? '',
                ];
                $context['field_values'] = $this->collectFieldValues($form_id, $submission['submission'] ?? []);
            }
        }

        return apply_filters('griffinforms_post_submission_context_built', $context, $submission_id);
    }

    /**
     * Flatten the saved submission into a field-id keyed map for the current form.
     *
     * Removed fields are ignored here so they do not rehydrate into a newer form
     * layout. Newly added fields simply fall back to their normal defaults.
     */
    protected function collectFieldValues(int $form_id, $submission_payload): array
    {
        if ($form_id <= 0 || !is_array($submission_payload)) {
            return [];
        }

        $form = new \GriffinForms\Items\Form();
        if (!$form->loadItem($form_id)) {
            return [];
        }

        $known_fields = [];
        foreach ($form->getFormFields(['id', 'field_type']) as $field_row) {
            $field_id = isset($field_row['id']) ? (int) $field_row['id'] : 0;
            if ($field_id > 0) {
                $known_fields[$field_id] = [
                    'field_type' => sanitize_key((string) ($field_row['field_type'] ?? '')),
                ];
            }
        }

        if (empty($known_fields)) {
            return [];
        }

        $field_values = [];
        foreach ($submission_payload as $page_data) {
            if (!is_array($page_data)) {
                continue;
            }

            foreach ($page_data as $field_id => $value) {
                $field_id = (int) $field_id;
                if ($field_id <= 0 || !isset($known_fields[$field_id])) {
                    continue;
                }

                $field_values[$field_id] = $value;
            }
        }

        return $field_values;
    }
}
