<?php
/**
 * Sponsor tier data layer.
 *
 * Tier terms are created by editors in Sponsors > Tiers. Display settings
 * live in term meta, so a newly added tier works with sensible defaults and
 * its settings are removed with the term.
 *
 * @package Kadence-Child
 */

defined( 'ABSPATH' ) || exit;

const PV_TIER_TAXONOMY       = 'tier';
const PV_TIER_META_ORDER     = 'pv_tier_order';
const PV_TIER_META_HEADING   = 'pv_tier_heading';
const PV_TIER_META_HIDDEN    = 'pv_tier_hidden';

// Logos per row follow the visible tier order: the first tier gets the
// biggest logos, the second a little smaller, every tier after that 4.
const PV_TIER_COLUMNS_BY_RANK = array( 2, 3 );
const PV_TIER_DEFAULT_COLUMNS = 4;

/**
 * Heading used when a tier has no custom heading, e.g. "Gold Sponsors".
 */
function pv_default_tier_heading( $tier_name ) {
    /* translators: %s: tier name, e.g. Gold */
    return sprintf( __( '%s Sponsors', 'kadence-child' ), $tier_name );
}

/**
 * Display settings for one tier, with defaults applied.
 *
 * @return array{order:int|null, heading:string, heading_custom:string, hidden:bool}
 */
function pv_get_tier_settings( WP_Term $term ) {
    $order   = get_term_meta( $term->term_id, PV_TIER_META_ORDER, true );
    $heading = (string) get_term_meta( $term->term_id, PV_TIER_META_HEADING, true );

    return array(
        'order'          => '' === $order ? null : (int) $order,
        'heading'        => '' !== $heading ? $heading : pv_default_tier_heading( $term->name ),
        'heading_custom' => $heading,
        'hidden'         => '1' === get_term_meta( $term->term_id, PV_TIER_META_HIDDEN, true ),
    );
}

/**
 * All tier terms in display order. Tiers never ordered in Sponsor Settings
 * (e.g. just created) sort after ordered ones, alphabetically.
 *
 * @return WP_Term[]
 */
function pv_get_sponsor_tiers() {
    $terms = get_terms( array(
        'taxonomy'   => PV_TIER_TAXONOMY,
        'hide_empty' => false,
    ) );
    if ( is_wp_error( $terms ) ) {
        return array();
    }

    usort( $terms, function ( $a, $b ) {
        $oa = get_term_meta( $a->term_id, PV_TIER_META_ORDER, true );
        $ob = get_term_meta( $b->term_id, PV_TIER_META_ORDER, true );
        $oa = '' === $oa ? PHP_INT_MAX : (int) $oa;
        $ob = '' === $ob ? PHP_INT_MAX : (int) $ob;
        return ( $oa <=> $ob ) ?: strcasecmp( $a->name, $b->name );
    } );

    return $terms;
}

/**
 * Save display settings for all tiers. $ordered_ids defines the order.
 *
 * @param int[] $ordered_ids Tier term IDs in display order.
 * @param array $settings    term_id => array( heading, hidden ).
 */
function pv_save_tier_settings( array $ordered_ids, array $settings ) {
    $position = 0;
    foreach ( $ordered_ids as $term_id ) {
        $term = get_term( (int) $term_id, PV_TIER_TAXONOMY );
        if ( ! $term instanceof WP_Term ) {
            continue;
        }
        $row     = isset( $settings[ $term->term_id ] ) ? (array) $settings[ $term->term_id ] : array();
        $heading = isset( $row['heading'] ) ? sanitize_text_field( wp_unslash( $row['heading'] ) ) : '';

        update_term_meta( $term->term_id, PV_TIER_META_ORDER, $position++ );
        update_term_meta( $term->term_id, PV_TIER_META_HEADING, $heading );
        update_term_meta( $term->term_id, PV_TIER_META_HIDDEN, empty( $row['hidden'] ) ? '0' : '1' );
    }
}

/**
 * Published posts of a partner post type, ordered by menu order
 * (Simple Custom Post Order drag order), optionally limited to a year.
 *
 * @param string $post_type sponsor|organizer.
 * @param string $year      speaker-year term slug, '' for all years.
 * @return WP_Post[]
 */
function pv_get_partner_posts( $post_type, $year = '' ) {
    $args = array(
        'post_type'      => $post_type,
        'post_status'    => 'publish',
        'posts_per_page' => -1,
        'orderby'        => array( 'menu_order' => 'ASC', 'title' => 'ASC' ),
        'no_found_rows'  => true,
    );
    if ( '' !== $year ) {
        $args['tax_query'] = array( array(
            'taxonomy' => 'speaker-year',
            'field'    => 'slug',
            'terms'    => $year,
        ) );
    }
    return get_posts( $args );
}

/**
 * Sponsors grouped by visible tier, in tier display order. Empty tiers are
 * omitted. A sponsor in several tiers appears in each.
 *
 * @param string $year speaker-year term slug, '' for all years.
 * @return array<int, array{term:WP_Term, settings:array, columns:int, posts:WP_Post[]}>
 */
function pv_get_sponsors_by_tier( $year = '' ) {
    $sponsors = pv_get_partner_posts( 'sponsor', $year );
    $groups   = array();

    foreach ( pv_get_sponsor_tiers() as $term ) {
        $settings = pv_get_tier_settings( $term );
        if ( $settings['hidden'] ) {
            continue;
        }
        $posts = array_values( array_filter( $sponsors, function ( $post ) use ( $term ) {
            return has_term( $term->term_id, PV_TIER_TAXONOMY, $post );
        } ) );
        if ( $posts ) {
            $rank     = count( $groups );
            $groups[] = array(
                'term'     => $term,
                'settings' => $settings,
                'columns'  => isset( PV_TIER_COLUMNS_BY_RANK[ $rank ] ) ? PV_TIER_COLUMNS_BY_RANK[ $rank ] : PV_TIER_DEFAULT_COLUMNS,
                'posts'    => $posts,
            );
        }
    }

    return $groups;
}
