<?php

namespace Modules\User\Http\Controllers;

use Catch\Base\CatchController as Controller;
use Catch\Support\Module\ModuleRepository;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Modules\User\Models\LogLogin;
use Modules\User\Models\LogOperate;
use Modules\User\Models\User;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class UserController extends Controller
{
    public function __construct(
        protected readonly User $user
    ) {
    }

    /**
     * get list
     *
     * @return mixed
     */
    public function index()
    {
        return $this->user->getList();
    }

    /**
     * store
     *
     * @param Request $request
     * @return false|mixed
     */
    public function store(Request $request)
    {
        $key =  $this->user->storeBy($request->all());
        if($key) {
            $user = $this->user->firstBy($key);
            if ($user->roles->pluck('identify')->contains('cp') &&
                $request->input('cp_name') ) {
                DB::table('user_belong_to_cp')
                    ->updateOrInsert([
                        'user_id' => $user->id,
                    ],[
                        'cp_name' => $request->input('cp_name'),
                        'is_enabled' => 1
                    ]);
            }
        }

        return $key;
    }

    /**
     * show
     *
     * @param $id
     * @return mixed
     */
    public function show($id)
    {
        $user = $this->user->firstBy($id)->makeHidden('password');
        if (app(ModuleRepository::class)->enabled('permissions')) {
            $user->setRelations([
                'roles' => $user->roles->pluck('id'),
                'jobs' => $user->jobs->pluck('id'),
                'role_identifies' => $user->roles->pluck('identify'),
            ]);
            if($user->role_identifies->contains('cp')) {
                $user->cp_name = DB::table('user_belong_to_cp')
                    ->where(['is_enabled' => 1, 'user_id' => $user->id])
                    ->value('cp_name');
            } else {
                $user->cp_name = null;
            }
        }

        return $user;
    }

    /**
     * update
     *
     * @param $id
     * @param Request $request
     * @return mixed
     */
    public function update($id, Request $request)
    {
        $res =  $this->user->updateBy($id, $request->all());
        $user = $this->user->firstBy($id);
        if ($user->roles->pluck('identify')->contains('cp') &&
            $request->input('cp_name') ) {
            DB::table('user_belong_to_cp')
                ->updateOrInsert([
                    'user_id' => $user->id,
                ],[
                    'cp_name' => $request->input('cp_name'),
                    'is_enabled' => 1
                ]);
        }
        return $res;
    }

    /**
     * destroy
     *
     * @param $id
     * @return bool|null
     */
    public function destroy($id)
    {
        if ($this->user->deleteBy($id)) {
            // 撤销用户的所有令牌
            $this->user->tokens()->delete();
        }

        return true;
    }

    /**
     * enable
     *
     * @param $id
     * @return bool
     */
    public function enable($id)
    {
        return $this->user->toggleBy($id);
    }

    /**
     *  online user
     *
     * @return Authenticatable
     */
    public function online(Request $request)
    {
        /* @var User $user */
        $user = $this->getLoginUser()->withPermissions();
        $showApp = $request->get('app');
        $user->showPermissions($showApp);

        if ($request->isMethod('post')) {
            return $user->updateBy($user->id, $request->all());
        }
        unset($user->password);
        return $user;
    }


    /**
     * login log
     * @param LogLogin $logLogin
     * @return LengthAwarePaginator
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function loginLog(LogLogin $logLogin)
    {
        $user = $this->getLoginUser();

        return $logLogin->getUserLogBy($user->isSuperAdmin() ? null : $user->email);
    }

    public function operateLog(LogOperate $logOperate, Request $request)
    {
        $scope = $request->get('scope', 'self');

        return $logOperate->setBeforeGetList(function ($builder) use ($scope){
            if ($scope == 'self') {
                return $builder->where('creator_id', $this->getLoginUserId());
            }
            return $builder;
        })->getList();
    }
}