<?php

namespace BitApps\PiPro\src\Integrations\BuddyBoss;

use BitApps\Pi\Helpers\Utility;
use BitApps\Pi\Services\FlowService;
use BitApps\PiPro\src\Integrations\IntegrationHelper;

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

final class BuddyBossTrigger
{
    public static function userCreatesGroup($groupId)
    {
        if (!\function_exists('groups_get_group')) {
            return;
        }

        $group = groups_get_group($groupId);
        $data = (array) Utility::jsonEncodeDecode($group);

        if (\function_exists('bp_groups_get_group_type')) {
            $data['type'] = bp_groups_get_group_type($groupId, false);
        }

        if (\function_exists('bp_get_group_cover_url')) {
            $data['cover_url'] = bp_get_group_cover_url($group);
        }

        if (\function_exists('bp_get_group_avatar_url')) {
            $data['avatar_url'] = bp_get_group_avatar_url($group);
        }

        if (isset($group->creator_id)) {
            $data['creator_data'] = Utility::getUserInfo($group->creator_id);
        }

        return self::execute(__FUNCTION__, $data);
    }

    public static function userAcceptsFriendshipRequest($id, $initiatorUserId, $friendUserId, $friendship)
    {
        self::executeUserFriendshipTrigger(__FUNCTION__, $id, $initiatorUserId, $friendUserId, $friendship);
    }

    public static function userAccountActivated($userId)
    {
        $data = Utility::getUserInfo($userId);

        return self::execute(__FUNCTION__, $data);
    }

    public static function userGainsFollower($follow)
    {
        if (!\is_object($follow) || !property_exists($follow, 'follower_id') || !property_exists($follow, 'leader_id')) {
            return;
        }

        $data = (array) Utility::jsonEncodeDecode($follow);
        $data['follower'] = Utility::getUserInfo($follow->follower_id);
        $data['leader'] = Utility::getUserInfo($follow->leader_id);

        return self::execute(__FUNCTION__, $data);
    }

    public static function userJoinsPublicGroup($groupId, $userId)
    {
        self::executeUserGroupTrigger(__FUNCTION__, $groupId, $userId, 'public');
    }

    public static function userJoinsPrivateGroup($groupId, $userId)
    {
        self::executeUserGroupTrigger(__FUNCTION__, $groupId, $userId);
    }

    public static function userJoinsSpecificTypeGroup($groupId, $userId)
    {
        self::executeUserGroupTrigger(__FUNCTION__, $groupId, $userId, null);
    }

    public static function userLeavesGroup($groupId, $userId)
    {
        self::executeUserGroupTrigger(__FUNCTION__, $groupId, $userId, 'public');
    }

    public static function userLeavesPrivateGroup($groupId, $userId)
    {
        self::executeUserGroupTrigger(__FUNCTION__, $groupId, $userId, 'private');
    }

    public static function userProfileTypeSetToSpecificType($userId, $memberType, $append)
    {
        $data = Utility::getUserInfo($userId);
        $data['member_type'] = $memberType;
        $data['append'] = $append;

        return self::execute(__FUNCTION__, $data);
    }

    public static function userReceivesPrivateMessage($message)
    {
        if (
            !\is_object($message)
            || !property_exists($message, 'id')
            || !property_exists($message, 'sender_id')
            || !property_exists($message, 'recipients')
        ) {
            return;
        }

        $data = [
            'message' => (array) Utility::jsonEncodeDecode($message),
            'sender'  => Utility::getUserInfo($message->sender_id)
        ];

        if (!empty($message->recipients)) {
            foreach ($message->recipients as $recipient) {
                if (empty($recipient->user_id) || $recipient->user_id == $message->sender_id) {
                    continue;
                }

                $data['recipients'][] = Utility::getUserInfo($recipient->user_id);
            }
        }

        return self::execute(__FUNCTION__, $data);
    }

    public static function userRequestsAccessPrivateGroup($userId, $admins, $groupId)
    {
        self::executeUserGroupTrigger(__FUNCTION__, $groupId, $userId, null);
    }

    public static function userSendsFriendshipRequest($friendshipId, $initiatorUserId, $friendUserId)
    {
        self::executeUserFriendshipTrigger(__FUNCTION__, $friendshipId, $initiatorUserId, $friendUserId);
    }

    public static function userUpdatesProfile($userId, $postedFieldIds, $errors, $oldValues, $newValues)
    {
        $data = [
            'user'             => Utility::getUserInfo($userId),
            'posted_field_ids' => $postedFieldIds,
            'errors'           => $errors,
            'old_values'       => $oldValues,
            'new_values'       => $newValues
        ];

        if (\function_exists('xprofile_get_field')) {
            foreach ($postedFieldIds as $fieldId) {
                $field = xprofile_get_field($fieldId);

                if ($field && isset($field->data->value)) {
                    $data['posted_fields'][$field->name] = $field->data->value;
                }
            }
        }

        return self::execute(__FUNCTION__, $data);
    }

    private static function executeUserFriendshipTrigger($machineSlug, $friendshipId, $initiatorUserId, $friendUserId, $friendship = null)
    {
        $data = [
            'friendship_id' => $friendshipId,
            'initiator'     => Utility::getUserInfo($initiatorUserId),
            'friend'        => Utility::getUserInfo($friendUserId)
        ];

        if ($friendship !== null) {
            $data['friendship'] = Utility::jsonEncodeDecode($friendship);
        }

        return self::execute($machineSlug, $data);
    }

    private static function executeUserGroupTrigger($machineSlug, $groupId, $userId, $expectedStatus = null)
    {
        if (!\function_exists('groups_get_group')) {
            return;
        }

        $group = groups_get_group($groupId);
        if ($expectedStatus && (empty($group->status) || $group->status !== $expectedStatus)) {
            return;
        }

        $data = [
            'user'  => Utility::getUserInfo($userId),
            'group' => (array) Utility::jsonEncodeDecode($group)
        ];

        if (empty($data['group']['type']) && \function_exists('bp_groups_get_group_type')) {
            $data['group']['type'] = bp_groups_get_group_type($groupId, false);
        }

        return self::execute($machineSlug, $data);
    }

    private static function execute($machineSlug, $data)
    {
        $flows = FlowService::exists('buddyBoss', $machineSlug);

        if (!$flows) {
            return;
        }

        IntegrationHelper::handleFlowForForm($flows, $data);
    }
}
