<?php

namespace GriffinForms\Includes\Pipelines\Handlers;

use GriffinForms\Includes\Integrations\Mailchimp\Contract;
use GriffinForms\Includes\Integrations\Mailchimp\IdentityStore;
use GriffinForms\Includes\Integrations\Mailchimp\Main;
use GriffinForms\Includes\Integrations\Mailchimp\SyncStateStore;
use GriffinForms\Includes\Pipelines\JobRepository;
use GriffinForms\Includes\Pipelines\PostSubmissionHandlerInterface;
use GriffinForms\Log;

class MailchimpSyncHandler implements PostSubmissionHandlerInterface
{
    protected $repository;
    protected $identity_store;
    protected $state_store;
    protected $log;

    public function __construct()
    {
        $this->repository = JobRepository::getInstance();
        $this->identity_store = new IdentityStore();
        $this->state_store = new SyncStateStore();
        $this->log = Log::getInstance();
    }

    public function getId(): string
    {
        return Contract::INTEGRATION_ID;
    }

    public function getPriority(): int
    {
        return 85;
    }

    public function supports(array $context): bool
    {
        $submission_id = isset($context['submission_id']) ? (int) $context['submission_id'] : 0;
        $form_id = isset($context['form_id']) ? (int) $context['form_id'] : 0;
        if ($submission_id <= 0 || $form_id <= 0) {
            return false;
        }

        $integration = new Main();
        if (!$integration->isConfigured()) {
            return false;
        }

        $effective = $integration->getEffectiveFormSettings($form_id);
        if (($effective['mode'] ?? '') === 'disabled') {
            return false;
        }

        return !empty($effective['audience_id']) && !empty($effective['subscriber_email_field']);
    }

    public function handle(array $context): void
    {
        $submission_id = isset($context['submission_id']) ? (int) $context['submission_id'] : 0;
        $form_id = isset($context['form_id']) ? (int) $context['form_id'] : 0;
        if ($submission_id <= 0 || $form_id <= 0) {
            return;
        }

        $integration = new Main();
        $effective = $integration->getEffectiveFormSettings($form_id);
        $audience_id = sanitize_text_field((string) ($effective['audience_id'] ?? ''));
        $subscription_status = sanitize_key((string) ($effective['subscription_status'] ?? 'subscribed'));
        $author_user_id = isset($context['submission_meta']['author']) ? (int) $context['submission_meta']['author'] : 0;
        $owner_context = $this->identity_store->buildOwnerContext($submission_id, $form_id, $author_user_id);
        if ($subscription_status !== 'pending') {
            $subscription_status = 'subscribed';
        }

        $job_id = $this->repository->enqueue(
            Contract::JOB_TYPE_SYNC,
            Contract::INTEGRATION_ID,
            $submission_id,
            $form_id,
            [
                'trigger' => 'submission_created',
            ],
            15
        );

        if ($job_id <= 0) {
            $this->state_store->saveState($submission_id, [
                'schema_version' => Contract::IDENTITY_SCHEMA_VERSION,
                'enabled' => true,
                'status' => Contract::STATUS_FAILED,
                'audience_id' => $audience_id,
                'subscription_status' => $subscription_status,
                'email_field_id' => (string) ($effective['subscriber_email_field'] ?? ''),
                'consent_field_id' => (string) ($effective['consent_field_id'] ?? ''),
                'consent_required' => !empty($effective['consent_field_id']),
                'owner' => $owner_context,
                'storage_strategy' => [
                    'canonical' => 'submission_meta',
                    'user_indexed' => $author_user_id > 0,
                    'dedicated_record' => false,
                ],
                'tags' => is_array($effective['static_tags'] ?? null) ? array_values($effective['static_tags']) : [],
                'last_error' => 'Mailchimp job could not be enqueued.',
            ]);

            $this->log->add(
                'error',
                'submission',
                $submission_id,
                get_current_user_id(),
                sprintf('Mailchimp sync job could not be queued for audience %s.', $audience_id !== '' ? $audience_id : 'unknown'),
                Contract::LOG_CATEGORY
            );
            return;
        }

        $this->state_store->saveState($submission_id, [
            'schema_version' => Contract::IDENTITY_SCHEMA_VERSION,
            'enabled' => true,
            'status' => Contract::STATUS_QUEUED,
            'job_id' => $job_id,
            'audience_id' => $audience_id,
            'subscription_status' => $subscription_status,
            'email_field_id' => (string) ($effective['subscriber_email_field'] ?? ''),
            'first_name_field_id' => (string) ($effective['first_name_field'] ?? ''),
            'last_name_field_id' => (string) ($effective['last_name_field'] ?? ''),
            'consent_field_id' => (string) ($effective['consent_field_id'] ?? ''),
            'consent_required' => !empty($effective['consent_field_id']),
            'owner' => $owner_context,
            'storage_strategy' => [
                'canonical' => 'submission_meta',
                'user_indexed' => $author_user_id > 0,
                'dedicated_record' => false,
            ],
            'tags' => is_array($effective['static_tags'] ?? null) ? array_values($effective['static_tags']) : [],
            'queued_at' => gmdate('c'),
        ]);

        $this->log->add(
            'info',
            'submission',
            $submission_id,
            get_current_user_id(),
            sprintf('Mailchimp sync job %d queued for audience %s.', $job_id, $audience_id),
            Contract::LOG_CATEGORY
        );
    }
}
