<?php

namespace App\Services;

use Illuminate\Http\UploadedFile;
use Intervention\Image\ImageManager;
use DB;
use Str;
use Storage;
use App\Models\User\User;
use App\Models\User\UserOnboardRole;
use RuntimeException;

/**
 * Provides User entity business logic (creation, update, etc)
 */
class UserService
{
    protected $accountService = null;

    public function __construct(AccountService $accountService)
    {
        $this->accountService = $accountService;
    }

    /**
     * loginSuccess marks users last login timestamp
     *
     * @param  mixed $user
     * @return void
     */
    public function loginSuccess(User $user)
    {
        $user->last_login_date = now('UTC');
        $user->save();
    }

    public function createUser($userData)
    {
        DB::beginTransaction();
        try {
            $user = new User();
            $user->uid = Str::random(config('app.uid_length'));
            $user->email = $userData['email'];
            $user->name = $userData['fullName'];

            $nameParts = preg_split('/\s+/', $user->name);
            $user->first_name = $nameParts[0];
            $user->last_name = $nameParts[sizeof($nameParts) - 1];

            // Password might be empty (social signup)
            if (isset($userData['password'])) {
                $user->password = app('hash')->make($userData['password']);
            }
            $user->last_login_date = now('UTC');
            // $user->profile_completeness = 1;
            $user->state = User::STATE_ACTIVE;

            // $user->linkedin_id = isset($userData['linkedin_id']) ? $userData['linkedin_id'] : null;

            $user->save();
            if ($user->password) {
                //Email signup, user has to verify email
                // $this->sendConfirmEmail($user);
            } else {
                //Social Signup: email is auto verified
                $user->email_verified_at = now('UTC');
                // $this->sendWelcomeEmail($user);
                $user->save();
            }

            $this->accountService->createAccount($user);

            // event(new \App\Events\UserSignup($user, $claimSuccess));
            DB::commit();
        } catch (Throwable $e) {
            DB::rollBack();
            throw $e;
        } catch (Exception $e) {
            DB::rollBack();
            throw $e;
        }

        return $user;
    }

    /**
     * updateUserOnboardRole
     *
     * @param  User $user
     * @param  int $userOnboardRoleId
     * @return boolean success
     */
    public function updateUserOnboardRole(User $user, int $userOnboardRoleId)
    {
        $onboardRole = UserOnboardRole::find($userOnboardRoleId);
        if (!$onboardRole) {
            throw new RuntimeException('User onboard role not found.');
        }
        $user->userOnboardRole()->associate($onboardRole);
        $user->save();
        return true;
    }

    /**
     * updateUserOnboardUsages
     *
     * @param  mixed $user
     * @param  array $userOnboardUsagesIds int array with the ids
     * @return boolean success
     */
    public function updateUserOnboardUsages(User $user, array $userOnboardUsagesIds)
    {
        $user->userOnboardUsages()->sync($userOnboardUsagesIds);
        return true;
    }

    /**
     * updateAvatar
     *
     * @param  User $user
     * @param  UploadedFile $newAvatar
     * @return void
     */
    public function updateAvatar(User $user, UploadedFile $newAvatar)
    {
        // Generates random filename (avoids cache problems)
        $fileExtension = $newAvatar->getClientOriginalExtension();
        $baseFilename = Str::random(config('app.uid_length'));
        $imageFilename = "{$baseFilename}.$fileExtension";

        // Stores original file to s3
        $originalPath = Storage::disk('s3')->putFileAs("users/{$user->uid}/profile-image", $newAvatar, $imageFilename,'public');

        // Generates and stores stadard thumbnail
        $manager = new ImageManager();
        $thumbSize = config('options.avatar.thumbnail_size');
        $thumbFilename = "{$baseFilename}_thumb.$fileExtension";
        $processedImage = $manager->make($newAvatar);
        $processedImage->fit($thumbSize['width'], $thumbSize['height']);
        $processedImage->save();
        Storage::disk('s3')->putFileAs("users/{$user->uid}/profile-image", $newAvatar, $thumbFilename,'public');

        $this->deleteAvatar($user);

        // updates user entity
        $user->avatar = $originalPath;
        $user->save();
    }

    /**
     * deleteAvatar
     *
     * @param  User $user
     * @return void
     */
    public function deleteAvatar(User $user)
    {
        // Deletes, if exists, old profile image
        if (!empty($user->avatar) && Storage::disk('s3')->exists($user->avatar)) {
            $splitName = explode('.', $user->avatar);
            $extension = array_pop($splitName);
            $thumbKey= implode('.', $splitName) . '_thumb.' . $extension;
            Storage::disk('s3')->delete($user->avatar);
            if (Storage::disk('s3')->exists($thumbKey)) {
                Storage::disk('s3')->delete($thumbKey);
            }
        }
        $user->avatar = null;
        $user->save();
    }

    public function updateUser(User $user, array $data)
    {
        $user->first_name = $data['firstName'];
        $user->last_name = $data['lastName'];
        $user->short_bio = $data['shortBio'];
        $user->location = $data['location'];

        $user->save();
    }

    public function updateEmail(User $user, $newEmail)
    {
        $user->email = $newEmail;
        $user->save();
    }

    public function updatePassword(User $user, $newPassword)
    {
        $user->password = app('hash')->make($newPassword);
        $user->save();
    }
}
