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

<cfscript>
/**
 * Get Menu for Builder
 * Returns categories and items in structured format for the menu builder UI
 *
 * POST: { BusinessID: int }
 *
 * Unified schema:
 *   - Categories = Items at ParentID=0 that have menu items as children
 *   - Templates = Items at ParentID=0 that appear in ItemTemplateLinks
 *   - Menu items have ItemParentItemID pointing to their category
 *   - All items have ItemBusinessID for filtering
 */

response = { "OK": false };

try {
    // Get request body
    requestBody = toString(getHttpRequestData().content);
    requestData = {};
    if (len(requestBody)) {
        requestData = deserializeJSON(requestBody);
    }

    businessID = 0;
    if (structKeyExists(requestData, "BusinessID")) {
        businessID = val(requestData.BusinessID);
    }

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

    // Check if new schema is active (ItemBusinessID column exists and has data)
    newSchemaActive = false;
    try {
        qCheck = queryExecute("
            SELECT COUNT(*) as cnt FROM Items
            WHERE ItemBusinessID = :businessID AND ItemBusinessID > 0
        ", { businessID: businessID }, { datasource: "payfrit" });
        newSchemaActive = (qCheck.cnt > 0);
    } catch (any e) {
        newSchemaActive = false;
    }

    if (newSchemaActive) {
        // NEW SCHEMA: Check if Categories table has data for this business
        hasCategoriesData = false;
        try {
            qCatCheck = queryExecute("
                SELECT COUNT(*) as cnt FROM Categories WHERE CategoryBusinessID = :businessID
            ", { businessID: businessID }, { datasource: "payfrit" });
            hasCategoriesData = (qCatCheck.cnt > 0);
        } catch (any e) {
            hasCategoriesData = false;
        }

        if (hasCategoriesData) {
            // Use Categories table
            qCategories = queryExecute("
                SELECT
                    CategoryID,
                    CategoryName,
                    CategorySortOrder as ItemSortOrder
                FROM Categories
                WHERE CategoryBusinessID = :businessID
                ORDER BY CategorySortOrder, CategoryName
            ", { businessID: businessID }, { datasource: "payfrit" });

            // Get menu items with CategoryID
            qItems = queryExecute("
                SELECT
                    i.ItemID,
                    i.ItemCategoryID as CategoryItemID,
                    i.ItemName,
                    i.ItemDescription,
                    i.ItemPrice,
                    i.ItemSortOrder,
                    i.ItemIsActive
                FROM Items i
                WHERE i.ItemBusinessID = :businessID
                  AND i.ItemIsActive = 1
                  AND i.ItemCategoryID > 0
                  AND NOT EXISTS (
                      SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = i.ItemID
                  )
                ORDER BY i.ItemSortOrder, i.ItemName
            ", { businessID: businessID }, { datasource: "payfrit" });
        } else {
            // Fallback: Categories are Items at ParentID=0 with children (not in ItemTemplateLinks)
            qCategories = queryExecute("
                SELECT DISTINCT
                    p.ItemID as CategoryID,
                    p.ItemName as CategoryName,
                    p.ItemSortOrder
                FROM Items p
                INNER JOIN Items c ON c.ItemParentItemID = p.ItemID
                WHERE p.ItemBusinessID = :businessID
                  AND p.ItemParentItemID = 0
                  AND p.ItemIsActive = 1
                  AND NOT EXISTS (
                      SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = p.ItemID
                  )
                ORDER BY p.ItemSortOrder, p.ItemName
            ", { businessID: businessID }, { datasource: "payfrit" });

            // Get all menu items (children of category Items, not templates)
            qItems = queryExecute("
                SELECT
                    i.ItemID,
                    i.ItemParentItemID as CategoryItemID,
                    i.ItemName,
                    i.ItemDescription,
                    i.ItemPrice,
                    i.ItemSortOrder,
                    i.ItemIsActive
                FROM Items i
                INNER JOIN Items cat ON cat.ItemID = i.ItemParentItemID
                WHERE i.ItemBusinessID = :businessID
                  AND i.ItemIsActive = 1
                  AND cat.ItemParentItemID = 0
                  AND NOT EXISTS (
                      SELECT 1 FROM ItemTemplateLinks tl WHERE tl.TemplateItemID = cat.ItemID
                  )
                ORDER BY i.ItemSortOrder, i.ItemName
            ", { businessID: businessID }, { datasource: "payfrit" });
        }

    } else {
        // OLD SCHEMA: Use Categories table
        qCategories = queryExecute("
            SELECT
                CategoryID,
                CategoryName,
                0 as ItemSortOrder
            FROM Categories
            WHERE CategoryBusinessID = :businessID
            ORDER BY CategoryName
        ", { businessID: businessID }, { datasource: "payfrit" });

        qItems = queryExecute("
            SELECT
                i.ItemID,
                i.ItemCategoryID as CategoryItemID,
                i.ItemName,
                i.ItemDescription,
                i.ItemPrice,
                i.ItemSortOrder,
                i.ItemIsActive
            FROM Items i
            INNER JOIN Categories c ON c.CategoryID = i.ItemCategoryID
            WHERE c.CategoryBusinessID = :businessID
              AND i.ItemIsActive = 1
              AND i.ItemParentItemID = 0
            ORDER BY i.ItemSortOrder, i.ItemName
        ", { businessID: businessID }, { datasource: "payfrit" });
    }

    // Get template links (which templates are linked to which menu items)
    qTemplateLinks = queryExecute("
        SELECT
            tl.ItemID as ParentItemID,
            tl.TemplateItemID,
            tl.SortOrder,
            t.ItemName as TemplateName,
            t.ItemPrice as TemplatePrice,
            t.ItemIsCheckedByDefault as TemplateIsDefault
        FROM ItemTemplateLinks tl
        INNER JOIN Items t ON t.ItemID = tl.TemplateItemID
        ORDER BY tl.ItemID, tl.SortOrder
    ", {}, { datasource: "payfrit" });

    // Get all templates for this business (items that appear in ItemTemplateLinks)
    if (newSchemaActive) {
        qTemplates = queryExecute("
            SELECT DISTINCT
                t.ItemID,
                t.ItemName,
                t.ItemPrice,
                t.ItemIsCheckedByDefault as IsDefault,
                t.ItemSortOrder,
                t.ItemRequiresChildSelection as RequiresSelection,
                t.ItemMaxNumSelectionReq as MaxSelections
            FROM Items t
            INNER JOIN ItemTemplateLinks tl ON tl.TemplateItemID = t.ItemID
            INNER JOIN Items i ON i.ItemID = tl.ItemID
            WHERE i.ItemBusinessID = :businessID
              AND t.ItemIsActive = 1
            ORDER BY t.ItemSortOrder, t.ItemName
        ", { businessID: businessID }, { datasource: "payfrit" });
    } else {
        qTemplates = queryExecute("
            SELECT DISTINCT
                t.ItemID,
                t.ItemName,
                t.ItemPrice,
                t.ItemIsCheckedByDefault as IsDefault,
                t.ItemSortOrder,
                t.ItemRequiresChildSelection as RequiresSelection,
                t.ItemMaxNumSelectionReq as MaxSelections
            FROM Items t
            INNER JOIN ItemTemplateLinks tl ON tl.TemplateItemID = t.ItemID
            INNER JOIN Items i ON i.ItemID = tl.ItemID
            INNER JOIN Categories c ON c.CategoryID = i.ItemCategoryID
            WHERE c.CategoryBusinessID = :businessID
              AND t.ItemIsActive = 1
            ORDER BY t.ItemSortOrder, t.ItemName
        ", { businessID: businessID }, { datasource: "payfrit" });
    }

    // Get all children of templates (options within modifier groups)
    // Filter by business and use DISTINCT to avoid duplicates from multiple template links
    qTemplateChildren = queryExecute("
        SELECT DISTINCT
            c.ItemID,
            c.ItemParentItemID as ParentItemID,
            c.ItemName,
            c.ItemPrice,
            c.ItemIsCheckedByDefault as IsDefault,
            c.ItemSortOrder
        FROM Items c
        WHERE c.ItemParentItemID IN (
            SELECT DISTINCT t.ItemID
            FROM Items t
            INNER JOIN ItemTemplateLinks tl ON tl.TemplateItemID = t.ItemID
            INNER JOIN Items i ON i.ItemID = tl.ItemID
            WHERE i.ItemBusinessID = :businessID
        )
        AND c.ItemIsActive = 1
        ORDER BY c.ItemSortOrder, c.ItemName
    ", { businessID: businessID }, { datasource: "payfrit" });

    // Build lookup of children by template ID
    childrenByTemplate = {};
    for (child in qTemplateChildren) {
        parentID = child.ParentItemID;
        if (!structKeyExists(childrenByTemplate, parentID)) {
            childrenByTemplate[parentID] = [];
        }
        arrayAppend(childrenByTemplate[parentID], {
            "id": "opt_" & child.ItemID,
            "dbId": child.ItemID,
            "name": child.ItemName,
            "price": child.ItemPrice,
            "isDefault": child.IsDefault == 1 ? true : false,
            "sortOrder": child.ItemSortOrder,
            "options": []
        });
    }

    // Build template lookup with their children
    templatesById = {};
    for (tmpl in qTemplates) {
        templateID = tmpl.ItemID;
        children = structKeyExists(childrenByTemplate, templateID) ? childrenByTemplate[templateID] : [];
        templatesById[templateID] = {
            "id": "mod_" & tmpl.ItemID,
            "dbId": tmpl.ItemID,
            "name": tmpl.ItemName,
            "price": tmpl.ItemPrice,
            "isDefault": tmpl.IsDefault == 1 ? true : false,
            "sortOrder": tmpl.ItemSortOrder,
            "isTemplate": true,
            "requiresSelection": isNull(tmpl.RequiresSelection) ? false : (tmpl.RequiresSelection == 1),
            "maxSelections": isNull(tmpl.MaxSelections) ? 0 : tmpl.MaxSelections,
            "options": children
        };
    }

    // Build modifier lookup by parent ItemID using template links
    modifiersByItem = {};
    for (link in qTemplateLinks) {
        parentID = link.ParentItemID;
        templateID = link.TemplateItemID;

        if (!structKeyExists(modifiersByItem, parentID)) {
            modifiersByItem[parentID] = [];
        }

        if (structKeyExists(templatesById, templateID)) {
            tmpl = duplicate(templatesById[templateID]);
            tmpl["sortOrder"] = link.SortOrder;
            arrayAppend(modifiersByItem[parentID], tmpl);
        }
    }

    // Build items lookup by CategoryID
    itemsByCategory = {};
    for (item in qItems) {
        catID = item.CategoryItemID;
        if (!structKeyExists(itemsByCategory, catID)) {
            itemsByCategory[catID] = [];
        }

        itemID = item.ItemID;
        itemModifiers = structKeyExists(modifiersByItem, itemID) ? modifiersByItem[itemID] : [];

        arrayAppend(itemsByCategory[catID], {
            "id": "item_" & item.ItemID,
            "dbId": item.ItemID,
            "name": item.ItemName,
            "description": isNull(item.ItemDescription) ? "" : item.ItemDescription,
            "price": item.ItemPrice,
            "imageUrl": javaCast("null", ""),
            "photoTaskId": javaCast("null", ""),
            "modifiers": itemModifiers,
            "sortOrder": item.ItemSortOrder
        });
    }

    // Build categories array
    categories = [];
    catIndex = 0;
    for (cat in qCategories) {
        catID = cat.CategoryID;
        catItems = structKeyExists(itemsByCategory, catID) ? itemsByCategory[catID] : [];

        arrayAppend(categories, {
            "id": "cat_" & cat.CategoryID,
            "dbId": cat.CategoryID,
            "name": cat.CategoryName,
            "description": "",
            "sortOrder": catIndex,
            "items": catItems
        });
        catIndex++;
    }

    // Build template library array for the UI
    templateLibrary = [];
    for (templateID in templatesById) {
        arrayAppend(templateLibrary, templatesById[templateID]);
    }

    response["OK"] = true;
    response["MENU"] = { "categories": categories };
    response["TEMPLATES"] = templateLibrary;
    response["CATEGORY_COUNT"] = arrayLen(categories);
    response["TEMPLATE_COUNT"] = arrayLen(templateLibrary);
    response["SCHEMA"] = newSchemaActive ? "unified" : "legacy";

    totalItems = 0;
    for (cat in categories) {
        totalItems += arrayLen(cat.items);
    }
    response["ITEM_COUNT"] = totalItems;

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

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