<cfsetting showdebugoutput="false">
<cfsetting enablecfoutputonly="true">
<cfcontent type="application/json; charset=utf-8" reset="true">
<cfheader name="Cache-Control" value="no-store">

<cfscript>
/**
 * Send OTP to phone number for LOGIN (existing verified accounts)
 *
 * POST: { "phone": "5551234567" }
 *
 * Returns: { OK: true, UUID: "..." } or { OK: false, ERROR: "..." }
 *
 * Only works for verified accounts. Returns error if no account found.
 */

function apiAbort(required struct payload) {
    writeOutput(serializeJSON(payload));
    abort;
}

function readJsonBody() {
    var raw = getHttpRequestData().content;
    if (isNull(raw)) raw = "";
    if (!len(trim(raw))) return {};
    try {
        var data = deserializeJSON(raw);
        if (isStruct(data)) return data;
    } catch (any e) {}
    return {};
}

function normalizePhone(required string p) {
    var x = trim(arguments.p);
    x = reReplace(x, "[^0-9]", "", "all");
    if (len(x) == 11 && left(x, 1) == "1") {
        x = right(x, 10);
    }
    return x;
}

function generateOTP() {
    return randRange(100000, 999999);
}

try {
    data = readJsonBody();
    phone = structKeyExists(data, "phone") ? normalizePhone(data.phone) : "";

    if (len(phone) != 10) {
        apiAbort({ "OK": false, "ERROR": "invalid_phone", "MESSAGE": "Please enter a valid 10-digit phone number" });
    }

    // Find verified account with this phone
    qUser = queryExecute("
        SELECT UserID, UserUUID
        FROM Users
        WHERE UserContactNumber = :phone
          AND UserIsContactVerified = 1
        LIMIT 1
    ", { phone: { value: phone, cfsqltype: "cf_sql_varchar" } }, { datasource: "payfrit" });

    if (qUser.recordCount == 0) {
        apiAbort({ "OK": false, "ERROR": "no_account", "MESSAGE": "No account found with this phone number. Please sign up first." });
    }

    // Generate and save OTP
    otp = generateOTP();
    queryExecute("
        UPDATE Users
        SET UserMobileVerifyCode = :otp
        WHERE UserID = :userId
    ", {
        otp: { value: otp, cfsqltype: "cf_sql_varchar" },
        userId: { value: qUser.UserID, cfsqltype: "cf_sql_integer" }
    }, { datasource: "payfrit" });

    // Send OTP via Twilio
    smsResult = application.twilioObj.sendSMS(
        recipientNumber: "+1" & phone,
        messageBody: "Your Payfrit login code is: " & otp
    );

    writeOutput(serializeJSON({
        "OK": true,
        "UUID": qUser.UserUUID,
        "MESSAGE": smsResult.success ? "Login code sent" : "SMS failed - please try again"
    }));

} catch (any e) {
    apiAbort({
        "OK": false,
        "ERROR": "server_error",
        "MESSAGE": e.message
    });
}
</cfscript>
