<?php

/* =========================================================
   SIGNUP.PHP
   FRONTEND + BACKEND IN ONE FILE
========================================================= */

session_start();

require_once "db.php";

date_default_timezone_set("Africa/Nairobi");


/* =========================================================
   VARIABLES
========================================================= */

$error = "";

$phone = "";

$invitation = "3313386";

$country_code = "+234";


/* =========================================================
   CAPTCHA
========================================================= */

if (!isset($_SESSION['signup_captcha'])) {

    $_SESSION['signup_captcha'] =
        (string) random_int(1000, 9999);

}


/* =========================================================
   HANDLE SIGNUP
========================================================= */

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    $phone =
        trim($_POST['phone'] ?? '');

    $password =
        $_POST['password'] ?? '';

    $confirm_password =
        $_POST['confirm_password'] ?? '';

    $verification =
        trim($_POST['verification'] ?? '');

    $invitation =
        trim($_POST['invitation'] ?? '3313386');

    $country_code =
        trim($_POST['country_code'] ?? '+234');


    /* =====================================================
       CHECK DATABASE CONNECTION
    ===================================================== */

    if (!$conn) {

        $error =
            "Database connection failed.";

    }


    /* =====================================================
       PHONE VALIDATION
    ===================================================== */

    if (!$error && $phone === '') {

        $error =
            "Please enter your phone number.";

    }


    if (!$error) {

        /*
         * Remove spaces, brackets and dashes.
         */

        $clean_phone =
            preg_replace(
                '/[\s\-\(\)]/',
                '',
                $phone
            );


        /*
         * Remove country code if user
         * accidentally enters it.
         */

        $country_without_plus =
            ltrim(
                $country_code,
                '+'
            );


        if (
            strpos(
                $clean_phone,
                $country_code
            ) === 0
        ) {

            $clean_phone =
                substr(
                    $clean_phone,
                    strlen($country_code)
                );

        } elseif (
            strpos(
                $clean_phone,
                $country_without_plus
            ) === 0
        ) {

            $clean_phone =
                substr(
                    $clean_phone,
                    strlen($country_without_plus)
                );

        }


        /*
         * Keep numbers only.
         */

        $clean_phone =
            preg_replace(
                '/[^0-9]/',
                '',
                $clean_phone
            );


        if ($clean_phone === '') {

            $error =
                "Please enter a valid phone number.";

        } elseif (
            strlen($clean_phone) < 7
        ) {

            $error =
                "Please enter a valid phone number.";

        } elseif (
            strlen($clean_phone) > 15
        ) {

            $error =
                "Please enter a valid phone number.";

        }

    }


    /* =====================================================
       PASSWORD
    ===================================================== */

    if (!$error && $password === '') {

        $error =
            "Please enter your password.";

    }


    if (
        !$error &&
        strlen($password) < 6
    ) {

        $error =
            "Password must be at least 6 characters.";

    }


    /* =====================================================
       CONFIRM PASSWORD
    ===================================================== */

    if (
        !$error &&
        $password !== $confirm_password
    ) {

        $error =
            "Passwords do not match.";

    }


    /* =====================================================
       CAPTCHA
    ===================================================== */

    if (
        !$error &&
        $verification === ''
    ) {

        $error =
            "Please enter the verification code.";

    }


    if (
        !$error &&
        (
            !isset($_SESSION['signup_captcha']) ||
            !hash_equals(
                (string) $_SESSION['signup_captcha'],
                $verification
            )
        )
    ) {

        $error =
            "Incorrect verification code.";

    }


    /* =====================================================
       INVITATION CODE
    ===================================================== */

    if (!$error && $invitation === '') {

        $error =
            "Invitation code is required.";

    }


    /* =====================================================
       CREATE FULL PHONE
    ===================================================== */

    if (!$error) {

        $full_phone =
            $country_code . $clean_phone;

    }


    /* =====================================================
       CHECK DUPLICATE PHONE
    ===================================================== */

    if (!$error) {

        $stmt =
            $conn->prepare(
                "SELECT id
                 FROM users
                 WHERE phone = ?
                 LIMIT 1"
            );


        if (!$stmt) {

            $error =
                "Database error. Please try again.";

        } else {

            $stmt->bind_param(
                "s",
                $full_phone
            );

            $stmt->execute();

            $stmt->store_result();


            if ($stmt->num_rows > 0) {

                $error =
                    "This phone number is already registered.";

            }


            $stmt->close();

        }

    }


    /* =====================================================
       FIND REFERRER
    ===================================================== */

    $referred_by = null;


    if (
        !$error &&
        $invitation !== ''
    ) {

        /*
         * Find the user whose referral_code
         * matches the invitation code.
         */

        $stmt =
            $conn->prepare(
                "SELECT id
                 FROM users
                 WHERE referral_code = ?
                 LIMIT 1"
            );


        if ($stmt) {

            $stmt->bind_param(
                "s",
                $invitation
            );

            $stmt->execute();

            $stmt->bind_result(
                $referrer_id
            );


            if ($stmt->fetch()) {

                $referred_by =
                    (int) $referrer_id;

            }


            $stmt->close();

        }

    }


    /* =====================================================
       GENERATE UNIQUE REFERRAL CODE
    ===================================================== */

    if (!$error) {

        do {

            $new_referral_code =
                (string) random_int(
                    1000000,
                    9999999
                );


            $stmt =
                $conn->prepare(
                    "SELECT id
                     FROM users
                     WHERE referral_code = ?
                     LIMIT 1"
                );


            if (!$stmt) {

                $error =
                    "Database error. Please try again.";

                break;

            }


            $stmt->bind_param(
                "s",
                $new_referral_code
            );

            $stmt->execute();

            $stmt->store_result();

            $exists =
                $stmt->num_rows > 0;

            $stmt->close();


        } while ($exists);

    }


    /* =====================================================
       HASH PASSWORD
    ===================================================== */

    if (!$error) {

        $hashed_password =
            password_hash(
                $password,
                PASSWORD_DEFAULT
            );

    }


    /* =====================================================
       INSERT USER
    ===================================================== */

    if (!$error) {

        /*
         * Balance starts at 0.
         */

        $initial_balance = 0;


        if ($referred_by !== null) {

            /*
             * User has a valid referrer.
             */

            $stmt =
                $conn->prepare(
                    "INSERT INTO users
                    (
                        phone,
                        password,
                        balance,
                        referral_code,
                        referred_by,
                        created_at
                    )
                    VALUES
                    (
                        ?,
                        ?,
                        ?,
                        ?,
                        ?,
                        NOW()
                    )"
                );


            if (!$stmt) {

                $error =
                    "Unable to create account.";

            } else {

                $stmt->bind_param(
                    "ssdsi",
                    $full_phone,
                    $hashed_password,
                    $initial_balance,
                    $new_referral_code,
                    $referred_by
                );


                if (!$stmt->execute()) {

                    $error =
                        "Unable to create account. Please try again.";

                }


                $new_user_id =
                    $stmt->insert_id;


                $stmt->close();

            }

        } else {

            /*
             * No matching referrer found.
             *
             * referred_by will be NULL.
             */

            $stmt =
                $conn->prepare(
                    "INSERT INTO users
                    (
                        phone,
                        password,
                        balance,
                        referral_code,
                        referred_by,
                        created_at
                    )
                    VALUES
                    (
                        ?,
                        ?,
                        ?,
                        ?,
                        NULL,
                        NOW()
                    )"
                );


            if (!$stmt) {

                $error =
                    "Unable to create account.";

            } else {

                $stmt->bind_param(
                    "ssds",
                    $full_phone,
                    $hashed_password,
                    $initial_balance,
                    $new_referral_code
                );


                if (!$stmt->execute()) {

                    $error =
                        "Unable to create account. Please try again.";

                }


                $new_user_id =
                    $stmt->insert_id;


                $stmt->close();

            }

        }

    }


    /* =====================================================
       SUCCESS
    ===================================================== */

    if (!$error) {

        /*
         * Generate a fresh CAPTCHA.
         */

        $_SESSION['signup_captcha'] =
            (string) random_int(
                1000,
                9999
            );


        /*
         * Redirect to login.
         */

        header(
            "Location: login.php?registered=1"
        );

        exit;

    }


    /* =====================================================
       REFRESH CAPTCHA AFTER ERROR
    ===================================================== */

    $_SESSION['signup_captcha'] =
        (string) random_int(
            1000,
            9999
        );

}

?>

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport"
      content="width=device-width,
      initial-scale=1.0,
      maximum-scale=1.0,
      user-scalable=no">

<title>Signup</title>


<style>

/* =====================================================
   RESET
===================================================== */

* {

    box-sizing: border-box;

    -webkit-tap-highlight-color:
        transparent;
}


html,
body {

    margin: 0;

    padding: 0;

    width: 100%;

    min-height: 100%;

    font-family:
        Arial,
        Helvetica,
        sans-serif;

    background:
        #ffffff;

    color:
        #606060;
}


body {

    overflow-x:
        hidden;
}


/* =====================================================
   PAGE
===================================================== */

.page {

    width: 100%;

    min-height: 100vh;

    padding:
        45px
        18px
        35px;
}


/* =====================================================
   TITLE
===================================================== */

.title {

    width: 100%;

    margin:
        10px
        0
        45px;

    text-align:
        center;

    font-size:
        25px;

    line-height:
        1.2;

    font-weight:
        700;

    color:
        #5d5d5d;
}


/* =====================================================
   ERROR MESSAGE
===================================================== */

.error-message {

    width: 100%;

    padding:
        12px
        15px;

    margin:
        0
        0
        20px;

    border-radius:
        12px;

    background:
        #fff1f1;

    border:
        1px solid
        #ffd0d0;

    color:
        #d00000;

    text-align:
        center;

    font-size:
        12px;

    line-height:
        1.4;
}


/* =====================================================
   FORM GROUP
===================================================== */

.form-group {

    width: 100%;

    margin-bottom:
        19px;
}


/* =====================================================
   LABEL
===================================================== */

.label {

    display:
        block;

    margin:
        0
        0
        7px
        4px;

    font-size:
        14px;

    line-height:
        1.2;

    font-weight:
        700;

    color:
        #606060;
}


.required {

    color:
        #e60000;

    margin-left:
        2px;
}


/* =====================================================
   INPUT BOX
===================================================== */

.input-box {

    width:
        100%;

    height:
        55px;

    border-radius:
        30px;

    background:
        #f8f9fe;

    display:
        flex;

    align-items:
        center;

    padding:
        0
        10px;

    position:
        relative;

    overflow:
        hidden;
}


/* =====================================================
   GENERAL ICON
===================================================== */

.icon {

    width:
        40px;

    height:
        40px;

    min-width:
        40px;

    border-radius:
        11px;

    background:
        #00815f;

    color:
        #ffffff;

    display:
        flex;

    align-items:
        center;

    justify-content:
        center;

    font-size:
        19px;

    font-weight:
        700;

    margin-right:
        8px;
}


/* =====================================================
   INPUT
===================================================== */

.input-box input {

    width:
        100%;

    min-width:
        0;

    height:
        100%;

    border:
        0;

    outline:
        0;

    background:
        transparent;

    color:
        #333333;

    font-family:
        Arial,
        Helvetica,
        sans-serif;

    font-size:
        13px;

    font-weight:
        400;
}


.input-box input::placeholder {

    color:
        #a7a7a7;

    opacity:
        1;
}


/* =====================================================
   PHONE ICON
===================================================== */

.phone-icon {

    width:
        40px;

    height:
        40px;

    min-width:
        40px;

    border-radius:
        11px;

    background:
        #00815f;

    color:
        #ffffff;

    display:
        flex;

    align-items:
        center;

    justify-content:
        center;

    font-size:
        20px;

    margin-right:
        7px;
}


/* =====================================================
   PHONE PREFIX
===================================================== */

.phone-prefix {

    height:
        38px;

    min-width:
        78px;

    border:
        2px solid
        #e6e6e6;

    border-radius:
        12px;

    background:
        #ffffff;

    display:
        flex;

    align-items:
        center;

    justify-content:
        center;

    gap:
        5px;

    color:
        #16866d;

    font-size:
        13px;

    font-weight:
        700;

    margin-right:
        8px;

    padding:
        0
        5px;

    outline:
        none;
}


/* =====================================================
   PASSWORD
===================================================== */

.password-input {

    padding-right:
        8px;
}


/* =====================================================
   EYE
===================================================== */

.eye {

    width:
        28px;

    min-width:
        28px;

    height:
        28px;

    margin-left:
        5px;

    display:
        flex;

    align-items:
        center;

    justify-content:
        center;

    color:
        #c6c8cb;

    font-size:
        20px;

    cursor:
        pointer;

    user-select:
        none;
}


/* =====================================================
   VERIFICATION
===================================================== */

.verify-input {

    padding-right:
        7px;
}


/* =====================================================
   CAPTCHA
===================================================== */

.verify-code {

    width:
        92px;

    min-width:
        92px;

    height:
        39px;

    border-radius:
        4px;

    background:
        #f1f1f1;

    border:
        1px solid
        #dddddd;

    display:
        flex;

    align-items:
        center;

    justify-content:
        center;

    color:
        #555555;

    font-size:
        17px;

    font-weight:
        700;

    letter-spacing:
        4px;

    margin-left:
        5px;

    cursor:
        pointer;

    user-select:
        none;
}


/* =====================================================
   INVITATION
===================================================== */

.invitation {

    color:
        #303030 !important;
}


/* =====================================================
   SIGN UP BUTTON
===================================================== */

.signup-btn {

    width:
        100%;

    height:
        56px;

    border:
        none;

    border-radius:
        30px;

    background:
        linear-gradient(
            100deg,
            #00855f 0%,
            #08aa82 100%
        );

    color:
        #ffffff;

    font-family:
        Arial,
        Helvetica,
        sans-serif;

    font-size:
        18px;

    font-weight:
        400;

    cursor:
        pointer;

    margin-top:
        5px;

    box-shadow:
        none;

    outline:
        none;
}


.signup-btn:active {

    transform:
        scale(.99);
}


/* =====================================================
   LOGIN AREA
===================================================== */

.login-area {

    width:
        100%;

    text-align:
        center;

    margin-top:
        30px;

    padding-bottom:
        10px;

    font-size:
        13px;

    color:
        #8a8a8a;
}


.login-link {

    color:
        #00815f;

    text-decoration:
        none;

    font-weight:
        700;

    margin-left:
        4px;
}


.login-link:active {

    opacity:
        .7;
}


/* =====================================================
   MOBILE
===================================================== */

@media (max-width: 430px) {

    .page {

        padding:
            38px
            15px
            30px;
    }


    .title {

        font-size:
            22px;

        margin:
            8px
            0
            38px;
    }


    .form-group {

        margin-bottom:
            17px;
    }


    .label {

        font-size:
            13px;

        margin-bottom:
            6px;

        margin-left:
            3px;
    }


    .input-box {

        height:
            52px;

        padding:
            0
            9px;

        border-radius:
            28px;
    }


    .icon,
    .phone-icon {

        width:
            38px;

        height:
            38px;

        min-width:
            38px;

        border-radius:
            10px;

        font-size:
            18px;

        margin-right:
            7px;
    }


    .phone-prefix {

        min-width:
            75px;

        height:
            36px;

        font-size:
            12px;

        margin-right:
            7px;
    }


    .input-box input {

        font-size:
            12px;
    }


    .eye {

        width:
            26px;

        min-width:
            26px;

        height:
            26px;

        font-size:
            18px;
    }


    .verify-code {

        width:
            86px;

        min-width:
            86px;

        height:
            36px;

        font-size:
            16px;

        letter-spacing:
            3px;
    }


    .signup-btn {

        height:
            53px;

        font-size:
            17px;

        margin-top:
            3px;
    }


    .login-area {

        margin-top:
            25px;

        font-size:
            12px;
    }

}


/* =====================================================
   VERY SMALL PHONES
===================================================== */

@media (max-width: 360px) {

    .page {

        padding-left:
            12px;

        padding-right:
            12px;

        padding-top:
            30px;
    }


    .title {

        font-size:
            20px;

        margin:
            8px
            0
            32px;
    }


    .form-group {

        margin-bottom:
            15px;
    }


    .label {

        font-size:
            12px;

        margin-bottom:
            5px;
    }


    .input-box {

        height:
            49px;

        padding-left:
            8px;

        padding-right:
            8px;
    }


    .icon,
    .phone-icon {

        width:
            36px;

        height:
            36px;

        min-width:
            36px;

        border-radius:
            9px;

        font-size:
            17px;

        margin-right:
            6px;
    }


    .phone-prefix {

        min-width:
            70px;

        height:
            34px;

        font-size:
            11px;

        margin-right:
            6px;
    }


    .input-box input {

        font-size:
            11px;
    }


    .eye {

        width:
            24px;

        min-width:
            24px;

        font-size:
            17px;
    }


    .verify-code {

        width:
            80px;

        min-width:
            80px;

        height:
            34px;

        font-size:
            15px;

        letter-spacing:
            2px;
    }


    .signup-btn {

        height:
            50px;

        font-size:
            16px;
    }

}

</style>

</head>


<body>


<div class="page">


    <!-- =================================================
         TITLE
    ================================================== -->

    <h1 class="title">
        Signup
    </h1>


    <!-- =================================================
         ERROR
    ================================================== -->

    <?php if ($error): ?>

        <div class="error-message">

            <?php
            echo htmlspecialchars(
                $error
            );
            ?>

        </div>

    <?php endif; ?>


    <!-- =================================================
         FORM
    ================================================== -->

    <form
        method="POST"
        action=""
        autocomplete="off"
        onsubmit="return validateForm();">


        <!-- =============================================
             PHONE NUMBER
        ============================================== -->

        <div class="form-group">

            <label class="label">

                Phone Number<span
                    class="required">*</span>

            </label>


            <div class="input-box">


                <div class="phone-icon">
                    ☎
                </div>


                <select
                    name="country_code"
                    class="phone-prefix">

                    <option value="+255"
                        <?php
                        echo $country_code === '+255'
                            ? 'selected'
                            : '';
                        ?>>
                        +255
                    </option>

                    

                </select>


                <input
                    type="tel"
                    name="phone"
                    id="phone"
                    value="<?php
                        echo htmlspecialchars($phone);
                    ?>"
                    placeholder="Please enter your phone number"
                    autocomplete="tel"
                    inputmode="numeric"
                    required>


            </div>

        </div>


        <!-- =============================================
             PASSWORD
        ============================================== -->

        <div class="form-group">

            <label class="label">

                Password<span
                    class="required">*</span>

            </label>


            <div class="input-box password-input">


                <div class="icon">
                    🔒
                </div>


                <input
                    type="password"
                    name="password"
                    id="password"
                    placeholder="Please enter your password"
                    autocomplete="new-password"
                    minlength="6"
                    required>


                <div
                    class="eye"
                    onclick="
                        togglePassword(
                            'password',
                            this
                        )
                    ">

                    ◉

                </div>


            </div>

        </div>


        <!-- =============================================
             CONFIRM PASSWORD
        ============================================== -->

        <div class="form-group">

            <label class="label">

                Please confirm login password<span
                    class="required">*</span>

            </label>


            <div class="input-box password-input">


                <div class="icon">
                    🔒
                </div>


                <input
                    type="password"
                    name="confirm_password"
                    id="confirmPassword"
                    placeholder="Please confirm login password"
                    autocomplete="new-password"
                    minlength="6"
                    required>


                <div
                    class="eye"
                    onclick="
                        togglePassword(
                            'confirmPassword',
                            this
                        )
                    ">

                    ◉

                </div>


            </div>

        </div>


        <!-- =============================================
             VERIFICATION CODE
        ============================================== -->

        <div class="form-group">

            <label class="label">

                Verification Code<span
                    class="required">*</span>

            </label>


            <div class="input-box verify-input">


                <div class="icon">
                    ✓
                </div>


                <input
                    type="text"
                    name="verification"
                    id="verification"
                    placeholder="Enter verification code"
                    autocomplete="off"
                    inputmode="numeric"
                    maxlength="4"
                    required>


                <div
                    class="verify-code"
                    id="captchaCode"
                    onclick="refreshCaptcha()">

                    <?php
                    echo htmlspecialchars(
                        $_SESSION['signup_captcha']
                    );
                    ?>

                </div>


            </div>

        </div>


        <!-- =============================================
             INVITATION CODE
        ============================================== -->

        <div class="form-group">

            <label class="label">

                Invitation code

            </label>


            <div class="input-box">


                <div class="icon">
                    ●
                </div>


                <input
                    class="invitation"
                    type="text"
                    name="invitation"
                    id="invitation"
                    value="<?php
                        echo htmlspecialchars(
                            $invitation
                        );
                    ?>"
                    readonly>


            </div>

        </div>


        <!-- =============================================
             SIGN UP
        ============================================== -->

        <button
            class="signup-btn"
            type="submit"
            id="signupButton">

            Sign Up

        </button>


    </form>


    <!-- =================================================
         LOGIN
    ================================================== -->

    <div class="login-area">

        <span>
            If you already have an account?
        </span>

        <a
            href="login.php"
            class="login-link">

            Login

        </a>

    </div>


</div>


<script>

/* =====================================================
   PASSWORD VISIBILITY
===================================================== */

function togglePassword(id, element) {

    const input =
        document.getElementById(id);


    if (
        input.type === "password"
    ) {

        input.type =
            "text";

        element.textContent =
            "◎";

    } else {

        input.type =
            "password";

        element.textContent =
            "◉";

    }

}


/* =====================================================
   CAPTCHA VISUAL REFRESH
===================================================== */

function refreshCaptcha() {

    /*
     * The real CAPTCHA is controlled by PHP.
     * Reloading the page generates a new
     * server-side CAPTCHA.
     */

    window.location.reload();

}


/* =====================================================
   FORM VALIDATION
===================================================== */

function validateForm() {

    const phone =
        document
        .getElementById("phone")
        .value
        .trim();


    const password =
        document
        .getElementById("password")
        .value;


    const confirmPassword =
        document
        .getElementById("confirmPassword")
        .value;


    const verification =
        document
        .getElementById("verification")
        .value
        .trim();


    if (!phone) {

        alert(
            "Please enter your phone number."
        );

        return false;

    }


    if (password.length < 6) {

        alert(
            "Password must be at least 6 characters."
        );

        return false;

    }


    if (
        password !==
        confirmPassword
    ) {

        alert(
            "Passwords do not match."
        );

        return false;

    }


    if (!verification) {

        alert(
            "Please enter the verification code."
        );

        return false;

    }


    /*
     * Prevent double submission.
     */

    const button =
        document.getElementById(
            "signupButton"
        );


    button.disabled =
        true;


    button.textContent =
        "Creating account...";


    return true;

}

</script>


</body>

</html>