<?php
/**
 * Portal Announcements (v1.19.53)
 *
 * Lightweight CRUD + admin UI for school-wide announcements that appear
 * on the student portal. Each announcement has a title, body, optional
 * end date, active flag, and an audience (all / year / program / class /
 * workshop / specific students).
 *
 * @package TradeSchoolManager
 */

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

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Plugin-owned custom tables; table names interpolated only; user values always pass through $wpdb->prepare().

class TSM_Announcements {

	/* ---------- Schema ---------- */

	public static function table() {
		global $wpdb;
		return $wpdb->prefix . 'tsm_announcements';
	}

	public static function install_schema() {
		global $wpdb;
		require_once ABSPATH . 'wp-admin/includes/upgrade.php';
		$charset = $wpdb->get_charset_collate();
		$t       = self::table();
		$sql = "CREATE TABLE {$t} (
			id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
			title VARCHAR(190) NOT NULL,
			body LONGTEXT NULL,
			end_date DATE NULL,
			active TINYINT(1) NOT NULL DEFAULT 1,
			audience_type VARCHAR(20) NOT NULL DEFAULT 'all',
			audience_value LONGTEXT NULL,
			created_by BIGINT UNSIGNED NULL,
			created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
			PRIMARY KEY (id),
			KEY active (active),
			KEY end_date (end_date),
			KEY audience_type (audience_type)
		) {$charset};";
		dbDelta( $sql );
	}

	/* ---------- CRUD ---------- */

	public static function all() {
		global $wpdb;
		$t = self::table();
		return $wpdb->get_results( "SELECT * FROM {$t} ORDER BY created_at DESC" );
	}

	public static function get( $id ) {
		global $wpdb;
		$t = self::table();
		return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$t} WHERE id = %d", absint( $id ) ) );
	}

	/**
	 * Returns active, in-window announcements.
	 *
	 * @param int $student_id  When provided, only returns announcements whose
	 *                         audience targets this student. When 0, returns all
	 *                         active rows (admin/teacher preview).
	 */
	public static function active( $student_id = 0 ) {
		global $wpdb;
		$t     = self::table();
		$today = current_time( 'Y-m-d' );
		$rows  = $wpdb->get_results( $wpdb->prepare(
			"SELECT * FROM {$t}
			 WHERE active = 1
			   AND ( end_date IS NULL OR end_date >= %s )
			 ORDER BY created_at DESC",
			$today
		) );
		if ( ! $student_id ) {
			return $rows;
		}
		$sid = (int) $student_id;
		$out = array();
		foreach ( $rows as $r ) {
			if ( self::row_targets_student( $r, $sid ) ) { $out[] = $r; }
		}
		return $out;
	}

	public static function for_class( $class_id ) {
		global $wpdb;
		$t = self::table();
		return $wpdb->get_results( $wpdb->prepare(
			"SELECT * FROM {$t}
			 WHERE audience_type = 'class'
			   AND audience_value = %s
			 ORDER BY created_at DESC",
			(string) absint( $class_id )
		) );
	}

	protected static function row_targets_student( $r, $sid ) {
		$type  = $r->audience_type ?: 'all';
		$value = $r->audience_value;
		if ( 'all' === $type ) { return true; }
		if ( 'specific' === $type ) {
			$ids = json_decode( $value ?: '[]', true );
			return is_array( $ids ) && in_array( $sid, array_map( 'intval', $ids ), true );
		}
		$target = TSMP_Audience::resolve_students( $type, ( 'year' === $type || 'program' === $type || 'class' === $type || 'workshop' === $type ) ? (int) $value : $value );
		foreach ( $target as $s ) { if ( (int) $s->id === $sid ) { return true; } }
		return false;
	}

	public static function save( $data, $id = 0 ) {
		global $wpdb;
		list( $atype, $aval ) = TSMP_Audience::parse_post( $data, 'audience' );
		$record = array(
			'title'          => sanitize_text_field( $data['title'] ?? '' ),
			'body'           => wp_kses_post( $data['body'] ?? '' ),
			'end_date'       => ! empty( $data['end_date'] ) ? sanitize_text_field( $data['end_date'] ) : null,
			'active'         => ! empty( $data['active'] ) ? 1 : 0,
			'audience_type'  => $atype,
			'audience_value' => is_array( $aval ) ? wp_json_encode( $aval ) : ( null === $aval ? null : (string) $aval ),
		);
		if ( $id ) {
			$wpdb->update( self::table(), $record, array( 'id' => absint( $id ) ) );
			return absint( $id );
		}
		$record['created_by'] = get_current_user_id();
		$wpdb->insert( self::table(), $record );
		return (int) $wpdb->insert_id;
	}

	public static function save_for_class( $class_id, $data, $id = 0 ) {
		global $wpdb;
		$class_id = absint( $class_id );
		$record   = array(
			'title'          => sanitize_text_field( $data['title'] ?? '' ),
			'body'           => wp_kses_post( $data['body'] ?? '' ),
			'end_date'       => ! empty( $data['end_date'] ) ? sanitize_text_field( $data['end_date'] ) : null,
			'active'         => ! empty( $data['active'] ) ? 1 : 0,
			'audience_type'  => 'class',
			'audience_value' => (string) $class_id,
		);
		if ( $id ) {
			$wpdb->update( self::table(), $record, array( 'id' => absint( $id ) ) );
			return absint( $id );
		}
		$record['created_by'] = get_current_user_id();
		$wpdb->insert( self::table(), $record );
		return (int) $wpdb->insert_id;
	}

	public static function delete( $id ) {
		global $wpdb;
		$wpdb->delete( self::table(), array( 'id' => absint( $id ) ) );
	}

	/* ---------- Admin UI ---------- */

	public static function render_admin() {
		self::install_schema();

		if ( isset( $_POST['tsm_ann_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['tsm_ann_nonce'] ) ), 'tsm_ann_save' ) ) {
			$id = isset( $_POST['id'] ) ? absint( $_POST['id'] ) : 0;
			self::save( wp_unslash( $_POST ), $id );
			echo '<div class="notice notice-success"><p>' . esc_html__( 'Announcement saved.', 'tradeschool-manager' ) . '</p></div>';
		}
		if ( isset( $_GET['delete'] ) && check_admin_referer( 'tsm_ann_delete' ) ) {
			self::delete( absint( $_GET['delete'] ) );
			echo '<div class="notice notice-success"><p>' . esc_html__( 'Announcement deleted.', 'tradeschool-manager' ) . '</p></div>';
		}

		$editing = null;
		if ( isset( $_GET['edit'] ) ) {
			$editing = self::get( absint( $_GET['edit'] ) );
		}

		$current_audience = array( 'type' => 'all', 'value' => null );
		if ( $editing ) {
			$val = $editing->audience_value;
			$decoded = $val ? json_decode( $val, true ) : null;
			$current_audience = array(
				'type'  => $editing->audience_type ?: 'all',
				'value' => ( null === $decoded ) ? $val : $decoded,
			);
		}

		$rows = self::all();
		?>
		<div class="tsm-grid" style="display:grid;grid-template-columns:1.1fr 1fr;gap:24px;align-items:start;margin-top:14px;">

			<!-- Form -->
			<div style="background:#fff;border:1px solid #dcdcde;border-radius:10px;padding:18px;">
				<h2 style="margin-top:0;"><?php echo $editing ? esc_html__( 'Edit Announcement', 'tradeschool-manager' ) : esc_html__( 'New Announcement', 'tradeschool-manager' ); ?></h2>
				<form method="post">
					<?php wp_nonce_field( 'tsm_ann_save', 'tsm_ann_nonce' ); ?>
					<input type="hidden" name="id" value="<?php echo $editing ? (int) $editing->id : 0; ?>">

					<p style="margin:0 0 6px;font-weight:600;"><?php esc_html_e( 'Title', 'tradeschool-manager' ); ?></p>
					<input name="title" class="large-text" required value="<?php echo esc_attr( $editing->title ?? '' ); ?>">

					<p style="margin:14px 0 6px;font-weight:600;"><?php esc_html_e( 'Message', 'tradeschool-manager' ); ?></p>
					<textarea name="body" class="large-text" rows="6"><?php echo esc_textarea( $editing->body ?? '' ); ?></textarea>
					<p class="description" style="margin-top:4px;"><?php esc_html_e( 'Basic HTML allowed (links, bold, lists).', 'tradeschool-manager' ); ?></p>

					<p style="margin:14px 0 6px;font-weight:600;"><?php esc_html_e( 'Audience', 'tradeschool-manager' ); ?></p>
					<?php TSMP_Audience::render( 'audience', $current_audience ); ?>

					<div style="display:flex;gap:24px;flex-wrap:wrap;margin-top:14px;">
						<div>
							<p style="margin:0 0 4px;font-weight:600;"><?php esc_html_e( 'End Date', 'tradeschool-manager' ); ?></p>
							<input type="date" name="end_date" value="<?php echo esc_attr( $editing->end_date ?? '' ); ?>">
							<p class="description" style="margin:4px 0 0;font-size:12px;"><?php esc_html_e( 'Optional. Hides after this date.', 'tradeschool-manager' ); ?></p>
						</div>
						<div>
							<p style="margin:0 0 4px;font-weight:600;"><?php esc_html_e( 'Active', 'tradeschool-manager' ); ?></p>
							<label><input type="checkbox" name="active" value="1" <?php checked( $editing ? (int) $editing->active : 1, 1 ); ?>> <?php esc_html_e( 'Show on student portal', 'tradeschool-manager' ); ?></label>
						</div>
					</div>

					<p style="margin-top:18px;">
						<button class="button button-primary"><?php echo $editing ? esc_html__( 'Update Announcement', 'tradeschool-manager' ) : esc_html__( 'Publish Announcement', 'tradeschool-manager' ); ?></button>
						<?php if ( $editing ) : ?>
							<a class="button" href="<?php echo esc_url( remove_query_arg( 'edit' ) ); ?>"><?php esc_html_e( 'Cancel', 'tradeschool-manager' ); ?></a>
						<?php endif; ?>
					</p>
				</form>
			</div>

			<!-- List -->
			<div style="background:#fff;border:1px solid #dcdcde;border-radius:10px;padding:18px;">
				<h2 style="margin-top:0;"><?php esc_html_e( 'All Announcements', 'tradeschool-manager' ); ?></h2>
				<?php if ( empty( $rows ) ) : ?>
					<p style="color:#646970;"><?php esc_html_e( 'No announcements yet.', 'tradeschool-manager' ); ?></p>
				<?php else : ?>
					<table class="widefat striped">
						<thead><tr>
							<th><?php esc_html_e( 'Title', 'tradeschool-manager' ); ?></th>
							<th><?php esc_html_e( 'Audience', 'tradeschool-manager' ); ?></th>
							<th><?php esc_html_e( 'Status', 'tradeschool-manager' ); ?></th>
							<th><?php esc_html_e( 'Ends', 'tradeschool-manager' ); ?></th>
							<th></th>
						</tr></thead>
						<tbody>
						<?php
						$today = current_time( 'Y-m-d' );
						foreach ( $rows as $r ) :
							$expired    = ( ! empty( $r->end_date ) && $r->end_date < $today );
							$status_lbl = ! $r->active ? __( 'Off', 'tradeschool-manager' ) : ( $expired ? __( 'Expired', 'tradeschool-manager' ) : __( 'Live', 'tradeschool-manager' ) );
							$av_decoded = $r->audience_value ? json_decode( $r->audience_value, true ) : null;
							$av_val     = ( null === $av_decoded ) ? $r->audience_value : $av_decoded;
							?>
							<tr>
								<td><strong><?php echo esc_html( $r->title ); ?></strong></td>
								<td><?php echo esc_html( TSMP_Audience::label( $r->audience_type ?: 'all', $av_val ) ); ?></td>
								<td><?php echo esc_html( $status_lbl ); ?></td>
								<td><?php echo esc_html( $r->end_date ?: ' - ' ); ?></td>
								<td>
									<a class="button button-small" href="<?php echo esc_url( add_query_arg( 'edit', $r->id ) ); ?>"><?php esc_html_e( 'Edit', 'tradeschool-manager' ); ?></a>
									<a class="button button-small" style="color:#a00;" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'delete', $r->id ), 'tsm_ann_delete' ) ); ?>" onclick="return confirm('<?php echo esc_js( __( 'Delete this announcement?', 'tradeschool-manager' ) ); ?>');"><?php esc_html_e( 'Delete', 'tradeschool-manager' ); ?></a>
								</td>
							</tr>
						<?php endforeach; ?>
						</tbody>
					</table>
				<?php endif; ?>
			</div>
		</div>
		<?php
	}
}
