<cfsetting showdebugoutput="false">
<cfsetting enablecfoutputonly="true">

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

<cfscript>
/**
 * Get Business Details
 * POST: { BusinessID: int }
 * Returns: { OK: true, BUSINESS: {...} } or { OK: false, ERROR: string }
 */

response = { "OK": false };

try {
    // Get request data
    requestBody = toString(getHttpRequestData().content);

    if (len(requestBody) == 0) {
        response["ERROR"] = "Request body is required";
        writeOutput(serializeJSON(response));
        abort;
    }

    requestData = deserializeJSON(requestBody);
    businessID = val(requestData.BusinessID ?: 0);

    if (businessID == 0) {
        response["ERROR"] = "BusinessID is required";
        writeOutput(serializeJSON(response));
        abort;
    }

    // Get business details
    q = queryTimed("
        SELECT
            ID,
            Name,
            Phone,
            StripeAccountID,
            StripeOnboardingComplete,
            IsHiring,
            HeaderImageExtension,
            TaxRate,
            BrandColor,
            SessionEnabled,
            SessionLockMinutes,
            SessionPaymentStrategy
        FROM Businesses
        WHERE ID = :businessID
    ", { businessID: businessID }, { datasource: "payfrit" });

    if (q.recordCount == 0) {
        response["ERROR"] = "Business not found";
        writeOutput(serializeJSON(response));
        abort;
    }

    // Get address from Addresses table (either linked via AddressBusinessID or via Businesses.BusinessAddressID)
    qAddr = queryTimed("
        SELECT a.Line1 AS AddressLine1, a.Line2 AS AddressLine2, a.City AS AddressCity, a.ZIPCode AS AddressZIPCode, s.Abbreviation
        FROM Addresses a
        LEFT JOIN tt_States s ON s.ID = a.StateID
        WHERE (a.BusinessID = :businessID OR a.ID = (SELECT AddressID FROM Businesses WHERE ID = :businessID))
          AND a.IsDeleted = 0
        LIMIT 1
    ", { businessID: businessID }, { datasource: "payfrit" });

    addressStr = "";
    addressLine1 = "";
    addressCity = "";
    addressState = "";
    addressZip = "";
    if (qAddr.recordCount > 0) {
        addressLine1 = qAddr.AddressLine1;
        addressCity = qAddr.AddressCity;
        addressState = qAddr.Abbreviation;
        addressZip = qAddr.AddressZIPCode;

        addressParts = [];
        if (len(qAddr.AddressLine1)) arrayAppend(addressParts, qAddr.AddressLine1);
        if (len(qAddr.AddressLine2)) arrayAppend(addressParts, qAddr.AddressLine2);
        cityStateZip = [];
        if (len(qAddr.AddressCity)) arrayAppend(cityStateZip, qAddr.AddressCity);
        if (len(qAddr.Abbreviation)) arrayAppend(cityStateZip, qAddr.Abbreviation);
        if (len(qAddr.AddressZIPCode)) arrayAppend(cityStateZip, qAddr.AddressZIPCode);
        if (arrayLen(cityStateZip) > 0) arrayAppend(addressParts, arrayToList(cityStateZip, ", "));
        addressStr = arrayToList(addressParts, ", ");
    }

    // Get hours from Hours table
    qHours = queryTimed("
        SELECT h.DayID, h.OpenTime, h.ClosingTime, d.Abbrev
        FROM Hours h
        JOIN tt_Days d ON d.ID = h.DayID
        WHERE h.BusinessID = :businessID
        ORDER BY h.DayID
    ", { businessID: businessID }, { datasource: "payfrit" });

    hoursArr = [];
    hoursStr = "";
    if (qHours.recordCount > 0) {
        for (h in qHours) {
            arrayAppend(hoursArr, {
                "day": h.Abbrev,
                "dayId": h.DayID,
                "open": timeFormat(h.OpenTime, "h:mm tt"),
                "close": timeFormat(h.ClosingTime, "h:mm tt")
            });
        }
        // Build readable hours string (group similar days)
        hourGroups = {};
        for (h in hoursArr) {
            key = h.open & "-" & h.close;
            if (!structKeyExists(hourGroups, key)) {
                hourGroups[key] = [];
            }
            arrayAppend(hourGroups[key], h.day);
        }
        hourStrParts = [];
        for (key in hourGroups) {
            days = hourGroups[key];
            arrayAppend(hourStrParts, arrayToList(days, ",") & ": " & key);
        }
        hoursStr = arrayToList(hourStrParts, ", ");
    }

    // Build business object
    taxRate = isNumeric(q.TaxRate) ? q.TaxRate : 0;
    business = {
        "BusinessID": q.ID,
        "Name": q.Name,
        "Address": addressStr,
        "Line1": addressLine1,
        "City": addressCity,
        "AddressState": addressState,
        "AddressZip": addressZip,
        "Phone": q.Phone,
        "Hours": hoursStr,
        "HoursDetail": hoursArr,
        "StripeConnected": (len(q.StripeAccountID) > 0 && q.StripeOnboardingComplete == 1),
        "IsHiring": q.IsHiring == 1,
        "TaxRate": taxRate,
        "TaxRatePercent": taxRate * 100,
        "BrandColor": len(q.BrandColor) ? (left(q.BrandColor, 1) == chr(35) ? q.BrandColor : chr(35) & q.BrandColor) : "",
        "SessionEnabled": isNumeric(q.SessionEnabled) ? q.SessionEnabled : 0,
        "SessionLockMinutes": isNumeric(q.SessionLockMinutes) ? q.SessionLockMinutes : 30,
        "SessionPaymentStrategy": len(q.SessionPaymentStrategy) ? q.SessionPaymentStrategy : "A"
    };

    // Add header image URL if extension exists
    if (len(q.HeaderImageExtension)) {
        business["HeaderImageURL"] = "/uploads/headers/" & q.ID & "." & q.HeaderImageExtension;
    }

    response["OK"] = true;
    response["BUSINESS"] = business;

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

try{logPerf(0);}catch(any e){}
writeOutput(serializeJSON(response));
</cfscript>
