<?php
/**
 * Campaign menu helpers and frontend grouping.
 *
 * @package Maca_Menu_List
 */

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Display name for a campaign (bilingual).
 *
 * @param object $campaign Campaign row.
 * @return string
 */
function maca_menulist_get_campaign_display_name($campaign) {
    if (!$campaign) {
        return '';
    }

    $local = isset($campaign->name) ? (string) $campaign->name : '';
    $english = isset($campaign->name_en) ? (string) $campaign->name_en : '';

    return maca_menulist_get_bilingual_field($local, $english);
}

/**
 * Admin list label for a campaign.
 *
 * @param object $campaign Campaign row.
 * @return string
 */
function maca_menulist_get_campaign_admin_label($campaign) {
    return maca_menulist_get_admin_content_label(
        isset($campaign->name) ? $campaign->name : '',
        isset($campaign->name_en) ? $campaign->name_en : ''
    );
}

/**
 * Whether a campaign should appear on the menu for the given context.
 *
 * @param object   $campaign    Campaign row.
 * @param bool     $qr_schedule When true, full schedule must match (QR). When false, website uses start/end date only.
 * @param int|null $timestamp   Optional Unix timestamp.
 * @return bool
 */
function maca_menulist_campaign_is_visible($campaign, $qr_schedule = false, $timestamp = null) {
    if (!$campaign || empty($campaign->is_active)) {
        return false;
    }

    if ($qr_schedule) {
        return maca_menulist_menu_matches_schedule($campaign, $timestamp);
    }

    return maca_menulist_menu_matches_website_schedule($campaign, $timestamp);
}

/**
 * Attach allergens and ratings to campaign dish lists (same as grouped categories).
 *
 * @param array<int, object> $dishes Dishes.
 * @return array<int, object>
 */
function maca_menulist_prepare_campaign_dishes($dishes) {
    if (empty($dishes)) {
        return array();
    }

    $dish_ids = array();
    foreach ($dishes as $dish) {
        $dish_ids[] = (int) $dish->id;
    }

    $allergens_by_dish = maca_menulist_db_get_allergens_for_dish_ids($dish_ids);

    foreach ($dishes as $index => $dish) {
        $dish_id = (int) $dish->id;
        $dishes[$index]->allergens = isset($allergens_by_dish[$dish_id])
            ? $allergens_by_dish[$dish_id]
            : array();
    }

    if (maca_menulist_dish_guest_ratings_enabled()) {
        $voter_key = maca_menulist_get_dish_rating_voter_key();
        $ratings_by_dish = maca_menulist_db_get_dish_rating_data_for_dish_ids($dish_ids, $voter_key);

        foreach ($dishes as $index => $dish) {
            $dish_id = (int) $dish->id;
            $rating_data = isset($ratings_by_dish[$dish_id]) ? $ratings_by_dish[$dish_id] : array(
                'average' => 0.0,
                'count' => 0,
                'user_rating' => 0,
            );
            $dishes[$index]->rating_average = (float) $rating_data['average'];
            $dishes[$index]->rating_count = (int) $rating_data['count'];
            $dishes[$index]->user_rating = (int) $rating_data['user_rating'];
        }
    }

    return $dishes;
}

/**
 * Active campaigns with visible dishes for frontend display.
 *
 * @param array<string, mixed> $args {
 *     @type bool $qr_schedule   When true, full campaign schedule applies (QR). When false, start/end date only (website).
 *     @type bool $takeaway_menu When true, takeaway availability filter applies.
 *     @type int|null $timestamp Optional preview timestamp (site timezone).
 * }
 * @return array<int, array{campaign: object, dishes: array<int, object>}>
 */
function maca_menulist_get_grouped_campaigns($args = array()) {
    $args = wp_parse_args(
        is_array($args) ? $args : array(),
        array(
            'qr_schedule' => false,
            'takeaway_menu' => false,
            'timestamp' => null,
        )
    );

    if ($args['takeaway_menu']) {
        $args['qr_schedule'] = true;
    }

    $timestamp = $args['timestamp'] !== null ? (int) $args['timestamp'] : null;

    $campaigns = maca_menulist_db_get_campaigns(true);
    $grouped = array();

    foreach ($campaigns as $campaign) {
        if (!maca_menulist_campaign_is_visible($campaign, $args['qr_schedule'], $timestamp)) {
            continue;
        }

        $dishes = maca_menulist_db_get_dishes_for_campaign((int) $campaign->id, true);
        $visible_dishes = array();

        foreach ($dishes as $dish) {
            if ($args['takeaway_menu']) {
                if (!function_exists('maca_menulist_dish_is_available_for_takeaway') || !maca_menulist_dish_is_available_for_takeaway($dish)) {
                    continue;
                }
            } elseif ($args['qr_schedule']) {
                if (!maca_menulist_dish_is_visible_on_qr($dish, $timestamp)) {
                    continue;
                }
            } elseif (!maca_menulist_dish_is_visible_on_website($dish)) {
                continue;
            }

            $visible_dishes[] = $dish;
        }

        if (empty($visible_dishes)) {
            continue;
        }

        $grouped[] = array(
            'campaign' => $campaign,
            'dishes' => maca_menulist_prepare_campaign_dishes($visible_dishes),
        );
    }

    return $grouped;
}

/**
 * First visible campaign for current context.
 *
 * @param array<string, mixed> $args Campaign grouping args.
 * @return object|null
 */
function maca_menulist_get_primary_active_campaign($args = array()) {
    $grouped = maca_menulist_get_grouped_campaigns($args);
    if (empty($grouped) || empty($grouped[0]['campaign'])) {
        return null;
    }

    return $grouped[0]['campaign'];
}

/**
 * Active campaign title for menu headings, if any.
 *
 * @param array<string, mixed> $args Campaign grouping args.
 * @return string
 */
function maca_menulist_get_active_campaign_menu_title($args = array()) {
    $campaign = maca_menulist_get_primary_active_campaign($args);
    if (!$campaign) {
        return '';
    }

    return maca_menulist_get_campaign_display_name($campaign);
}

/**
 * Admin status label for a campaign schedule.
 *
 * @param object $campaign Campaign row.
 * @return string
 */
function maca_menulist_get_campaign_status($campaign) {
    return maca_menulist_get_menu_status($campaign);
}
