<?php

namespace BitApps\PiPro\src\Integrations\MailMint;

use Mint\MRM\DataBase\Models\ContactGroupModel;
use BitApps\Pi\Deps\BitApps\WPValidator\Validator;
use BitApps\PiPro\Deps\BitApps\WPKit\Http\Response;

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


final class MailMintHelper
{
    /**
     * Fetch all lists from MailMint.
     *
     * @return Response
     */
    public function getLists()
    {
        $classValidationErrors = self::validateClassExistence('ContactGroupModel');

        if ($classValidationErrors) {
            // translators: %s: Class name
            return Response::error(\sprintf(__('MailMint class %s is not available.', 'bit-pi'), 'ContactGroupModel'));
        }

        $lists = ContactGroupModel::get_all_lists_or_tags('lists');


        foreach ($lists as $list) {
            $allList[] = (object) [
                'value' => $list['id'],
                'label' => $list['title'],
            ];
        }

        return Response::success($allList);
    }

    /**
     * Fetch all tags from MailMint.
     *
     * @return Response
     */
    public function getTags()
    {
        $classValidationErrors = self::validateClassExistence('ContactGroupModel');

        if ($classValidationErrors) {
            // translators: %s: Class name
            return Response::error(\sprintf(__('MailMint class %s is not available.', 'bit-pi'), 'ContactGroupModel'));
        }

        $tags = ContactGroupModel::get_all_lists_or_tags('tags');


        foreach ($tags as $tag) {
            $allTags[] = (object) [
                'value' => $tag['id'],
                'label' => $tag['title'],
            ];
        }

        return Response::success($allTags);
    }

    /**
     * Check if MailMint is installed.
     *
     * @return bool
     */
    public static function isPluginInstalled()
    {
        return \defined('MAILMINT');
    }

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

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

    /**
     * Validate API functions.
     *
     * @param array|string $apiFunctions
     * @param null|array $payload
     *
     * @return null|array
     */
    public static function validateApiFunctions($apiFunctions, $payload = [])
    {
        if (\is_string($apiFunctions)) {
            $apiFunctions = [$apiFunctions];
        }

        foreach ($apiFunctions as $function) {
            if (!\function_exists($function)) {
                return [
                    // translators: %s: Function name
                    'response'    => \sprintf(__('MailMint API function %s is not available.', 'bit-pi'), $function),
                    'payload'     => $payload,
                    'status_code' => 400
                ];
            }
        }
    }

    /**
     * Validate class existence.
     *
     * @param array|string $classNames
     * @param null|array $payload
     *
     * @return null|array
     */
    public static function validateClassExistence($classNames, $payload = [])
    {
        if (\is_string($classNames)) {
            $classNames = [$classNames];
        }

        $classPaths = [
            'ContactGroupPivotModel' => 'Mint\MRM\DataBase\Models\ContactGroupPivotModel',
            'ContactGroupModel'      => 'Mint\MRM\DataBase\Models\ContactGroupModel',
            'ContactModel'           => 'Mint\MRM\DataBase\Models\ContactModel',
            'CampaignModel'          => 'Mint\MRM\DataBase\Models\CampaignModel',
            'NoteModel'              => 'Mint\MRM\DataBase\Models\NoteModel',
            'ListData'               => 'Mint\MRM\DataStores\ListData',
            'TagData'                => 'Mint\MRM\DataStores\TagData',
            'ContactData'            => 'Mint\MRM\DataStores\ContactData',
        ];

        foreach ($classNames as $class) {
            if (!class_exists($classPaths[$class])) {
                return [
                    // translators: %s: Class name
                    'response'    => \sprintf(__('MailMint class %s is not available.', 'bit-pi'), $class),
                    'payload'     => $payload,
                    'status_code' => 400
                ];
            }
        }
    }

    public static function setListsToContact($contactId, $lists)
    {
        if (empty($lists)) {
            return;
        }

        $lists = array_map(
            function ($listId) {
                $list = ContactGroupModel::get($listId);

                return ContactGroupModel::get_or_insert_contact_group_by_title($list['title'], 'lists');
            },
            $lists
        );

        return ContactGroupModel::set_lists_to_contact($lists, $contactId);
    }

    public static function setTagsToContact($contactId, $tags)
    {
        if (empty($tags)) {
            return;
        }

        $tags = array_map(
            function ($tagId) {
                $tag = ContactGroupModel::get($tagId);

                return ContactGroupModel::get_or_insert_contact_group_by_title($tag['title'], 'tags');
            },
            $tags
        );

        return ContactGroupModel::set_tags_to_contact($tags, $contactId);
    }
}
