<?php
require '../config/db.php';
require '../app/Controllers/sessions.php';

// Consultar configuracoes da plataforma
$stmtConfigsPlatform = $pdo->prepare("SELECT * FROM configs");
$stmtConfigsPlatform->execute();
$stmtConfigsPlatformResult = $stmtConfigsPlatform->fetch(PDO::FETCH_ASSOC);

$affiliates_ref = filter_input(INPUT_GET, "ref", FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$data = filter_input_array(INPUT_POST, FILTER_SANITIZE_FULL_SPECIAL_CHARS);

// Verificar codigo de afiliado para adicionar visualizaçao 
$stmtReference2 = $pdo->prepare("SELECT * FROM users WHERE affiliate_code = :affiliate_code");
$stmtReference2->bindValue(':affiliate_code', $affiliates_ref);
$stmtReference2->execute();
$resultReference2 = $stmtReference2->fetch(PDO::FETCH_ASSOC);

if ($resultReference2) {
    $stmtUpdateVisits = $pdo->prepare('UPDATE users SET visits_affiliate_link = visits_affiliate_link + 1 WHERE affiliate_code = :affiliate_code');
    $stmtUpdateVisits->execute([
        ':affiliate_code' => $resultReference2['affiliate_code']
    ]);
}

$toastMessage = null;
$toastType = null;

$stmtClientIp = $pdo->prepare("SELECT 1 FROM users WHERE client_ip = :client_ip LIMIT 1");
$stmtClientIp->execute([
    ':client_ip' => getIP()
]);

function getIP()
{
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
        return $_SERVER['HTTP_CLIENT_IP'];
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ipList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        return trim($ipList[0]);
    }
    return $_SERVER['REMOTE_ADDR'] ?? 'Desconhecido';
}

if ($stmtClientIp->rowCount() === 0 && !isset($_SESSION['visitor'])) {
    $_SESSION['visitor'] = 'anonimo';
    $stmtInsertVisitor = $pdo->prepare("INSERT INTO visitors (description, ip_visitor, created_at) VALUES (:description, :ip_visitor, :created_at)");
    $stmtInsertVisitor->execute([
        ':description' => 'anônimo',
        ':ip_visitor' => getIP(),
        ':created_at' => date("Y-m-d H:i:s")
    ]);
}

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    // Verificação de campos
    if (isset($_POST['register'])) {
        if (empty($data['phone']) || empty($data['password'])) {
            $toastMessage = 'Campos incompletos.';
            $toastType = 'error';
        } elseif (strlen($data['phone']) < 11) {
            $toastMessage = 'Celular inválido.';
            $toastType = 'error';
        } elseif (strlen($data['password']) < 6) {
            $toastMessage = 'Mínimo 6 caracteres para o campo senha.';
            $toastType = 'error';
        } else {
            // Verificação de telefone já existente
            $stmt = $pdo->prepare("SELECT 1 FROM users WHERE phone = :phone LIMIT 1");
            $stmt->bindValue(':phone', $data['phone']);
            $stmt->execute();

            // Verificacao de telefone ja existente admin
            $stmtPhoneAdmin = $pdo->prepare("SELECT 1 FROM admin_users WHERE phone = :phone LIMIT 1");
            $stmtPhoneAdmin->bindValue(':phone', $data['phone']);
            $stmtPhoneAdmin->execute();

            if ($stmt->rowCount() > 0 || $stmtPhoneAdmin->rowCount() > 0) {
                $toastMessage = 'Esse celular já está cadastrado.';
                $toastType = 'error';
            } else {
                // Verificação de código afiliado já existente antes de criar o usuário
                do {
                    $affiliateCode = bin2hex(random_bytes(3));
                    $stmt2 = $pdo->prepare("SELECT 1 FROM users WHERE affiliate_code = :affiliate_code LIMIT 1");
                    $stmt2->execute([':affiliate_code' => $affiliateCode]);
                    $result = $stmt2->fetch(PDO::FETCH_ASSOC);
                    $attempts++;
                    if ($attempts > 5) {
                        throw new Exception(("Falha ao gerar Código de afiliado único."));
                    }
                } while ($result);

                // Verifica se o código de indicação é válido, se fornecido
                if (!empty($data['reference_code'])) {
                    $stmtReference = $pdo->prepare("SELECT * FROM users WHERE affiliate_code = :affiliate_code");
                    $stmtReference->bindValue(':affiliate_code', $data['reference_code']);
                    $stmtReference->execute();

                    $resultReference = $stmtReference->fetch(PDO::FETCH_ASSOC);
                    if (!$resultReference) {
                        $toastMessage = 'Código afiliado inválido.';
                        $toastType = 'error';
                        return;
                    }
                }

                // Realiza o cadastro do usuário
                try {
                    $pdo->beginTransaction();

                    $stmtInsert = $pdo->prepare("INSERT INTO users (phone, balance, password, client_ip, affiliate_code, indicated_by, date) VALUES (:phone, :balance, :password, :client_ip, :affiliate_code, :indicated_by, :date)");
                    $stmtInsert->execute([
                        ':phone' => $data['phone'],
                        ':balance' => 0,
                        ':password' => password_hash($data['password'], PASSWORD_DEFAULT),
                        ':client_ip' => getIP(),
                        ':affiliate_code' => strtoupper($affiliateCode),
                        ':indicated_by' => $resultReference['affiliate_code'] ?? null,
                        ':date' => date("Y-m-d H:i:s")
                    ]);

                    $pdo->commit();

                    $toastMessage = 'Conta criada!';
                    $toastType = 'success';

                    $_SESSION['user'] = $data['phone'];

                    echo "
                    <script>
                    setTimeout(() => {
                        window.location.href = 'index.php';
                    }, 3000);
                    </script>";

                    // Trata erros de inserção ao banco de dados
                } catch (PDOException $e) {
                    $pdo->rollBack();
                    $toastMessage = 'Erro ao registrar: ' . $e->getMessage();
                    $toastType = 'error';
                }
            }
        }
    } elseif (isset($_POST['send-login'])) {
        $dataLogin = filter_input_array(INPUT_POST, FILTER_SANITIZE_FULL_SPECIAL_CHARS);

        if (empty($dataLogin['phone']) || empty($dataLogin['password'])) {
            $toastMessage = 'Campos incompletos.';
            $toastType = 'error';
        } elseif (strlen($dataLogin['phone']) < 11) {
            $toastMessage = 'Celular inválido.';
            $toastType = 'error';
        } elseif (strlen($dataLogin['password']) < 6) {
            $toastMessage = 'Mínimo 6 caracteres para o campo senha.';
            $toastType = 'error';
        } else {
            // Verifica se é admin
            $stmtLoginAdmin = $pdo->prepare("SELECT * FROM admin_users WHERE phone = :phone LIMIT 1");
            $stmtLoginAdmin->execute([':phone' => $dataLogin['phone']]);
            $resultAdmin = $stmtLoginAdmin->fetch(PDO::FETCH_ASSOC);

            if ($resultAdmin && password_verify($dataLogin['password'], $resultAdmin['password'])) {
                // Login como admin
                $updateAdmin = $pdo->prepare("UPDATE admin_users SET last_login = :last_login WHERE phone = :phone");
                $updateAdmin->execute([
                    ':last_login' => date("Y-m-d H:i:s"),
                    ':phone' => $dataLogin['phone'],
                ]);

                $_SESSION['user'] = $dataLogin['phone'];
                $_SESSION['admin_session'] = $dataLogin['phone'];
                $toastMessage = 'Bem-vindo a administração!';
                $toastType = 'success';
                echo "
                <script>
                setTimeout(() => {
                    window.location.href = 'dash/';
                }, 3000);
                </script>";
            } else {
                // Tenta login como usuário comum
                $stmtLoginUser = $pdo->prepare("SELECT * FROM users WHERE phone = :phone LIMIT 1");
                $stmtLoginUser->execute([':phone' => $dataLogin['phone']]);
                $resultUser = $stmtLoginUser->fetch(PDO::FETCH_ASSOC);

                if ($resultUser && password_verify($dataLogin['password'], $resultUser['password'])) {
                    $updateUser = $pdo->prepare("UPDATE users SET last_login = :last_login WHERE phone = :phone");
                    $updateUser->execute([
                        ':last_login' => date("Y-m-d H:i:s"),
                        ':phone' => $dataLogin['phone']
                    ]);

                    $_SESSION['user'] = $dataLogin['phone'];
                    $toastMessage = 'Você efetuou o login.';
                    $toastType = 'success';
                    echo "
                    <script>
                    setTimeout(() => {
                        window.location.href = 'index.php';
                    }, 3000);
                    </script>";
                } else {
                    $toastMessage = 'Usuário ou senha inválidos.';
                    $toastType = 'error';
                }
            }
        }
    }
}
