<?php

/*
 * This file is part of the AuthStack project.
 *
 * (c) Buckhill Ltd <development@buckhill.co.uk>
 *
 * This source file is subject to the Buckhill license that is bundled
 * with this source code in the file LICENSE.
 *
 */

namespace AuthStack\AuthProfile\Services;

use AuthStack\AuthProfile\Errors\NoActiveProfileError;
use AuthStack\AuthProfile\Model\AuthProfile;
use Illuminate\Support\Collection;

class ProfileManager
{
    protected $collection;
    protected $active_profile;

    /**
     * ProfileManager constructor.
     */
    public function __construct()
    {
        $this->collection = collect();
    }

    /**
     * @param array|null $data
     * @param            $active_profile
     *
     * @return mixed
     */
    public static function fromArray(array $data = null, $active_profile)
    {
        $me = new static;

        return $me
            ->setCollection(collect(is_null($data) || empty($data) ? [] : $data))
            ->setActiveProfile($active_profile)
            ;
    }

    /**
     * @return $this
     */
    public function clear()
    {
        $this->collection = collect([]);
        $this->active_profile = null;

        return $this;
    }

    /**
     * @param Collection $collection
     *
     * @return ProfileManager
     */
    public function setCollection(Collection $collection)
    {
        $this->collection = $collection;

        return $this;
    }

    /**
     * @param AuthProfile $profile
     *
     * @return AuthProfile
     */
    public function add(AuthProfile $profile)
    {
        $has = $this->getCollection()->where('user_id', $profile->getUserId());

        if(!$has->count())
        {
            $this->getCollection()->push($profile->toArray());

            return $profile;
        }

        return AuthProfile::fromArray($has->first());
    }

    /**
     * @return Collection
     */
    public function getCollection()
    {
        return $this->collection;
    }

    /**
     * @return bool
     */
    public function isAuthenticated()
    {
        // If there's at least 1 profile in collection, user is authenticated
        return (0 !== $this->getCollection()->count()) && $this->hasActiveProfile();
    }

    /**
     * @return bool
     */
    public function hasActiveProfile()
    {
        $result = false;

        try
        {
            $active = $this->getActiveProfile();

            $result = true;
        }
        catch(\Exception $e)
        {
        }

        return $result;
    }

    /**
     * @return array
     */
    public function toArray()
    {
        if(!$this->getCollection()->count()) return [];
        return [
            'active' => $this->getActiveProfileId(),
            'profiles' => $this->getCollection()->all()
        ];
    }

    /**
     * @param string $session_id
     *
     * @return ProfileManager
     */
    public function setActiveProfile($session_id = '')
    {
        $this->active_profile = $session_id;

        return $this;
    }

    public function setActiveProfileIfExists($session_id = '')
    {
        $exists = $this->getCollection()->where('session_id', $session_id);

        if(!$exists->count())
        {
            return false;
        }

        return $this->setActiveProfile($session_id);
    }

    /**
     * @return string
     */
    public function getActiveProfileId()
    {
        return $this->active_profile;
    }

    /**
     * @throws NoActiveProfileError
     * @return AuthProfile
     */
    public function getActiveProfile()
    {
        $result = $this->getCollection()->where('session_id', $this->active_profile);

        if(!$result->count())
        {
            throw new NoActiveProfileError("The profile collection did not contain an active profile specified in the session.");
        }

        return AuthProfile::fromArray($result->first());
    }
}