<?php

namespace BitApps\PiPro\src\Integrations\WishlistMember;

use BitApps\Pi\src\Flow\NodeInfoProvider;

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


final class WishlistMemberServices
{
    private $nodeInfoProvider;

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

    /**
     * Create level.
     *
     * @return collection
     */
    public function createLevel()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'name' => ['required', 'sanitize:text']
        ];

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            'wlmapi_create_level',
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        $response = wlmapi_create_level($fieldMappings);

        if (isset($response['ERROR'])) {
            return [
                'response'    => $response['ERROR'],
                'payload'     => $fieldMappings,
                'status_code' => 404
            ];
        }

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

    /**
     * Update Level.
     *
     * @return collection
     */
    public function updateLevel()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'level_id' => ['required', 'integer'],
            'name'     => ['required', 'sanitize:text']
        ];

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            'wlmapi_update_level',
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        $response = wlmapi_update_level(
            $fieldMappings['level_id'],
            $fieldMappings
        );

        if (isset($response['ERROR'])) {
            return [
                'response'    => $response['ERROR'],
                'payload'     => $fieldMappings,
                'status_code' => 404
            ];
        }

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

    /**
     * Get Levels.
     *
     * @return collection
     */
    public function getAllLevel()
    {
        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions('wlmapi_get_levels');

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        return [
            'response'    => wlmapi_get_levels(),
            'payload'     => [],
            'status_code' => 200
        ];
    }

    /**
     * Get Level by ID.
     *
     * @return collection
     */
    public function getLevelById()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

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

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            'wlmapi_get_level',
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        $levelData = wlmapi_get_level($fieldMappings['id']);

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

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

    /**
     * Delete Level.
     *
     * @return collection
     */
    public function deleteLevel()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

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

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            'wlmapi_delete_level',
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        $response = wlmapi_delete_level($fieldMappings['id']);

        if (isset($response['ERROR'])) {
            return [
                'response'    => $response['ERROR'],
                'payload'     => $fieldMappings,
                'status_code' => 404
            ];
        }

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

    /**
     * Create Member.
     *
     * @return collection
     */
    public function createMember()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();
        $generatePassword = $this->nodeInfoProvider->getFieldMapConfigs('generatePassword.value') ?? false;

        $rules = [
            'user_login' => ['required', 'sanitize:text'],
            'user_email' => ['required', 'sanitize:email'],
            'levels'     => ['required', 'integer']
        ];

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            'wlmapi_add_member',
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        $fieldMappings['user_pass'] = $generatePassword ? wp_generate_password() : $fieldMappings['user_pass'] ?? '';

        $response = wlmapi_add_member(
            array_merge(
                $fieldMappings,
                [
                    'ObeyRegistrationRequirements' => false,
                    'SendMail'                     => true,
                    'SendMailPerLevel'             => true,
                ]
            )
        );

        if (isset($response['ERROR'])) {
            return [
                'response'    => $response['ERROR'],
                'payload'     => $fieldMappings,
                'status_code' => 404
            ];
        }

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

    /**
     * Update Member.
     *
     * @return collection
     */
    public function updateMember()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

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

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            'wlmapi_update_member',
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        $response = wlmapi_update_member(
            $fieldMappings['member_id'],
            $fieldMappings
        );

        if (isset($response['ERROR'])) {
            return [
                'response'    => $response['ERROR'],
                'payload'     => $fieldMappings,
                'status_code' => 404
            ];
        }

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

    /**
     * Get Members.
     *
     * @return collection
     */
    public function getAllMember()
    {
        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions('wlmapi_get_members');

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        return [
            'response'    => wlmapi_get_members(),
            'payload'     => [],
            'status_code' => 200
        ];
    }

    /**
     * Get Member by ID.
     *
     * @return collection
     */
    public function getMemberById()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

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

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            'wlmapi_get_member',
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        $memberData = wlmapi_get_member($fieldMappings['id']);

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

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

    /**
     * Get Member by email.
     *
     * @return collection
     */
    public function getMemberByEmail()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'email' => ['required', 'sanitize:email']
        ];

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            'wlmapi_get_member_by',
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        $memberData = wlmapi_get_member_by('user_email', $fieldMappings['email']);

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

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

    /**
     * Get Member by username.
     *
     * @return collection
     */
    public function getMemberByUsername()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'username' => ['required', 'sanitize:text']
        ];

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            'wlmapi_get_member_by',
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        $memberData = wlmapi_get_member_by('user_login', $fieldMappings['username']);

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

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

    /**
     * Get Member Levels.
     *
     * @return collection
     */
    public function getMemberLevels()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

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

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            'wlmapi_get_member_levels',
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        $levels = wlmapi_get_member_levels($fieldMappings['id']);

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

    /**
     * Delete Member.
     *
     * @return collection
     */
    public function deleteMember()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

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

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            'wlmapi_delete_member',
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        $response = wlmapi_delete_member($fieldMappings['id']);

        if (isset($response['ERROR'])) {
            return [
                'response'    => $response['ERROR'],
                'payload'     => $fieldMappings,
                'status_code' => 404
            ];
        }

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

    /**
     * Check User is Member of Level.
     *
     * @return collection
     */
    public function checkUserIsMemberOfLevel()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'member_id' => ['required', 'integer'],
            'level_id'  => ['required', 'integer']
        ];

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            ['wlmapi_is_user_a_member', 'wlmapi_get_level'],
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

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

        $level = wlmapi_get_level($fieldMappings['level_id']);

        if (isset($level['ERROR'])) {
            return [
                'response'    => $level['ERROR'],
                'payload'     => $fieldMappings,
                'status_code' => 404
            ];
        }

        $response = wlmapi_is_user_a_member($fieldMappings['level_id'], $fieldMappings['member_id']);
        if (empty($response)) {
            return [
                'response'    => __('User is not a member.', 'bit-pi'),
                'payload'     => $fieldMappings,
                'status_code' => 404
            ];
        }

        return [
            'response'    => __('User is a member.', 'bit-pi'),
            'payload'     => $fieldMappings,
            'status_code' => 200
        ];
    }

    /**
     * Add Member to Level.
     *
     * @return collection
     */
    public function addMemberToLevel()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'member_id' => ['required', 'integer'],
            'level_id'  => ['required', 'integer']
        ];

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            'wlmapi_add_member_to_level',
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        $response = wlmapi_add_member_to_level(
            $fieldMappings['level_id'],
            [
                'Users'                        => [$fieldMappings['member_id']],
                'ObeyLevelsAdditionalSettings' => false,
                'SendMail'                     => true,
                'SendMailPerLevel'             => true,
            ]
        );

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

    /**
     * Remove Member from Level.
     *
     * @return collection
     */
    public function removeMemberFromLevel()
    {
        $fieldMappings = $this->nodeInfoProvider->getFieldMapData();

        $rules = [
            'member_id' => ['required', 'integer'],
            'level_id'  => ['required', 'integer']
        ];

        $validationErrors = WishlistMemberHelper::validateFieldMap($fieldMappings, $rules);

        if ($validationErrors) {
            return $validationErrors;
        }

        $apiValidationErrors = WishlistMemberHelper::validateApiFunctions(
            'wlmapi_remove_member_from_level',
            $fieldMappings
        );

        if ($apiValidationErrors) {
            return $apiValidationErrors;
        }

        $response = wlmapi_remove_member_from_level(
            $fieldMappings['level_id'],
            $fieldMappings['member_id']
        );

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