<?php
include(__DIR__ . '/table.php');

// =======================
// CONFIG
// =======================
try {
    @$config_ini = parse_ini_file(__DIR__ . "/config.ini");
} catch (Exception $e) {
    @$config_ini = parse_ini_file(__DIR__ . "/../config.ini");
}

// =======================
// DEBUG MODE
// =======================
if (!empty($config_ini['debug']) && $config_ini['debug'] == 1) {
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);
} else {
    ini_set('display_errors', 0);
}

// =======================
// SESSION
// =======================
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

// =======================
// CSRF TOKEN
// =======================
function generate_token() {
    if (!isset($_SESSION["ftg"])) {
        $_SESSION["ftg"] = bin2hex(random_bytes(32));
    }
    return $_SESSION["ftg"];
}

// =======================
// SQLITE DB PATH (ABSOLUTE)
// =======================
$dbPath = __DIR__ . '/../api/.db.db';

// =======================
// CREATE TABLES
// =======================
function createTables($tables, $dbLoc) {
    $db = new SQLite3($dbLoc);

    foreach ($tables as $tableName => $columns) {
        $sql = "CREATE TABLE IF NOT EXISTS $tableName (";
        foreach ($columns as $columnName => $columnType) {
            $sql .= "$columnName $columnType, ";
        }
        $sql = rtrim($sql, ', ') . ");";
        $db->exec($sql);
    }
    $db->close();
}

createTables($tables, $dbPath);

// =======================
// SQLITE WRAPPER
// =======================
class SQLiteWrapper {
    private $db;

    public function __construct($dbLoc) {
        $this->db = new SQLite3($dbLoc);
    }

    public function select($table, $columns = "*", $where = "", $order = "", $params = []) {
        $sql = "SELECT $columns FROM $table";
        if ($where) $sql .= " WHERE $where";
        if ($order) $sql .= " ORDER BY $order";

        $stmt = $this->db->prepare($sql);
        foreach ($params as $k => $v) {
            $stmt->bindValue($k, $v);
        }

        $res = $stmt->execute();
        $rows = [];
        while ($row = $res->fetchArray(SQLITE3_ASSOC)) {
            $rows[] = $row;
        }
        return $rows;
    }

    public function insert($table, $data) {
        $cols = implode(',', array_keys($data));
        $vals = ':' . implode(',:', array_keys($data));
        $stmt = $this->db->prepare("INSERT INTO $table ($cols) VALUES ($vals)");
        foreach ($data as $k => $v) {
            $stmt->bindValue(":$k", $v);
        }
        return $stmt->execute();
    }

    public function update($table, $data, $where, $params = []) {
        $set = [];
        foreach ($data as $k => $v) {
            $set[] = "$k=:$k";
        }
        $stmt = $this->db->prepare("UPDATE $table SET " . implode(',', $set) . " WHERE $where");
        foreach ($data as $k => $v) {
            $stmt->bindValue(":$k", $v);
        }
        foreach ($params as $k => $v) {
            $stmt->bindValue($k, $v);
        }
        return $stmt->execute();
    }

    public function delete($table, $where, $params = []) {
        $stmt = $this->db->prepare("DELETE FROM $table WHERE $where");
        foreach ($params as $k => $v) {
            $stmt->bindValue($k, $v);
        }
        return $stmt->execute();
    }

    public function getLastInsertId() {
        return $this->db->lastInsertRowID();
    }
}

// =======================
// INIT DB (GLOBAL)
// =======================
$db = new SQLiteWrapper($dbPath);

// =======================
// CURRENT USER
// =======================
function getCurrentUser($db) {
    if (empty($_SESSION['user_id'])) {
        return false;
    }

    $user = $db->select(
        "users",
        "*",
        "id = :id",
        "",
        [":id" => $_SESSION['user_id']]
    );

    return $user ? $user[0] : false;
}

// =======================
// ENCRYPTION
// =======================
class Encryption {
    public static function run($input) {
        return strrev(bin2hex($input));
    }
}

// =======================
// CURL CALL
// =======================
class calllink {
    public static function run($url) {
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 5,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false
        ]);
        return json_decode(curl_exec($ch), true);
    }
}

// =======================
// REAL IP
// =======================
function real_ip() {
    foreach ([
        'HTTP_X_FORWARDED_FOR',
        'HTTP_CLIENT_IP',
        'REMOTE_ADDR'
    ] as $key) {
        if (!empty($_SERVER[$key])) {
            return htmlspecialchars($_SERVER[$key], ENT_QUOTES, 'UTF-8');
        }
    }
    return 'unknown';
}
// =======================
// ROLE LABEL (PT-BR)
// =======================
function role_label_ptbr($role) {
    $map = [
        'master'         => 'MASTER',
        'super-reseller' => 'SUPER REVENDEDOR',
        'reseller'       => 'REVENDEDOR',
        'client'         => 'CLIENTE',
    ];
    $role = (string)$role;
    return $map[$role] ?? strtoupper($role);
}

// =======================
// SETTINGS (CHAVE/VALOR)
// =======================
function settings_get($db, $key, $default = null) {
    try {
        $rows = $db->select('settings', 'value', 'key = :k', '', [':k' => (string)$key]);
        if ($rows && array_key_exists('value', $rows[0])) {
            return $rows[0]['value'];
        }
    } catch (Throwable $e) {
        // ignore
    }
    return $default;
}

function settings_set($db, $key, $value) {
    $key = (string)$key;
    $value = (string)$value;
    try {
        $rows = $db->select('settings', 'key', 'key = :k', '', [':k' => $key]);
        if ($rows) {
            return $db->update('settings', ['value' => $value], 'key = :k', [':k' => $key]);
        }
        return $db->insert('settings', ['key' => $key, 'value' => $value]);
    } catch (Throwable $e) {
        return false;
    }
}
