<?php
/**
 * Shared Audience Picker (Phase 3).
 *
 * Reusable selector used by Notes, Announcements and Email Students. Pick
 * one audience type per item and resolve to a flat list of student IDs.
 *
 * Audience types:
 *   - all          -> every active student
 *   - year         -> all active students in a school year
 *   - program      -> all active students enrolled in a program
 *   - class        -> all students enrolled in a class
 *   - workshop     -> all students enrolled in a workshop instance
 *   - specific     -> checkbox multi-select from a searchable student table
 *
 * @package TradeSchoolManager
 */

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

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared

class TSMP_Audience {

	/* ---------- Resolver ---------- */

	/**
	 * Resolve a posted audience selection into a deduped list of student rows.
	 *
	 * @param string $type      one of: all|year|program|class|workshop|specific
	 * @param mixed  $value     scalar id for year/program/class/workshop, array of ids for specific
	 * @return array<int,object> student rows (id, first_name, last_name, email, ...)
	 */
	public static function resolve_students( $type, $value ) {
		$type = sanitize_key( $type );
		$out  = array();
		$seen = array();
		$push = function( $s ) use ( &$out, &$seen ) {
			if ( $s && isset( $s->id ) && ! isset( $seen[ (int) $s->id ] ) ) {
				$seen[ (int) $s->id ] = true;
				$out[]                = $s;
			}
		};

		switch ( $type ) {
			case 'all':
				foreach ( TSM_Students::active() as $s ) { $push( $s ); }
				break;
			case 'year':
				foreach ( TSM_Students::active( absint( $value ) ) as $s ) { $push( $s ); }
				break;
			case 'program':
				global $wpdb;
				$pen = $wpdb->prefix . 'tsm_program_enrollments';
				// phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- Plugin-owned table name only.
				$ids = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT student_id FROM {$pen} WHERE program_id = %d", absint( $value ) ) );
				foreach ( $ids as $sid ) { $push( TSM_Students::get( (int) $sid ) ); }
				break;
			case 'class':
				if ( class_exists( 'TSM_Classes' ) ) {
					foreach ( TSM_Classes::students_in_class( absint( $value ) ) as $s ) { $push( $s ); }
				}
				break;
			case 'workshop':
				if ( class_exists( 'TSM_Workshops' ) && method_exists( 'TSM_Workshops', 'roster' ) ) {
					foreach ( TSM_Workshops::roster( absint( $value ) ) as $s ) { $push( $s ); }
				}
				break;
			case 'specific':
				$ids = is_array( $value ) ? array_map( 'absint', $value ) : array();
				foreach ( $ids as $sid ) { $push( TSM_Students::get( $sid ) ); }
				break;
		}
		return $out;
	}

	/**
	 * Extract (type, value) from a posted $_POST array using $field as the
	 * prefix (e.g. "audience"). Returns array( type, value ).
	 */
	public static function parse_post( $post, $field = 'audience' ) {
		$type  = isset( $post[ $field . '_type' ] ) ? sanitize_key( $post[ $field . '_type' ] ) : 'all';
		$value = null;
		switch ( $type ) {
			case 'year':     $value = absint( $post[ $field . '_year' ]     ?? 0 ); break;
			case 'program':  $value = absint( $post[ $field . '_program' ]  ?? 0 ); break;
			case 'class':    $value = absint( $post[ $field . '_class' ]    ?? 0 ); break;
			case 'workshop': $value = absint( $post[ $field . '_workshop' ] ?? 0 ); break;
			case 'specific':
				$ids = isset( $post[ $field . '_students' ] ) ? (array) $post[ $field . '_students' ] : array();
				$value = array_map( 'absint', $ids );
				break;
		}
		return array( $type, $value );
	}

	/**
	 * Human readable label for a saved audience selection.
	 */
	public static function label( $type, $value ) {
		switch ( $type ) {
			case 'all':      return __( 'All active students', 'tradeschool-manager' );
			case 'year':
				$y = class_exists( 'TSM_School_Years' ) ? TSM_School_Years::get( (int) $value ) : null;
				/* translators: %s: school year name. */
				return $y ? sprintf( __( 'Year: %s', 'tradeschool-manager' ), $y->name ) : __( 'Year', 'tradeschool-manager' );
			case 'program':
				$p = class_exists( 'TSM_Programs' ) ? TSM_Programs::get( (int) $value ) : null;
				/* translators: %s: program name. */
				return $p ? sprintf( __( 'Program: %s', 'tradeschool-manager' ), $p->name ) : __( 'Program', 'tradeschool-manager' );
			case 'class':
				$c = class_exists( 'TSM_Classes' ) ? TSM_Classes::get( (int) $value ) : null;
				/* translators: %s: class name. */
				return $c ? sprintf( __( 'Class: %s', 'tradeschool-manager' ), $c->name ) : __( 'Class', 'tradeschool-manager' );
			case 'workshop':
				return __( 'Workshop instance', 'tradeschool-manager' );
			case 'specific':
				$n = is_array( $value ) ? count( $value ) : 0;
				/* translators: %d: number of selected students. */
				return sprintf( _n( '%d selected student', '%d selected students', $n, 'tradeschool-manager' ), $n );
		}
		return '';
	}

	/* ---------- Renderer ---------- */

	/**
	 * Render the audience picker UI. All inputs are prefixed by $field.
	 *
	 * @param string $field   prefix for posted field names (e.g. "audience")
	 * @param array  $current array( 'type' => string, 'value' => mixed )
	 * @param array  $opts    array( 'include' => list of allowed types )
	 */
	public static function render( $field = 'audience', $current = array(), $opts = array() ) {
		$current = wp_parse_args( $current, array( 'type' => 'all', 'value' => null ) );
		$include = $opts['include'] ?? array( 'all', 'year', 'program', 'class', 'workshop', 'specific' );

		$years     = class_exists( 'TSM_School_Years' ) ? TSM_School_Years::all() : array();
		$programs  = class_exists( 'TSM_Programs' )     ? TSM_Programs::all()     : array();
		$active_yr = class_exists( 'TSM_Active_Year' )  ? (int) TSM_Active_Year::get() : 0;
		$classes   = class_exists( 'TSM_Classes' )      ? TSM_Classes::all( $active_yr ) : array();
		$workshops = ( class_exists( 'TSM_Workshops' ) && method_exists( 'TSM_Workshops', 'all_instances' ) ) ? TSM_Workshops::all_instances() : array();
		$students  = TSM_Students::active();

		$type    = $current['type'];
		$current_specific = is_array( $current['value'] ) ? array_map( 'intval', $current['value'] ) : array();

		$labels = array(
			'all'      => __( 'All active students',  'tradeschool-manager' ),
			'year'     => __( 'School year',          'tradeschool-manager' ),
			'program'  => __( 'Program',              'tradeschool-manager' ),
			'class'    => __( 'Class',                'tradeschool-manager' ),
			'workshop' => __( 'Workshop instance',    'tradeschool-manager' ),
			'specific' => __( 'Specific students',    'tradeschool-manager' ),
		);

		$uid = 'tsmaud_' . wp_generate_password( 6, false, false );
		TSM_Inline_Assets::style(
			'tsm-audience-picker',
			'.tsm-aud{background:#fff;border:1px solid #dcdcde;border-radius:8px;padding:14px;}.tsm-aud-types{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px;}.tsm-aud-types label{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid #dcdcde;border-radius:999px;background:#f6f7f7;cursor:pointer;font-size:13px;}.tsm-aud-types input{margin:0;}.tsm-aud-types label.is-on{background:#2271b1;color:#fff;border-color:#2271b1;}.tsm-aud-panel{display:none;padding:10px 0 0;}.tsm-aud-panel.is-on{display:block;}.tsm-aud-tbl{border:1px solid #dcdcde;border-radius:6px;background:#fff;}.tsm-aud-tbl-head{padding:8px;border-bottom:1px solid #dcdcde;background:#f6f7f7;display:flex;gap:8px;align-items:center;flex-wrap:wrap;}.tsm-aud-tbl-head input[type=search]{flex:1;min-width:180px;}.tsm-aud-tbl-body{max-height:340px;overflow:auto;}.tsm-aud-tbl table{width:100%;border-collapse:collapse;}.tsm-aud-tbl th,.tsm-aud-tbl td{text-align:left;padding:6px 10px;border-bottom:1px solid #f0f0f1;font-size:13px;}.tsm-aud-tbl th{position:sticky;top:0;background:#f6f7f7;}.tsm-aud-count{font-size:12px;color:#646970;margin-left:auto;}'
		);
		TSM_Inline_Assets::script(
			'tsm-audience-picker-' . $uid,
			'(function(){
				var root=document.getElementById(' . wp_json_encode( $uid ) . ');
				if(!root) return;
				function show(){
					var t=root.querySelector(\'input[name$="_type"]:checked\');
					if(!t) return;
					root.querySelectorAll(\'.tsm-aud-types label\').forEach(function(l){l.classList.remove(\'is-on\');});
					if(t.parentNode) t.parentNode.classList.add(\'is-on\');
					root.querySelectorAll(\'.tsm-aud-panel\').forEach(function(p){p.classList.toggle(\'is-on\', p.getAttribute(\'data-for\')===t.value);});
				}
				root.querySelectorAll(\'input[name$="_type"]\').forEach(function(r){r.addEventListener(\'change\', show);});
				show();
				var q=root.querySelector(\'[data-aud-search]\');
				var rows=root.querySelectorAll(\'[data-aud-row]\');
				var cnt=root.querySelector(\'[data-aud-count]\');
				function recount(){
					var n=0; root.querySelectorAll(\'[data-aud-cb]:checked\').forEach(function(){n++;});
					if(cnt) cnt.textContent = n+\' selected\';
				}
				if(q){ q.addEventListener(\'input\', function(){
					var v=q.value.toLowerCase();
					rows.forEach(function(r){r.style.display = r.getAttribute(\'data-h\').indexOf(v)>-1 ? \'\' : \'none\';});
				}); }
				var ba=root.querySelector(\'[data-aud-all]\'); if(ba) ba.addEventListener(\'click\', function(){
					rows.forEach(function(r){ if(r.style.display!==\'none\'){ var cb=r.querySelector(\'[data-aud-cb]\'); if(cb){ cb.checked=true; } } });
					recount();
				});
				var bn=root.querySelector(\'[data-aud-none]\'); if(bn) bn.addEventListener(\'click\', function(){
					root.querySelectorAll(\'[data-aud-cb]\').forEach(function(cb){cb.checked=false;}); recount();
				});
				root.querySelectorAll(\'[data-aud-cb]\').forEach(function(cb){cb.addEventListener(\'change\', recount);});
				recount();
			})();'
		);
		?>
		<div class="tsm-aud" id="<?php echo esc_attr( $uid ); ?>" data-field="<?php echo esc_attr( $field ); ?>">
			<div class="tsm-aud-types">
				<?php foreach ( $include as $t ) : ?>
					<label class="<?php echo $type===$t ? 'is-on' : ''; ?>">
						<input type="radio" name="<?php echo esc_attr( $field ); ?>_type" value="<?php echo esc_attr( $t ); ?>" <?php checked( $type, $t ); ?>>
						<?php echo esc_html( $labels[ $t ] ); ?>
					</label>
				<?php endforeach; ?>
			</div>

			<?php if ( in_array( 'year', $include, true ) ) : ?>
			<div class="tsm-aud-panel" data-for="year">
				<select name="<?php echo esc_attr( $field ); ?>_year">
					<?php foreach ( $years as $y ) : ?>
						<option value="<?php echo (int) $y->id; ?>" <?php selected( $type==='year' ? (int) $current['value'] : $active_yr, $y->id ); ?>><?php echo esc_html( $y->name ); ?></option>
					<?php endforeach; ?>
				</select>
			</div>
			<?php endif; ?>

			<?php if ( in_array( 'program', $include, true ) ) : ?>
			<div class="tsm-aud-panel" data-for="program">
				<select name="<?php echo esc_attr( $field ); ?>_program">
					<option value="0"> - </option>
					<?php foreach ( $programs as $p ) : ?>
						<option value="<?php echo (int) $p->id; ?>" <?php selected( $type==='program' ? (int) $current['value'] : 0, $p->id ); ?>><?php echo esc_html( $p->name ); ?></option>
					<?php endforeach; ?>
				</select>
			</div>
			<?php endif; ?>

			<?php if ( in_array( 'class', $include, true ) ) : ?>
			<div class="tsm-aud-panel" data-for="class">
				<select name="<?php echo esc_attr( $field ); ?>_class">
					<option value="0"> - </option>
					<?php foreach ( $classes as $c ) : ?>
						<option value="<?php echo (int) $c->id; ?>" <?php selected( $type==='class' ? (int) $current['value'] : 0, $c->id ); ?>><?php echo esc_html( $c->name ); ?></option>
					<?php endforeach; ?>
				</select>
				<p class="description" style="margin:6px 0 0;font-size:12px;"><?php esc_html_e( 'Classes shown belong to the active school year (use the topbar switcher to change years).', 'tradeschool-manager' ); ?></p>
			</div>
			<?php endif; ?>

			<?php if ( in_array( 'workshop', $include, true ) ) : ?>
			<div class="tsm-aud-panel" data-for="workshop">
				<select name="<?php echo esc_attr( $field ); ?>_workshop">
					<option value="0"> - </option>
					<?php foreach ( $workshops as $w ) :
						$wname  = $w->workshop_name ?? ( $w->label ?? '' );
						$wlabel = trim( $wname . '  -  ' . ( $w->start_date ?? '' ), '  - ' ); ?>
						<option value="<?php echo (int) $w->id; ?>" <?php selected( $type==='workshop' ? (int) $current['value'] : 0, $w->id ); ?>><?php echo esc_html( $wlabel ); ?></option>
					<?php endforeach; ?>
				</select>
			</div>
			<?php endif; ?>

			<?php if ( in_array( 'specific', $include, true ) ) : ?>
			<div class="tsm-aud-panel" data-for="specific">
				<div class="tsm-aud-tbl">
					<div class="tsm-aud-tbl-head">
						<input type="search" placeholder="<?php esc_attr_e( 'Search by name, email, or ID...', 'tradeschool-manager' ); ?>" data-aud-search>
						<button type="button" class="button button-small" data-aud-all><?php esc_html_e( 'Select all', 'tradeschool-manager' ); ?></button>
						<button type="button" class="button button-small" data-aud-none><?php esc_html_e( 'Clear', 'tradeschool-manager' ); ?></button>
						<span class="tsm-aud-count" data-aud-count></span>
					</div>
					<div class="tsm-aud-tbl-body">
						<table>
							<thead><tr>
								<th style="width:32px;"></th>
								<th><?php esc_html_e( 'ID', 'tradeschool-manager' ); ?></th>
								<th><?php esc_html_e( 'Name', 'tradeschool-manager' ); ?></th>
								<th><?php esc_html_e( 'Email', 'tradeschool-manager' ); ?></th>
								<th><?php esc_html_e( 'Status', 'tradeschool-manager' ); ?></th>
							</tr></thead>
							<tbody>
								<?php foreach ( $students as $s ) :
									$haystack = strtolower( $s->first_name . ' ' . $s->last_name . ' ' . $s->email . ' ' . $s->id ); ?>
									<tr data-aud-row data-h="<?php echo esc_attr( $haystack ); ?>">
										<td><input type="checkbox" name="<?php echo esc_attr( $field ); ?>_students[]" value="<?php echo (int) $s->id; ?>" <?php checked( in_array( (int) $s->id, $current_specific, true ) ); ?> data-aud-cb></td>
										<td><?php echo (int) $s->id; ?></td>
										<td><?php echo esc_html( $s->last_name . ', ' . $s->first_name ); ?></td>
										<td><?php echo esc_html( $s->email ); ?></td>
										<td><?php echo esc_html( $s->status ?? '' ); ?></td>
									</tr>
								<?php endforeach; ?>
							</tbody>
						</table>
					</div>
				</div>
			</div>
			<?php endif; ?>
		</div>
		<?php
	}
}
