<?php
require_once("class.db.php");
require_once("class.company.php");
require_once("class.setting.php");
// Error reporting
error_reporting(E_ALL);
ini_set('display_errors', 1);
///////////////////////////////
class SaaS
{

    private $restapi;
    public $company;
    private $conn;
    public $settings;


    public function __construct($restapi = null, $db_name = null)
    {
        $this->restapi = $restapi;
        $this->company = new COMPANY($restapi);
        $this->settings = new Setting($restapi);
        /////////////////////////////////////////
        if (!$this->restapi->dbutils->isDBInService()) {
            die($this->restapi->Response(["message" => "Failed to connect to the database, please try again laiter", "success" => false], 500));
        }
        $db = new APIDB($db_name);
        $this->conn = $db->dbConnection();
    }

    public function getAllCountries()
    {
        $results = [];
        $stmt = $this->restapi->dbutils->runQuery("SELECT * FROM pm_country");
        $stmt->execute();
        while ($response = $stmt->fetch(PDO::FETCH_ASSOC)) {
            array_push($results, $response);
        }
        return $results;
    }

    public function getAllCurrencies()
    {
        $results = [];
        $stmt = $this->restapi->dbutils->runQuery("SELECT * FROM pm_currency");
        $stmt->execute();
        while ($response = $stmt->fetch(PDO::FETCH_ASSOC)) {
            array_push($results, $response);
        }
        return $results;
    }
    public function createAccount($fields)
    {
        $response = array();
        $db_name = $this->generateDBName();
        $is_active = true;
        $fields["db_name"] = $db_name;
        $fields["is_active"] = $is_active;
        // TO-DO
        // create company
        $company = $this->company->createCompany($fields);
        // get company
        $companyid = $company["id"];
        // create user$companyid
        $is_staff = true;
        $is_superuser = true;
        $fields["is_staff"] = $is_staff;
        $fields["is_superuser"] = $is_superuser;
        $fields["is_verified"] = true;
        /////////////////////////////////
        $user = $this->restapi->authCreate($fields, $companyid);
        $response["company"] = $company;
        $response["user"] = $user;
        $userid = $user["id"];
        // get user
        $this->CreateDatabase($db_name, $companyid, $userid);
        // merge user and company
        // init settings
        $this->_initDefaultSettings($companyid);
        return $response;
    }




    public function VerifyAccount($data)
    {
        extract($data);
        if ($this->restapi->UserExists($username, $companyid)) {
            die($this->restapi->Response(["message" => "Username already taken", "success" => false], 400));
        } else if (!$this->restapi->utils->isValidEmail($email)) {
            die($this->restapi->Response(["message" => "Invalid Email address", "success" => false], 400));
        } else if ($this->restapi->utils->EmailExists($email)) {
            die($this->restapi->Response(["message" => "Email already taken", "success" => false], 400));
        } else if ($this->company->getCompany($username)) {
            die($this->restapi->dbutils->Response(["message" => "Company name already taken", "success" => false], 400));
        }

        return array("message" => "", "success" => true);
    }


    public function CreateDatabase($databaseName, $companyid, $userid, $databaseCollation = "utf8mb4_unicode_ci")
    {
        // Database configuration
        //////////////////////////////////////////////////////////////////
        try {
            // Create connection (without specifying a database)
            // Database details with collation
            // Recommended collation for full Unicode support
            // SQL to create database with collation
            $sql_drop = "DROP DATABASE IF EXISTS $databaseName";
            $this->conn->exec($sql_drop);
            //////////////////////////////////////////////////
            $sql = "CREATE DATABASE IF NOT EXISTS $databaseName 
                    CHARACTER SET utf8mb4 
                    COLLATE $databaseCollation";
            // Execute the query
            $this->conn->exec($sql);
            /////////////////////////////////////////////////////////////////////////////////
            $response = $this->SeedDatabase($databaseName, $companyid, $userid);
            ////////////////////////////////////////////////////////////////
            return $response;
        } catch (PDOException $e) {
            return array("message" => "Error: " . $e->getMessage(), "success" => false);
        }
    }

    public function SeedDatabase($databaseName, $companyid, $userid)
    {
        $filePath = $this->company->utils->joinPaths(__DIR__, "data.sql");
        $this->conn->exec("USE $databaseName");
        // Check if the file exists and is readable
        if (!file_exists($filePath) || !is_readable($filePath)) {
            die($this->restapi->Response(array("message" => "Error: SQL file not found or is not readable at $filePath", "success" => false)));
        }
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        try {
            ///////////////////////////////////////////////////////////////////////////////// SEED DATABASE
            // Read the entire file content into a string
            // Check if file exists
            if (!file_exists($filePath)) {
                die($this->restapi->Response(array("message" => "SQL file not found: $filePath", "success" => false)));
            }
            // Read SQL file
            $sql = file_get_contents($filePath);
            ///////////////////////////////////
            if ($sql === false) {
                die($this->restapi->Response(array("message" => "Failed to read SQL file: $filePath", "success" => false)));
            }
            // Temporary variable to store current query
            $tmp = '';
            // Loop through each line of the SQL file
            foreach (explode("\n", $sql) as $line) {
                // Skip comments and empty lines
                if (substr(trim($line), 0, 2) == '--' || trim($line) == '') {
                    continue;
                }
                // Add line to current segment
                $tmp .= $line;

                // Check if line ends with a semicolon (end of query)
                if (substr(trim($line), -1, 1) == ';') {
                    try {
                        // Execute query
                        $this->conn->exec($tmp);
                        $tmp = '';
                    } catch (PDOException $e) {
                        die($this->restapi->Response(array("message" => "Error executing query: " . $e->getMessage(), "success" => false)));
                        $tmp = '';
                    }
                }
            }
            /////////////////////////////////////////////////////////////////////////////// SEED COMPANY
            return array("message" => "Database created successfully", "success" => true);
        } catch (PDOException $e) {
            // Handle any database errors
            return die($this->restapi->Response(array("message" => "Database Error: " . $e->getMessage() . "\n", "success" => false)));
        }
    }

    public function getCompanyDBUtils($companyid)
    {
        /////////////////////////////////////////////
        $company = $this->company->getCompany($companyid);
        $company_no = $company["company_no"];
        /////////////////////////////////////////////
        extract($company);
        $companyDbUtils = new DBUtils($db_name);
        return $companyDbUtils;
    }

    public function CreateCompany($companyid)
    {
        /////////////////////////////////////////////
        $company = $this->company->getCompany($companyid);
        $company_no = $company["company_no"];
        /////////////////////////////////////////////
        extract($company);
        $companyDbUtils = new DBUtils($db_name);
        /////////////////////////////////////////////////
        if ($companyDbUtils->isDBInService()) {
            ////////
            $stmt2 = $companyDbUtils->runQuery("SELECT * FROM `pm_company` WHERE `company_no`=:ucompany_no");
            $stmt2->bindParam(":ucompany_no", $company_no);
            $stmt2->execute();
            $counter = $stmt2->rowCount();
            if ($counter == 0) {
                // Prepare the statement
                $stmt = $companyDbUtils->runQuery("INSERT INTO `pm_company` 
            (`company_no`, `company_name`, `site_title`, `db_name`, `logo`, `favicon`, `email`, `address`,`postcode`,`city`,`mobile`,`phone`,`is_active`, `last_updated`)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
                // Bind the values to the placeholders
                // The bindParam/bindValue method automatically handles quoting and escapes the data.
                $stmt->bindParam(1, $company_no);
                $stmt->bindParam(2, $company_name);
                $stmt->bindParam(3, $site_title);
                $stmt->bindParam(4, $db_name);
                /////////////////////////////////////
                $stmt->bindParam(5, $logo);
                $stmt->bindParam(6, $favicon);
                $stmt->bindParam(7, $email);
                $stmt->bindParam(8, $address);
                $stmt->bindParam(9, $postcode);
                $stmt->bindParam(10, $city);
                $stmt->bindParam(11, $mobile);
                $stmt->bindParam(12, $phone);
                ////////////////////////////////////////
                $stmt->bindParam(13, $is_active);
                $stmt->bindParam(14, $last_updated);
                // Execute the statement
                if ($stmt->execute()) {
                    return array("message" => "Successfully created company " . $db_name, "success" => true);
                } else {
                    return array("message" => "Something went wrong, please try again laiter" . $db_name, "success" => false);
                }
            } else {
                $stmt = $companyDbUtils->runQuery("UPDATE `pm_company` SET `company_name`=?, `site_title`=?, `db_name`=?, `logo`=?, `favicon`=?, `email`=?, `address`=?,`postcode`=?,`city`=?,`mobile`=?,`phone`=?,`is_active`=?, `last_updated`=? WHERE `company_no`=?");
                // Bind the values to the placeholders
                // The bindParam/bindValue method automatically handles quoting and escapes the data.
                $stmt->bindParam(1, $company_name);
                $stmt->bindParam(2, $site_title);
                $stmt->bindParam(3, $db_name);
                /////////////////////////////////////
                $stmt->bindParam(4, $logo);
                $stmt->bindParam(5, $favicon);
                $stmt->bindParam(6, $email);
                $stmt->bindParam(7, $address);
                $stmt->bindParam(8, $postcode);
                $stmt->bindParam(9, $city);
                $stmt->bindParam(10, $mobile);
                $stmt->bindParam(11, $phone);
                ////////////////////////////////////////
                $stmt->bindParam(12, $is_active);
                $stmt->bindParam(13, $last_updated);
                $stmt->bindParam(14, $company_no);
                // Execute the statement
                if ($stmt->execute()) {
                    return array("message" => "Successfully updated company " . $db_name, "success" => true);
                } else {
                    return array("message" => "Something went wrong, please try again laiter" . $db_name, "success" => false);
                }
                // 
            }
        } else {
            return array("message" => "Failed to create company" . $db_name, "success" => true);
        }
        // //////////////////////////////////////////////////////////////////////////////////////
    }

    public function getCompany($companyid)
    {
        $company = $this->company->getCompany($companyid);
        $db_name = $company["db_name"];
        $company_no = $company["company_no"];
        $companyDbUtils = new DBUtils($db_name);
        $response = array();
        $stmt = $companyDbUtils->runQuery("SELECT * FROM pm_company WHERE company_no=:ucompanyno");
        $stmt->bindparam(":ucompanyno", $company_no);
        $stmt->execute();
        $counter = $stmt->rowCount();
        $response = $stmt->fetch(PDO::FETCH_ASSOC);
        $response["success"] = true;
        ///////////////
        return $response;
    }
    /////////////////////////////////////////
    public function getUser($userid)
    {
        $response = array();
        $user = $this->restapi->getUser($userid);
        $companyid = $user["company"];
        $userno = $user["user_no"];
        $company = $this->company->getCompany($companyid);
        $db_name = $company["db_name"];
        $company_no = $company["company_no"];
        $companyDbUtils = new DBUtils($db_name);
        $stmt = $companyDbUtils->runQuery("SELECT * FROM pm_user WHERE user_no=:uuserno");
        $stmt->bindparam(":uuserno", $userno);
        $stmt->execute();
        $counter = $stmt->rowCount();
        $response = $stmt->fetch(PDO::FETCH_ASSOC);
        $response["company"] = $company;
        $response["token"] = $user["token"];
        $response["success"] = true;
        ///////////////
        return $response;
    }
    /////////////////////////////////////////////
    public function login($username, $password)
    {
        $login = $this->restapi->authenticateLogin($username, $password);
        if ($login["success"]) {
            $userid = $login["id"];
            return $this->getUser($userid);
        } else {
            return $login;
        }
    }
    ////////////////////////////////////
    public function AuthToken($token)
    {
        $data = $this->restapi->AuthToken($token);
        if ($data["success"]) {
            $userid = intval($data["userid"]);
            return $this->getUser($userid);
        } else {
            return $data;
        }
    }
    //  array
    public function Auth()
    {
        $data = $this->restapi->getAuthToken();
        if ($data["success"]) {
            $userid = intval($data["userid"]);
            return $this->getUser($userid);
        } else {
            return $data;
        }
    }

    public function _initAuth()
    {
        $auth = $this->restapi->getAuthToken();
        if ($auth["success"]) {
            $userid = intval($auth["userid"]);
            return $this->getUser($userid);
        } else {
            die($this->restapi->Response($auth, 400));
        }
    }


    //  array
    public function AuthUser()
    {
        $data = $this->restapi->getAuthToken();
        if ($data["success"]) {
            $userid = intval($data["userid"]);
            return $this->restapi->getUser($userid);
        } else {
            return $data;
        }
    }

    public function AuthCompany()
    {
        $data = $this->restapi->getAuthToken();
        if ($data["success"]) {
            $companyid = intval($data["companyid"]);
            return $this->company->getCompany($companyid);
        } else {
            return $data;
        }
    }

    public function Normallogin($username, $password, $companyid)
    {
        ////////////////////////////////////////////////////////
        $currentCompany = $this->company->getCompany($companyid);
        $db_name = $currentCompany["db_name"];
        $companyDbUtils = new DBUtils($db_name);
        //////////////////////////////////////////////////////////////
        $newpassword = $this->restapi->utils->passwordEncrypt($password, 'md5');
        // print_r($login);
        $stmt = $companyDbUtils->runQuery("SELECT * FROM pm_user WHERE (`login`=:uusername OR `email`=:uusername) AND `pass`=:upassword");
        $stmt->bindparam(":uusername", $username);
        $stmt->bindparam(":upassword", $newpassword);
        if ($stmt->execute()) {
            $counter = $stmt->rowCount();
            if ($counter > 0) { // if the user already exits in the current company in session
                $row = $stmt->fetch(PDO::FETCH_ASSOC);
                $row["success"] = true;
                return $row;
            } else {
                return array("message" => "Invalid login credentials", "success" => false);
            }
        } else {
            return array("message" => "Something went wrong, please try again laiter" . $db_name, "success" => false);
        }
    }

    /////////////////////////////////////////////
    public function loginUser($username, $password, $companyid)
    {
        ////////////////////////////////////////////////////////
        $currentCompany = $this->company->getCompany($companyid);
        $db_name = $currentCompany["db_name"];
        $company_no = $currentCompany["company_no"];
        $companyDbUtils = new DBUtils($db_name);
        //////////////////////////////////////////////////////////////
        $login = $this->restapi->authenticateLogin($username, $password);
        if ($login["success"]) {
            $userid = $login["id"];
            $usercompanyid = $login["company"];
            $userno = $login["user_no"];
            // $userCompany = $this->company->getCompany($companyid);
            $stmt = $companyDbUtils->runQuery("SELECT * FROM pm_user WHERE user_no=:uuserno");
            $stmt->bindparam(":uuserno", $userno);
            if ($stmt->execute()) {
                $counter = $stmt->rowCount();
                if ($counter > 0) { // if the user already exits in the current company in session
                    return $this->getUser($userid);
                } else {
                    $user = $this->restapi->getUser($userid);
                    $type = $user["type"];
                    $mresponse = array();
                    $mresponse["company"] = $currentCompany;
                    $mresponse["user"] = $user;
                    // get company from the user data from his previous database\
                    $usercompany = $this->company->getCompany($usercompanyid);
                    $udb_name = $usercompany["db_name"];
                    $ucompany_no = $usercompany["company_no"];
                    $usercompanyDbUtils = new DBUtils($udb_name);
                    $stmt = $usercompanyDbUtils->runQuery("SELECT * FROM pm_user WHERE user_no=:uuserno");
                    $stmt->bindparam(":uuserno", $userno);
                    if ($stmt->execute()) {
                        $counter = $stmt->rowCount();
                        if ($counter > 0) { // if the user already exits in the current company in session
                            $userdata = $stmt->fetch(PDO::FETCH_ASSOC);
                            if ($userdata["type"] == "administrator" || $userdata["type"] == "hotel") { // users should join other hotels as adminitrators or owners
                                $userdata["type"] = "registered";
                            }
                            $userdata["company_name"] = $userdata["company"];
                            /////////////////////////////////////////////////////////////////////////////////////
                            $user = $this->CreateUser($mresponse, $userdata);
                            return $this->getUser($userid);
                        } else {
                            return array("message" => "User doesn't exist", "success" => false);
                        }
                    } else {
                        return array("message" => "Something went wrong, please try again laiter", "success" => false);
                    }
                    // TODO: 
                    // $mresponse 
                    // get user 
                    // check if admin , hotel or register
                    // create user in the current database
                }
            } else {
                return array("message" => "Something went wrong, please try again laiter", "success" => false);
            }
        } else {
            return $login;
        }
    }

    public function _initDefaultSettings($companyid)
    {
        /////////////////////////////////////////////
        $company = $this->company->getCompany($companyid);
        /////////////////////////////////////////////////
        if (!$company["success"]) {
            die($company);
        }
        /////////////////////////////////////////////
        $uuid = $this->restapi->utils->generateUUID();
        $email = $company["email"];
        // TODO: Add default settings
        $this->settings->UpdateSettingByCodeName($companyid, "PESAPAL_IPN_ID", $uuid);
        $this->settings->UpdateSettingByCodeName($companyid, "PESAPAL_NOTIFICATION_EMAIL", $email);
    }



    /////////////////////////////////////////////
    public function CreateUser($data, $info)
    {

        extract($info);
        $company = $data["company"];
        ////////////////////////////
        $company_id = $company["id"];
        $company_no = $company["company_no"];
        $db_name = $company["db_name"];
        ////////////////////////////////////////////////////////////
        $user = $data["user"];
        $password = $user["password"];
        $user_no = $user["user_no"];
        $type = isset($type) || empty($type) ? "administrator" : $type;
        $timestamp = time(); // Returns current Unix timestamp
        $add_date = isset($add_date) || empty($add_date) ? $timestamp : $add_date;
        $edit_date = isset($edit_date) || empty($edit_date) ? $timestamp : $edit_date;
        $checked = isset($checked) || empty($checked) ? 1 : $checked;
        $fb_id = isset($fb_id) || empty($fb_id) ? null : $fb_id;
        $is_super_user = isset($is_super_user) || empty($is_super_user) ? 1 : $is_super_user;
        $token = isset($token) || empty($token) ? "" : $token;
        $companyDbUtils = new DBUtils($db_name);
        /////////////////////////////////////////
        $scompany = $this->getCompany($company_id);
        $scompanyid = $scompany["id"];
        $company_name = isset($company_name) && !empty($company_name) ? $company_name : $scompany["company_name"];
        /////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////
        if ($companyDbUtils->isDBInService()) {
            ////////
            $stmt2 = $companyDbUtils->runQuery("SELECT * FROM `pm_user` WHERE `user_no`=:uuser_no");
            $stmt2->bindParam(":uuser_no", $user_no);
            $stmt2->execute();
            $counter = $stmt2->rowCount();
            if ($counter == 0) {
                // Prepare the statement
                $stmt = $companyDbUtils->runQuery("INSERT INTO `pm_user` (`company_id`, `user_no`, `firstname`, `lastname`, `email`, `login`, `pass`, `type`, `add_date`, `edit_date`, `checked`, `fb_id`, `address`, `postcode`, `city`, `company`, `country`, `mobile`, `phone`, `token`, `is_super_user`) 
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
                // Bind the values to the placeholders
                $stmt->bindParam(1, $scompanyid);
                $stmt->bindParam(2, $user_no);
                $stmt->bindParam(3, $first_name);
                $stmt->bindParam(4, $last_name);
                $stmt->bindParam(5, $email);
                $stmt->bindParam(6, $username);
                $stmt->bindParam(7, $password);
                $stmt->bindParam(8, $type);
                $stmt->bindParam(9, $add_date);
                $stmt->bindParam(10, $edit_date);
                $stmt->bindParam(11, $checked);
                $stmt->bindParam(12, $fb_id);
                $stmt->bindParam(13, $address);
                $stmt->bindParam(14, $postcode);
                $stmt->bindParam(15, $city);
                $stmt->bindParam(16, $company_name);
                $stmt->bindParam(17, $country);
                $stmt->bindParam(18, $mobile);
                $stmt->bindParam(19, $phone);
                $stmt->bindParam(20, $token);
                $stmt->bindParam(21, $is_super_user);
                // Execute the statement
                if ($stmt->execute()) {
                    /////////////////////////////////////////////////////////////////
                    $response = array();
                    $stmt3 = $companyDbUtils->runQuery("SELECT * FROM pm_user WHERE user_no=:uuserno");
                    $stmt3->bindparam(":uuserno", $user_no);
                    if ($stmt3->execute()) {
                        $counter = $stmt3->rowCount();
                        if ($counter > 0) {
                            $response = $stmt3->fetch(PDO::FETCH_ASSOC);
                            $response["company"] = $company;
                            $response["success"] = true;
                            return $response;
                        } else {
                            return array("message" => "No user with this user number was found", "success" => false);
                        }
                    } else {
                        return array("message" => "Something went wrong, please try again laiter", "success" => false);
                    }
                    //////////////////////////////////////////

                } else {
                    return array("message" => "Something went wrong, please try again laiter", "success" => false);
                }
            } else {
                // Prepare the statement
                $stmt = $companyDbUtils->runQuery("UPDATE `pm_user` SET  `firstname`= ?, `lastname`= ?, `email`= ?, `login`= ?, `pass`= ?, `type`= ?, `add_date`= ?, `edit_date`= ?, `checked`= ?, `fb_id`= ?, `address`= ?, `postcode`= ?, `city`= ?, `company`= ?, `country`= ?, `mobile`= ?, `phone`= ?, `token`= ?, `is_super_user`= ? WHERE `user_no`= ?");
                // Bind the values to the placeholders
                $stmt->bindParam(1, $first_name);
                $stmt->bindParam(2, $last_name);
                $stmt->bindParam(3, $email);
                $stmt->bindParam(4, $username);
                $stmt->bindParam(5, $password);
                $stmt->bindParam(6, $type);
                $stmt->bindParam(7, $add_date);
                $stmt->bindParam(8, $edit_date);
                $stmt->bindParam(9, $checked);
                $stmt->bindParam(10, $fb_id);
                $stmt->bindParam(11, $address);
                $stmt->bindParam(12, $postcode);
                $stmt->bindParam(13, $city);
                $stmt->bindParam(14, $company_name);
                $stmt->bindParam(15, $country);
                $stmt->bindParam(16, $mobile);
                $stmt->bindParam(17, $phone);
                $stmt->bindParam(18, $token);
                $stmt->bindParam(19, $is_super_user);
                $stmt->bindParam(20, $user_no);
                // Execute the statement
                if ($stmt->execute()) {
                    /////////////////////////////////////////////////////////////////
                    $response = array();
                    $stmt3 = $companyDbUtils->runQuery("SELECT * FROM pm_user WHERE user_no=:uuserno");
                    $stmt3->bindparam(":uuserno", $user_no);
                    if ($stmt3->execute()) {
                        $counter = $stmt3->rowCount();
                        if ($counter > 0) {
                            $response = $stmt3->fetch(PDO::FETCH_ASSOC);
                            $response["company"] = $company;
                            $response["success"] = true;
                            return $response;
                        } else {
                            return array("message" => "No user with this user number was found", "success" => false);
                        }
                        //////////////////////////////////////////
                    } else {
                        return array("message" => "Something went wrong, please try again laiter", "success" => false);
                    }
                } else {
                    return array("message" => "Something went wrong, please try again laiter", "success" => false);
                }
            }
        } else {
            return array("message" => "Failed connected to the created database:" . $db_name, "success" => true);
        }
        // //////////////////////////////////////////////////////////////////////////////////////
    }

    public function createUpdateSaasUser($info, $companyid, $user_no = null)
    {
        extract($info);
        // TO-DO
        // create company
        $company = $this->company->getCompany($companyid);
        // get company
        $companyid = $company["id"];
        // create user$companyid
        ////////////////////////////
        $company_id = $company["id"];
        $db_name = $company["db_name"];
        ///////////////////////////////
        $userno = isset($user_no) || empty($user_no) ? $this->restapi->utils->getRandom() : $user_no;
        //////////////////////////////////////
        $companyDbUtils = new DBUtils($db_name);
        /////////////////////////////////////////
        $scompany = $this->getCompany($company_id);
        $scompanyid = $scompany["id"];
        ///////////////////////////////////////////////////////
        if ($companyDbUtils->isDBInService()) {
            /////////////////////////////////////////////////////////////////////////
            $stmt2 = $companyDbUtils->runQuery("SELECT * FROM `pm_user` WHERE `user_no`=:uuser_no");
            $stmt2->bindParam(":uuser_no", $userno);
            $stmt2->execute();
            $counter = $stmt2->rowCount();
            if ($counter == 0) {
                $newpassword = $this->restapi->utils->passwordEncrypt($password, 'md5');
                // Prepare the statement
                $stmt = $companyDbUtils->runQuery("INSERT INTO `pm_user` (`company_id`, `user_no`, `firstname`, `lastname`, `email`, `login`, `pass`, `type`, `add_date`, `edit_date`, `checked`, `fb_id`, `address`, `postcode`, `city`, `company`, `country`, `mobile`, `phone`, `token`, `is_super_user`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
                // Bind the values to the placeholders
                $stmt->bindParam(1, $scompanyid);
                $stmt->bindParam(2, $userno);
                $stmt->bindParam(3, $first_name);
                $stmt->bindParam(4, $last_name);
                $stmt->bindParam(5, $email);
                $stmt->bindParam(6, $username);
                $stmt->bindParam(7, $newpassword);
                $stmt->bindParam(8, $type);
                $stmt->bindParam(9, $add_date);
                $stmt->bindParam(10, $edit_date);
                $stmt->bindParam(11, $checked);
                $stmt->bindParam(12, $fb_id);
                $stmt->bindParam(13, $address);
                $stmt->bindParam(14, $postcode);
                $stmt->bindParam(15, $city);
                $stmt->bindParam(16, $company_name);
                $stmt->bindParam(17, $country);
                $stmt->bindParam(18, $mobile);
                $stmt->bindParam(19, $phone);
                $stmt->bindParam(20, $token);
                $stmt->bindParam(21, $is_super_user);
                // Execute the statement
                if ($stmt->execute()) {
                    /////////////////////////////////////////////////////////////////
                    $response = array();
                    $stmt3 = $companyDbUtils->runQuery("SELECT * FROM pm_user WHERE user_no=:uuserno");
                    $stmt3->bindparam(":uuserno", $user_no);
                    if ($stmt3->execute()) {
                        $counter = $stmt3->rowCount();
                        if ($counter > 0) {
                            $response = $stmt3->fetch(PDO::FETCH_ASSOC);
                            $response["company"] = $company;
                            $response["success"] = true;
                            return $response;
                        } else {
                            return array("message" => "No user with this user number was found", "success" => false);
                        }
                    } else {
                        return array("message" => "Something went wrong, please try again laiter", "success" => false);
                    }
                    //////////////////////////////////////////
                } else {
                    return array("message" => "Something went wrong, please try again laiter", "success" => false);
                }
            } else {
                $old_user = $stmt2->fetch(PDO::FETCH_ASSOC);
                ///////////////////////////////////////
                $type = isset($type) || empty($type) ? $old_user["type"] : $type;
                $add_date = isset($add_date) || empty($add_date) ? $old_user["add_date"] : $add_date;
                $edit_date = isset($edit_date) || empty($edit_date) ? $old_user["edit_date"] : $edit_date;
                $checked = isset($checked) || empty($checked) ? $old_user["checked"] : $checked;
                $fb_id = isset($fb_id) || empty($fb_id) ? $old_user["fb_id"] : $fb_id;
                $is_super_user = isset($is_super_user) || empty($is_super_user) ? $old_user["is_super_user"] : $is_super_user;
                $token = isset($token) || empty($token) ? $old_user["token"] : $token;
                $username = isset($username) || empty($username) ? $old_user["username"] : $username;
                $first_name = isset($first_name) || empty($first_name) ? $old_user["first_name"] : $first_name;
                $last_name = isset($last_name) || empty($last_name) ? $old_user["last_name"] : $last_name;
                $email = isset($email) || empty($email) ? $old_user["email"] : $email;
                ///////////////////////////////////////////////////////////////////////////////
                $address = isset($address) || empty($address) ? $old_user["address"] : $address;
                $postcode = isset($postcode) || empty($postcode) ? $old_user["postcode"] : $postcode;
                $city = isset($city) || empty($city) ? $old_user["city"] : $city;
                $company_name = isset($company_name) || empty($company_name) ? $old_user["company_name"] : $company_name;
                $country = isset($country) || empty($country) ? $old_user["country"] : $country;
                $mobile = isset($mobile) || empty($mobile) ? $old_user["mobile"] : $mobile;
                $phone = isset($phone) || empty($phone) ? $old_user["phone"] : $phone;
                $newpassword = empty($password) ? $old_user["pass"] : $this->restapi->utils->passwordEncrypt($password, 'md5');
                // Prepare the statement
                $stmt = $companyDbUtils->runQuery("UPDATE `pm_user` SET  `firstname`= ?, `lastname`= ?, `email`= ?, `login`= ?, `pass`= ?, `type`= ?, `add_date`= ?, `edit_date`= ?, `checked`= ?, `fb_id`= ?, `address`= ?, `postcode`= ?, `city`= ?, `company`= ?, `country`= ?, `mobile`= ?, `phone`= ?, `token`= ?, `is_super_user`= ? WHERE `user_no`= ?");
                // Bind the values to the placeholders
                $stmt->bindParam(1, $first_name);
                $stmt->bindParam(2, $last_name);
                $stmt->bindParam(3, $email);
                $stmt->bindParam(4, $username);
                $stmt->bindParam(5, $newpassword);
                $stmt->bindParam(6, $type);
                $stmt->bindParam(7, $add_date);
                $stmt->bindParam(8, $edit_date);
                $stmt->bindParam(9, $checked);
                $stmt->bindParam(10, $fb_id);
                $stmt->bindParam(11, $address);
                $stmt->bindParam(12, $postcode);
                $stmt->bindParam(13, $city);
                $stmt->bindParam(14, $company_name);
                $stmt->bindParam(15, $country);
                $stmt->bindParam(16, $mobile);
                $stmt->bindParam(17, $phone);
                $stmt->bindParam(18, $token);
                $stmt->bindParam(19, $is_super_user);
                $stmt->bindParam(20, $user_no);
                // Execute the statement
                if ($stmt->execute()) {
                    /////////////////////////////////////////////////////////////////
                    $response = array();
                    $stmt3 = $companyDbUtils->runQuery("SELECT * FROM pm_user WHERE user_no=:uuserno");
                    $stmt3->bindparam(":uuserno", $user_no);
                    if ($stmt3->execute()) {
                        $counter = $stmt3->rowCount();
                        if ($counter > 0) {
                            $response = $stmt3->fetch(PDO::FETCH_ASSOC);
                            $response["company"] = $company;
                            $response["success"] = true;
                            return $response;
                        } else {
                            return array("message" => "No user with this user number was found", "success" => false);
                        }
                        //////////////////////////////////////////
                    } else {
                        return array("message" => "Something went wrong, please try again laiter", "success" => false);
                    }
                } else {
                    return array("message" => "Something went wrong, please try again laiter", "success" => false);
                }
            }
        } else {
            return array("message" => "Failed connected to the created database:" . $db_name, "success" => true);
        }
        // //////////////////////////////////////////////////////////////////////////////////////
    }

    public function UpdateSaasUser($fields, $userno, $companyid)
    {
        $response = array();
        // create user$companyid
        $is_staff = false;
        $is_superuser = false;
        $fields["is_staff"] = $is_staff;
        $fields["is_superuser"] = $is_superuser;
        $fields["is_verified"] = false;
        $fields["is_active"] = true;
        // TO-DO
        // create company
        $company = $this->company->getCompany($companyid);
        // get company
        $companyid = $company["id"];
        // create user$companyid
        /////////////////////////////////
        $user = $this->restapi->authUpdate($fields, $userno);
        $response["company"] = $company;
        $response["user"] = $user;
        // get user
        // merge user and company
        return $response;
    }


    public function _initSession($auth)
    {
        $authtoken = $auth["token"];
        $token = $authtoken["token"];
        $tokenUser = $authtoken["user_id"];
        // COMPANY
        //////////////////////////////
        $company = $auth["company"];
        //print_r($company);
        $company_id = $company["id"];
        $company_no = $company["company_no"];
        $logo = $company["logo"];
        $favicon = $company["favicon"];
        $db_name = $company["db_name"];
        $site_title = $company["site_title"];
        $company_name = $company["company_name"];
        $email = $company["email"];
        $address = $company["address"];
        $postcode = $company["postcode"];
        $city = $company["city"];
        $mobile = $company["mobile"];
        $phone = $company["phone"];
        // AUTH SESSION
        $_SESSION['AUTH_KEY'] = $token;
        $_SESSION['AUTH_USER'] = $tokenUser;
        // INIT COMPANY SESSION
        ///////////////////////////////// Company
        $_SESSION['company']['id'] = $company_id;
        $_SESSION['company']['company_no'] = $company_no;
        $_SESSION['company']['db_name'] = $db_name;
        $_SESSION['company']['site_title'] = $site_title;
        $_SESSION['company']['company_name'] = $company_name;
        $_SESSION['company']['logo'] = $logo;
        $_SESSION['company']['favicon'] = $favicon;
        //////////////////////////////////////
        define('PMS_AUTH_KEY', $token);
        define('PMS_AUTH_USER', $tokenUser);
        define('PMS_DB_NAME', $db_name);
        define('PMS_SITE_TITLE', $site_title);
        define('PMS_SITE_NAME', $company_name);
        define('PMS_SITE_LOGO', $logo);
        define('PMS_SITE_FAVICON', $favicon);
        define('PMS_EMAIL', $email);
        define('PMS_ADDRESS', $address);
        define('PMS_PHONE', $phone);
        define('PMS_MOBILE', $mobile);
    }

    public function generateDBName($length = 5, $prefix = 'karibu_be_')
    {
        // Validate length
        $length = max(2, min(10, (int)$length));

        // Allowed characters (excluding special chars that might cause SQL issues)
        $chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
        $charLength = strlen($chars);

        $randomPart = '';
        for ($i = 0; $i < $length; $i++) {
            $randomPart .= $chars[rand(0, $charLength - 1)];
        }

        // Sanitize the custom prefix
        $prefix = preg_replace('/[^a-zA-Z0-9_]/', '', $prefix);

        // Combine and ensure it ends with underscore
        $generatedPrefix = rtrim($prefix, '_') . '_' . $randomPart;

        // Ensure total length is reasonable (max 20 chars)
        return substr($generatedPrefix, 0, 20);
    }

    public function AuthorizationError($errorMessage)
    {
        return '<!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Authorization Error</title>
            <!-- Use a simple, clean design to focus on the error message -->
            <style>
                body {
                    font-family: \'Inter\', Arial, sans-serif;
                    background-color: #f0f2f5;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    height: 100vh;
                    margin: 0;
                    text-align: center;
                    color: #333;
                }
                .error-container {
                    background-color: #fff;
                    padding: 40px 60px;
                    border-radius: 12px;
                    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
                    max-width: 90%;
                    width: 450px;
                    box-sizing: border-box;
                }
                .error-icon {
                    color: #d9534f;
                    font-size: 4em;
                    margin-bottom: 10px;
                }
                h1 {
                    color: #d9534f;
                    font-size: 1.5em;
                    margin: 0;
                    padding: 0;
                }
                p {
                    font-size: 1em;
                    color: #666;
                    margin-top: 10px;
                }
            </style>
        </head>
        <body>
            <div class="error-container">
                <div class="error-icon">&#9888;</div>
                <h1>' . htmlspecialchars($errorMessage, ENT_QUOTES, 'UTF-8') . '</h1>
                <p>Please return to the previous page and try again.</p>
            </div>
        </body>
        </html>';
    }
}
