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

<cfscript>
/**
 * Update Business Info
 *
 * POST JSON:
 * {
 *   "BusinessID": 37,
 *   "Name": "My Business",
 *   "Phone": "(555) 123-4567",
 *   "Line1": "123 Main St",
 *   "City": "Los Angeles",
 *   "State": "CA",
 *   "Zip": "90001"
 * }
 */

response = { "OK": false };

try {
    requestBody = toString(getHttpRequestData().content);
    if (!len(requestBody)) {
        throw(message="No request body provided");
    }

    data = deserializeJSON(requestBody);

    businessId = structKeyExists(data, "BusinessID") ? val(data.BusinessID) : 0;
    if (businessId == 0) {
        throw(message="BusinessID is required");
    }

    // Update business name, phone, and tax rate
    bizName = structKeyExists(data, "Name") && isSimpleValue(data.Name) ? trim(data.Name) : "";
    bizPhone = structKeyExists(data, "Phone") && isSimpleValue(data.Phone) ? trim(data.Phone) : "";

    // Handle tax rate (accept either TaxRatePercent like 8.25, or TaxRate like 0.0825)
    taxRate = "";
    if (structKeyExists(data, "TaxRatePercent") && isNumeric(data.TaxRatePercent)) {
        taxRate = data.TaxRatePercent / 100;
    } else if (structKeyExists(data, "TaxRate") && isNumeric(data.TaxRate)) {
        taxRate = data.TaxRate;
    }

    if (len(bizName)) {
        if (isNumeric(taxRate)) {
            queryExecute("
                UPDATE Businesses SET Name = :name, Phone = :phone, TaxRate = :taxRate
                WHERE ID = :id
            ", {
                name: bizName,
                phone: bizPhone,
                taxRate: { value: taxRate, cfsqltype: "cf_sql_decimal" },
                id: businessId
            }, { datasource: "payfrit" });
        } else {
            queryExecute("
                UPDATE Businesses SET Name = :name, Phone = :phone
                WHERE ID = :id
            ", {
                name: bizName,
                phone: bizPhone,
                id: businessId
            }, { datasource: "payfrit" });
        }
    }

    // Update or create address
    addressLine1 = structKeyExists(data, "Line1") && isSimpleValue(data.Line1) ? trim(data.Line1) : "";
    city = structKeyExists(data, "City") && isSimpleValue(data.City) ? trim(data.City) : "";
    state = structKeyExists(data, "State") && isSimpleValue(data.State) ? trim(data.State) : "";
    zip = structKeyExists(data, "Zip") && isSimpleValue(data.Zip) ? trim(data.Zip) : "";

    // Clean up city - remove trailing punctuation
    city = reReplace(city, "[,.\s]+$", "", "all");

    // Get state ID
    stateID = 0;
    if (len(state)) {
        qState = queryExecute("
            SELECT ID FROM tt_States WHERE Abbreviation = :abbr
        ", { abbr: uCase(state) }, { datasource: "payfrit" });
        if (qState.recordCount > 0) {
            stateID = qState.ID;
        }
    }

    // Check if business has an address
    qAddr = queryExecute("
        SELECT ID FROM Addresses
        WHERE BusinessID = :bizID AND UserID = 0 AND IsDeleted = 0
        LIMIT 1
    ", { bizID: businessId }, { datasource: "payfrit" });

    if (qAddr.recordCount > 0) {
        // Update existing address
        queryExecute("
            UPDATE Addresses SET
                Line1 = :line1,
                City = :city,
                StateID = :stateID,
                ZIPCode = :zip
            WHERE ID = :addrID
        ", {
            line1: addressLine1,
            city: city,
            stateID: stateID,
            zip: zip,
            addrID: qAddr.ID
        }, { datasource: "payfrit" });
    } else {
        // Create new address
        queryExecute("
            INSERT INTO Addresses (Line1, City, StateID, ZIPCode, BusinessID, UserID, AddressTypeID, AddedOn)
            VALUES (:line1, :city, :stateID, :zip, :bizID, 0, 2, NOW())
        ", {
            line1: addressLine1,
            city: city,
            stateID: stateID,
            zip: zip,
            bizID: businessId
        }, { datasource: "payfrit" });
    }

    response.OK = true;

} catch (any e) {
    response.ERROR = e.message;
}

writeOutput(serializeJSON(response));
</cfscript>
