<?php

namespace App\Services;

use App\Exceptions\InvalidProfileSharingAttempt;
use App\Models\ProfileSharing;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

trait ProfileSharingService
{
    /**
     * Store new record
     *
     * @param array $data
     * @return Builder|Model
     */
    public static function store(array $data): Model|Builder
    {
        return ProfileSharing::query()->create($data);
    }

    /**
     * Update existing record
     *
     * @param array $data
     * @return mixed
     */
    public function updateService(array $data): mixed
    {
        return tap($this)->update($data);
    }

    /**
     * Shared profiles
     *
     * @param int|null $pageNumber
     * @return array
     */
    public static function profileSharing(int $pageNumber = null): array
    {
        /** @var User $user */
        $user = auth()->user();

        $queryBuilder = ProfileSharing::query()
            ->with('sharedUserProfile')
            ->where('recipient_user_id', $user->{"id"})
            ->orderByDesc("created_at");

        $sharedUserProfilesPaginator = $queryBuilder->paginate(
            perPage: config("torryme.constants.items_per_page"),
            page: $pageNumber
        );

        $sharedUserProfilesArray = array();
        foreach ($sharedUserProfilesPaginator as $sharedUserProfile) {
            $sharedUserProfilesArray[] = $sharedUserProfile->{"sharedUserProfile"};
        }

        return default_paginator_format(
            $sharedUserProfilesPaginator->lastPage(),
            $sharedUserProfilesPaginator->total(),
            $sharedUserProfilesPaginator->currentPage(),
            "shared_profiles",
            $sharedUserProfilesArray,
        );
    }

    /**
     * Check if profile has already been shared
     *
     * @param int $recipientUserId
     * @return bool
     */
    public static function alreadyShared(int $recipientUserId): bool
    {
        /** @var User $user */
        $user = auth()->user();

        return ProfileSharing::query()
            ->where("sharer_user_id", $user->{"id"})
            ->where("shared_user_id", $user->{"id"})
            ->where("recipient_user_id", $recipientUserId)->exists();
    }

    /**
     * Share profile
     *
     * @param int $recipientUserId
     * @return void
     * @throws \Exception
     */
    public static function addProfileSharing(int $recipientUserId): void
    {
        try {
            /** @var User $user */
            $user = auth()->user();

            if($user->{"id"} == $recipientUserId) {
                throw new InvalidProfileSharingAttempt(__("errors.invalid_profile_sharing_attempt"));
            }

            if (self::alreadyShared($recipientUserId)) {
                ProfileSharing::store([
                    "sharer_user_id" => $user->{"id"},
                    "shared_user_id" => $user->{"id"},
                    "recipient_user_id" => $recipientUserId
                ]);
            }
        } catch (\Exception $exception) {
            log_debug(exception: $exception, prefix: 'ProfileSharingService::addProfileSharing');
            throw $exception;
        }
    }
}
