<?php

namespace Mtc\Core\Admin;

use Mtc\Core\AdminUser;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use \Illuminate\Database\Eloquent\Model as EloquentModel;
use Mtc\Modules\DoctorPolicy\Classes\DoctorPolicy;
use App\Casts\OptionalEncrypted;

/**
 * Admin\User class.  This looks after the admin_users table
 * using Eloquent base modelling
 *
 * @author william.cameron
 */
class User extends EloquentModel
{
    use HasFactory;

    public $timestamps = false;
    protected $table = "admin_users";
    protected $fillable = ['username', 'password'];

    protected $casts = [
        'email' => OptionalEncrypted::class,
        'name' => OptionalEncrypted::class,
        'username' => OptionalEncrypted::class,
        'credentials' => OptionalEncrypted::class,
        'totp_secret' => OptionalEncrypted::class,
    ];


    /**
     * Save category restrictions for admin user
     *
     * @param int[] $categories list of categories admin user CAN edit
     */
    public function setRestrictedCategories($categories = [])
    {

        // Remove Roles that are no longer needed
        UserAllowedCategories::where('user_id', $this->id)
            ->delete();

        if (empty($categories)) {
            return;
        }
        // Loop through roles and make sure we have all of them set up
        foreach ($categories as $category) {
            UserAllowedCategories::firstOrCreate([
                'user_id' => $this->id,
                'category_id' => $category
            ]);
        }
    }

    /**
     * Relationship to the categories that are allowed for this admin
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function allowedCategories()
    {
        return $this->hasMany(UserAllowedCategories::class, 'user_id');
    }

    /**
     * Confirmed policies for a user
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function confirmedPolicies()
    {
        return $this->belongsToMany(DoctorPolicy::class, 'admin_user_policy_confirmations', 'user_id', 'policy_id')
            ->withPivot([
                'created_at'
            ]);
    }


    public function favouriteLinks()
    {
        return $this->belongsToMany(Menu::class, 'admin_users__favourite_links', 'user_id', 'menuitem_id');
    }


    public function linkedUsers()
    {
        return $this->hasMany(UserLinkedUser::class, 'user_id');
    }


    public function role()
    {
        return $this->belongsTo(Role::class, 'role');
    }

    public static function getAdminUser(?int $adminId=null)
    {
        $adminUser = new AdminUser();
        if (empty($adminUser->user)) {
            // check if its cli request
            if (php_sapi_name() === 'cli') {
                return self::query()
                    ->find(MTCADMIN_USERID);
            }

            static $cachedAdmin;

            if ($cachedAdmin instanceof self) {
                return $cachedAdmin;
            }

            $current = AdminUser::getCurrent();
            if (!$current) {
                return null;
            }

            $cachedAdmin = self::query()
                ->with('allowedCategories')
                ->find($current->id);

            return $cachedAdmin;
        }

        return $adminUser;
    }

    public static function getAllowedCategories()
    {
        $user = self::getAdminUser();
        if (!$user) {
            return collect();
        }

        if (!$user->relationLoaded('allowedCategories')) {
            $user->load('allowedCategories');
        }

        return $user->allowedCategories->pluck('category_id');
    }

    public static function newFactory()
    {
        return \Database\Factories\AdminUserFactory::new();
    }
}
