<cfsetting showdebugoutput="false">
<cfsetting enablecfoutputonly="true">
<cfcontent type="application/json; charset=utf-8">

<!--- Add a new delivery address for the authenticated user --->
<cfscript>
function readJsonBody() {
    var raw = getHttpRequestData().content;
    if (isNull(raw) || len(trim(toString(raw))) == 0) return {};
    try {
        var data = deserializeJSON(toString(raw));
        return isStruct(data) ? data : {};
    } catch (any e) {
        return {};
    }
}

try {
    // Get authenticated user ID from request context (set by Application.cfm)
    userId = request.UserID ?: 0;

    if (userId <= 0) {
        writeOutput(serializeJSON({
            "OK": false,
            "ERROR": "unauthorized",
            "MESSAGE": "Authentication required"
        }));
        abort;
    }

    data = readJsonBody();

    // Required fields
    line1 = trim(data.Line1 ?: "");
    city = trim(data.City ?: "");
    stateId = val(data.StateID ?: 0);
    zipCode = trim(data.ZIPCode ?: "");

    // Optional fields
    line2 = trim(data.Line2 ?: "");
    label = trim(data.Label ?: "");
    setAsDefault = (data.SetAsDefault ?: false) == true;

    // Validation
    if (len(line1) == 0 || len(city) == 0 || stateId <= 0 || len(zipCode) == 0) {
        writeOutput(serializeJSON({
            "OK": false,
            "ERROR": "missing_fields",
            "MESSAGE": "Line1, City, StateID, and ZIPCode are required"
        }));
        abort;
    }

    // If setting as default, clear other defaults first
    if (setAsDefault) {
        queryExecute("
            UPDATE Addresses
            SET AddressIsDefaultDelivery = 0
            WHERE AddressUserID = :userId
              AND (AddressBusinessID = 0 OR AddressBusinessID IS NULL)
              AND AddressTypeID LIKE '%2%'
        ", {
            userId: { value: userId, cfsqltype: "cf_sql_integer" }
        }, { datasource: "payfrit" });
    }

    // Get next AddressID
    qNext = queryExecute("SELECT IFNULL(MAX(AddressID), 0) + 1 AS NextID FROM Addresses", {}, { datasource: "payfrit" });
    newAddressId = qNext.NextID;

    // Insert new address
    queryExecute("
        INSERT INTO Addresses (
            AddressID,
            AddressUserID,
            AddressBusinessID,
            AddressTypeID,
            AddressLabel,
            AddressIsDefaultDelivery,
            AddressLine1,
            AddressLine2,
            AddressCity,
            AddressStateID,
            AddressZIPCode,
            AddressIsDeleted,
            AddressAddedOn
        ) VALUES (
            :addressId,
            :userId,
            0,
            '2',
            :label,
            :isDefault,
            :line1,
            :line2,
            :city,
            :stateId,
            :zipCode,
            0,
            :addedOn
        )
    ", {
        addressId: { value: newAddressId, cfsqltype: "cf_sql_integer" },
        userId: { value: userId, cfsqltype: "cf_sql_integer" },
        label: { value: label, cfsqltype: "cf_sql_varchar" },
        isDefault: { value: setAsDefault ? 1 : 0, cfsqltype: "cf_sql_integer" },
        line1: { value: line1, cfsqltype: "cf_sql_varchar" },
        line2: { value: line2, cfsqltype: "cf_sql_varchar" },
        city: { value: city, cfsqltype: "cf_sql_varchar" },
        stateId: { value: stateId, cfsqltype: "cf_sql_integer" },
        zipCode: { value: zipCode, cfsqltype: "cf_sql_varchar" },
        addedOn: { value: now(), cfsqltype: "cf_sql_timestamp" }
    }, { datasource: "payfrit" });

    // Get state info for response
    qState = queryExecute("SELECT tt_StateAbbreviation as StateAbbreviation, tt_StateName as StateName FROM tt_States WHERE tt_StateID = :stateId", {
        stateId: { value: stateId, cfsqltype: "cf_sql_integer" }
    }, { datasource: "payfrit" });

    stateAbbr = qState.recordCount ? qState.StateAbbreviation : "";
    stateName = qState.recordCount ? qState.StateName : "";

    writeOutput(serializeJSON({
        "OK": true,
        "ADDRESS": {
            "AddressID": newAddressId,
            "Label": len(label) ? label : "Address",
            "IsDefault": setAsDefault,
            "Line1": line1,
            "Line2": line2,
            "City": city,
            "StateID": stateId,
            "StateAbbr": stateAbbr,
            "StateName": stateName,
            "ZIPCode": zipCode,
            "DisplayText": line1 & (len(line2) ? ", " & line2 : "") & ", " & city & ", " & stateAbbr & " " & zipCode
        }
    }));

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