<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use App\Models\UserModel;
use CodeIgniter\Shield\Entities\User;
use CodeIgniter\Exceptions\PageNotFoundException;
use CodeIgniter\Database\Exceptions\DatabaseException;
use App\Models\User_accessModel;
use App\Entities\User_access;

class Users extends BaseController
{
    private UserModel $model;
    private User_accessModel $user_access_model;
    public function __construct()
    {
        $this->model = new UserModel;
        $this->user_access_model = new User_accessModel;
    }
    
    public function index(): string
    {
        
        $data = $this->model->findAll();

        return view("Users/index",[
                "users" => $data
            ]);
    }
 
    public function show($id)
    {

        $user = $this->getUserOr404($id);
        return view("Users/show",[
            "user" => $user
        ]);

    }

    public function new()
    {
        $user = new User;
        $user->username = '';
        $user->pass = '';
        $user->email = '';
       return view("Users/new",["user" => $user]);
    }

    public function create()
    {

        $rules =[
            'username' => [
                'label' => 'Auth.username',
                'rules' => [
                    'required',
                    'max_length[30]',
                    'min_length[3]',
                    'regex_match[/\A[a-zA-Z0-9\.]+\z/]',
                    'is_unique[users.username]',
                ],
            ],
            'email' => [
                'label' => 'Auth.email',
                'rules' => [
                    'required',
                    'max_length[254]',
                    'valid_email',
                    'is_unique[auth_identities.secret]',
                ],
            ],
            "password" => [
                "label" => "Password",
                "rules" => "required|strong_password"
            ],
            "password_confirmation" => [
                "label" => "Password Confirmation",
                "rules" => "required|matches[password]"
            ]
        ];


        if( ! $this->validate($rules)) {
            return redirect()->back()
                            ->with("errors", $this->validator->getErrors())
                            ->withInput();
        }
        $model = new UserModel;

        $user = new User($this->request->getPost());

        $isAdmin = $user->usergroup == 'admin' ? true : false;

        $user->password = $this->request->getPost("password");

        $model = new UserModel;
        $model->save($user);

        $user = $model->findById(($model->getInsertID()));

        $user->activate();

        if($isAdmin) {
            $user->addGroup("user", "admin");
        }else{
            $user->addGroup("user");
        }

        session()->removeTempdata("magicLogin");
    
        return redirect()->to("users")->with("message","User saved.");
    }

    public function edit($id)
    {

        $user = $this->getUserOr404($id);

        if($user->inGroup("admin")){
            $user->usergroup = "admin";
        }else{
            $user->usergroup = "user";
        }
        $user_access_levels = $this->getUserAccessLevels($id);

        return view("Users/edit",[
            "user" => $user,
            "user_access_levels" => $user_access_levels,
        ]);

    }


    public function update($id)
    {
        $rules =[
            'username' => [
                'label' => 'Auth.username',
                'rules' => [
                    'required',
                    'max_length[30]',
                    'min_length[3]',
                    'regex_match[/\A[a-zA-Z0-9\.]+\z/]',
                    'is_unique[users.username, users.id, '.$id.']',
                ],
            ],
            'email' => [
                'label' => 'Auth.email',
                'rules' => [
                    'required',
                    'max_length[254]',
                    'valid_email',
                    'is_unique[auth_identities.secret, auth_identities.user_id, '.$id .']',
                ],
            ],
        ];
       

        if( ! $this->validate($rules)) {
            return redirect()->back()
                            ->with("errors", $this->validator->getErrors())
                            ->withInput();
        }

        $user = $this->getUserOr404($id);

        $user->fill($this->request->getPost());


        //dd($user);
        $arr = json_decode(json_encode($user), true);
        //$value = $arr['highlighting']['448364']['Data']['0'];
//dd($arr);
        $user_access_levels = $this->getUserAccessLevels($id);
//dd($user_access_levels);

        $arr  = json_decode(json_encode($user), true);
        //dd($user);

        $set = array();
        $erro = array();
        foreach($user_access_levels as $user_access_level){
            $user_access = new User_access;
            $ualid = $user_access_level->ualid;
            if( isset( $arr["uaid_$ualid"]) && !empty($arr["uaid_$ualid"])){
                $uaid = (int)$arr["uaid_$ualid"];
                $user_access->uaid = $uaid;
            }
            // else{
            //     $uaid = 0;
            //     $user_access->uaid = $uaid;
            // }
            if( isset( $arr["can_access_$ualid"]) && $arr["can_access_$ualid"] == "1"){
                $user_access->can_access = 1;
            }else{
                $user_access->can_access = 0;
            }
            if( isset( $arr["can_edit_$ualid"]) && $arr["can_edit_$ualid"] == "1"){
                $user_access->can_edit = 1;
            }else{
                $user_access->can_edit = 0;
            }
            $user_access->uid = (int)$id;
            $user_access->ualid = (int)$ualid;
            $set[] = $user_access;               
            if(!$this->user_access_model->save($user_access)){
                $erro[] = $this->user_access_model->errors();
            }
//            $set[] = ["user_id"=>$id, "ualid" => $ualid];                    
        }

        //dd($set, $erro);

        // $set = array();
        // foreach($arr as $u){
        //     $set[] = $arr["can_access_$u->ualid"];
        //     // if( isset( $arr["can_access_$user_access_level->ualid"]) && $arr["can_access_$user_access_level->ualid"] == "1"){
        //     //     $set[] = ["user_id"=>$id, "ualid" => $user_access_level->ualid];                    
        //     // }
        // }

        $user->__unset("_method");

        if(!$user->hasChanged()){
            return redirect()->back()->with("message","Nothing to update.");
        }

        if( !$this->model->save($user)){
            return redirect()->back()->with("errors",$this->model->errors())->withInput();
        }

        if($user->usergroup == 'admin') {
            $user->addGroup("admin");
        }else{
            $user->removeGroup("admin");
        }
        return redirect()->to("users")->with("message","User updated");

    }

    public function confirmDelete($id)
    {
        $user = $this->getUserOr404($id);

        return view("Users/delete",[
            "user"=>$user
        ]);
    }
    public function delete($id)
    {
        try{

            $this->model->delete($id,true);

        } catch (DatabaseException $e) {
            return redirect()->back()->with("errors",$this->model->errors())->withInput();
        }
        return redirect()->to("users")->with("message","User deleted.");

    }

    private function getUserOr404($id): User
    {
        $user = $this->model->find($id);

        if($user === null){
            throw new PageNotFoundException("User with id $id not found");
        }

        return $user;
    }

    // private function getUser_accessOr404($uid, $ualid): User
    // {
    //     $user = $this->model->getIdValue() getIdValue(([]) find($id);

    //     if($user === null){
    //         throw new PageNotFoundException("User with id $id not found");
    //     }

    //     return $user;
    // }


    private function getUserAccessLevels($uid)
    {
        $sql = "SELECT user_access_levels.ualid, user_access_levels.access_level,
        ua.can_access, ua.can_edit,ua.uaid,
        ifnull(ua.uid,$uid) AS uid
        FROM user_access_levels
        LEFT JOIN 
        (SELECT user_access.uaid, user_access.ualid, ifnull(user_access.uid,$uid) AS uid, user_access.can_access, user_access.can_edit 
        FROM user_access
        WHERE user_access.uid=$uid
        ) ua
        ON user_access_levels.ualid=ua.ualid
        WHERE ua.uid=1 OR IFNULL(ua.uid,$uid)=$uid
        ORDER BY user_access_levels.access_level";

        $data = $this->model->query($sql)->getResult();
        return $data;
    }
}
