<?php

namespace BitApps\PiPro\src\Integrations\Poptics;

use BitApps\Pi\src\Flow\NodeInfoProvider;
use BitApps\PiPro\Deps\BitApps\WPValidator\Validator;
use Poptics\Core\Campaign\Campaign;
use Poptics\Core\Submissions\Submission;

if (!\defined('ABSPATH')) {
    exit;
}

final class PopticsService
{
    private $nodeInfoProvider;

    public function __construct(NodeInfoProvider $nodeInfoProvider)
    {
        $this->nodeInfoProvider = $nodeInfoProvider;
    }

    /**
     * Delete campaign by ID.
     *
     * @return array
     */
    public function deleteCampaign()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = ['campaign_id' => ['required', 'integer']];

        if ($validationErrors = self::validateFieldMap($fieldMappings, $rules)) {
            return $validationErrors;
        }

        if ($error = self::validateClassExistence('campaign')) {
            return $error;
        }

        $campaign = new Campaign((int) $fieldMappings['campaign_id']);

        if (empty($campaign->delete())) {
            return [
                'response'    => __('Campaign not found or could not be deleted.', 'bit-pi'),
                'payload'     => $fieldMappings,
                'status_code' => 404
            ];
        }

        return [
            'response'    => __('Campaign deleted successfully.', 'bit-pi'),
            'payload'     => $fieldMappings,
            'status_code' => 200
        ];
    }

    /**
     * Get campaign by ID.
     *
     * @return array
     */
    public function getCampaignById()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = ['campaign_id' => ['required', 'integer']];

        if ($validationErrors = self::validateFieldMap($fieldMappings, $rules)) {
            return $validationErrors;
        }

        if ($error = self::validateClassExistence('campaign')) {
            return $error;
        }

        $campaign = new Campaign((int) $fieldMappings['campaign_id']);

        $campaignData = $campaign->get_data();

        if (empty($campaignData)) {
            return [
                'response'    => __('Campaign not found.', 'bit-pi'),
                'payload'     => $fieldMappings,
                'status_code' => 404
            ];
        }

        return [
            'response'    => $campaignData,
            'payload'     => $fieldMappings,
            'status_code' => 200
        ];
    }

    /**
     * Get all campaigns.
     *
     * @return array
     */
    public function getCampaigns()
    {
        if ($error = self::validateClassExistence('campaign')) {
            return $error;
        }

        $allCampaigns = Campaign::all();

        $allCampaigns['items'] = array_map(
            function ($campaign) {
                $campaignObj = new Campaign($campaign->ID);

                return array_merge(
                    ['id' => $campaign->ID],
                    $campaignObj->get_data()
                );
            },
            $allCampaigns['items'] ?? []
        );

        return [
            'response'    => $allCampaigns,
            'payload'     => [],
            'status_code' => 200
        ];
    }

    /**
     * Get all submissions.
     *
     * @return array
     */
    public function getSubmissions()
    {
        if ($error = self::validateClassExistence('submission')) {
            return $error;
        }

        $submission = new Submission();

        return [
            'response'    => $submission->get_all_submissions(),
            'payload'     => [],
            'status_code' => 200
        ];
    }

    /**
     * Get submissions by campaign ID.
     *
     * @return array
     */
    public function getSubmissionsByCampaignId()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = ['campaign_id' => ['required', 'integer']];

        if ($validationErrors = self::validateFieldMap($fieldMappings, $rules)) {
            return $validationErrors;
        }

        if ($error = self::validateClassExistence('submission')) {
            return $error;
        }

        $submission = new Submission($fieldMappings);

        return [
            'response'    => $submission->get_all_submissions(),
            'payload'     => $fieldMappings,
            'status_code' => 200
        ];
    }

    /**
     * Validate field map.
     *
     * @param array $fieldMappings
     * @param array $validationRules
     *
     * @return null|array
     */
    private static function validateFieldMap($fieldMappings, $validationRules)
    {
        $validator = new Validator();
        $validation = $validator->make($fieldMappings, $validationRules);

        if ($validation->fails()) {
            return [
                'response'    => $validation->errors(),
                'payload'     => $fieldMappings,
                'status_code' => 400
            ];
        }
    }

    /**
     * Validate class existence.
     *
     * @param string $class
     *
     * @return null|array
     */
    private static function validateClassExistence($class)
    {
        $classes = [
            'campaign'   => 'Poptics\Core\Campaign\Campaign',
            'submission' => 'Poptics\Core\Submissions\Submission'
        ];

        if (!class_exists($classes[$class])) {
            return [
                'response'    => __('Poptics plugin is not active.', 'bit-pi'),
                'payload'     => [],
                'status_code' => 400
            ];
        }
    }
}
