<?php
/**
 * The audience screen.
 *
 * Everyone who may be messaged, and everyone who agreed but will not be —
 * because "why is this person not getting my campaigns" is the question this
 * screen exists to answer, and a list of only the reachable cannot answer it.
 *
 * @package TextTango
 *
 * @var array<string, mixed> $args View data supplied by AudiencePage::render().
 */

declare( strict_types=1 );

defined( 'ABSPATH' ) || exit;

use TextTango\Admin\AudiencePage;
use TextTango\Marketing\Audience;
use TextTango\Marketing\AudienceFilter;
use TextTango\Support\Paging;

$texttango_rows   = (array) ( $args['rows'] ?? array() );
$texttango_filter = $args['filter'] ?? null;
$texttango_paging = $args['paging'] ?? null;
$texttango_total  = (int) ( $args['total'] ?? 0 );
$texttango_roster = (array) ( $args['roster'] ?? array() );
$texttango_states = (array) ( $args['states'] ?? array() );
$texttango_url    = (string) ( $args['url'] ?? '' );
$texttango_active = $texttango_filter instanceof AudienceFilter && $texttango_filter->is_active();

/*
 * Reachable is counted from the roster rather than from the filtered rows: the
 * headline must not change because somebody typed in the search box.
 */
$texttango_reach = 0;

foreach ( (array) ( $texttango_roster['rows'] ?? array() ) as $texttango_row ) {
	if ( Audience::STATE_CONSENTING === (string) $texttango_row['state'] ) {
		++$texttango_reach;
	}
}

$texttango_tones = array(
	Audience::STATE_CONSENTING => 'tt-badge-ok',
	Audience::STATE_SUPPRESSED => 'tt-badge-error',
	Audience::STATE_UNUSABLE   => 'tt-badge-warn',
	Audience::STATE_OUTSIDE    => 'tt-badge-off',
);
?>
<div class="wrap">
	<div id="texttango-app" class="texttango-ui">
		<div class="tt-py-4">

			<header class="tt-mb-6">
				<?php
				load_template(
					TEXTTANGO_PATH . 'templates/admin/partials/brand.php',
					false,
					array( 'title' => __( 'Audience', 'texttango' ) )
				);
				?>
				<p class="tt-mt-1 tt-mb-0 tt-text-sm tt-text-slate-500">
					<?php esc_html_e( 'Who this site may message, and why somebody is not on the list.', 'texttango' ); ?>
				</p>
			</header>

			<?php foreach ( (array) ( $args['notices'] ?? array() ) as $texttango_notice ) : ?>
				<div class="tt-notice tt-notice-<?php echo esc_attr( 'ok' === $texttango_notice['type'] ? 'ok' : 'error' ); ?> tt-mb-4">
					<?php echo esc_html( (string) $texttango_notice['message'] ); ?>
				</div>
			<?php endforeach; ?>

			<div class="tt-grid tt-grid-cols-2 tt-gap-4 tt-mb-4 sm:tt-grid-cols-4">
				<?php
				$texttango_figures = array(
					__( 'Can be messaged', 'texttango' )  => $texttango_reach,
					__( 'Opted out', 'texttango' )        => (int) ( $texttango_roster['suppressed'] ?? 0 ),
					__( 'No usable number', 'texttango' ) => (int) ( $texttango_roster['unusable'] ?? 0 ),
					__( 'Consents on record', 'texttango' ) => (int) ( $texttango_roster['consenting'] ?? 0 ),
				);
				?>
				<?php foreach ( $texttango_figures as $texttango_label => $texttango_value ) : ?>
					<div class="tt-card">
						<div class="tt-eyebrow"><?php echo esc_html( (string) $texttango_label ); ?></div>
						<div class="tt-analytics-figure"><?php echo esc_html( number_format_i18n( (int) $texttango_value ) ); ?></div>
					</div>
				<?php endforeach; ?>
			</div>

			<?php
			/*
			 * Said plainly when the list is partial. A store past the ceiling would
			 * otherwise be shown a page one that looks like the whole audience.
			 */
			?>
			<?php if ( (int) ( $texttango_roster['consenting'] ?? 0 ) >= (int) ( $args['ceiling'] ?? 0 ) ) : ?>
				<div class="tt-notice tt-notice-warn tt-mb-4">
					<?php
					echo esc_html(
						sprintf(
							/* translators: %s: maximum recipients. */
							__( 'This store has more consenting customers than one campaign can hold, so this list stops at %s. Campaigns are limited the same way.', 'texttango' ),
							number_format_i18n( (int) ( $args['ceiling'] ?? 0 ) )
						)
					);
					?>
				</div>
			<?php endif; ?>

			<div class="tt-card">
				<div class="tt-mb-4 tt-flex tt-flex-wrap tt-items-start tt-justify-between tt-gap-3">
					<div>
						<h2 class="tt-m-0 tt-mb-1 tt-p-0 tt-text-lg tt-font-semibold tt-text-slate-900">
							<?php esc_html_e( 'Everyone who agreed', 'texttango' ); ?>
						</h2>
						<p class="tt-m-0 tt-text-sm tt-text-slate-500">
							<?php esc_html_e( 'Customers with an account, guests who agreed at checkout, and numbers imported from a list. Stopping a number stops order updates as well as marketing.', 'texttango' ); ?>
						</p>
					</div>
					<a class="tt-btn tt-btn-secondary tt-shrink-0" href="<?php echo esc_url( (string) ( $args['consent_url'] ?? '' ) ); ?>">
						<?php esc_html_e( 'Consent settings', 'texttango' ); ?>
					</a>
				</div>

				<?php
				/*
				 * A GET form, like the message log's: a filtered audience can be
				 * linked to a colleague, the back button behaves, and a read needs
				 * no nonce.
				 */
				?>
				<form method="get" action="<?php echo esc_url( admin_url( 'admin.php' ) ); ?>" class="tt-mb-4 tt-flex tt-flex-wrap tt-items-end tt-gap-3">
					<input type="hidden" name="page" value="<?php echo esc_attr( AudiencePage::SLUG ); ?>" />

					<div class="tt-grow tt-max-w-md">
						<label class="tt-label" for="texttango-audience-search"><?php esc_html_e( 'Search', 'texttango' ); ?></label>
						<input
							type="search"
							class="tt-input"
							id="texttango-audience-search"
							name="<?php echo esc_attr( AudienceFilter::SEARCH_ARG ); ?>"
							value="<?php echo esc_attr( $texttango_filter instanceof AudienceFilter ? $texttango_filter->search() : '' ); ?>"
							placeholder="<?php esc_attr_e( 'A number or a name', 'texttango' ); ?>"
						/>
					</div>

					<div>
						<label class="tt-label" for="texttango-audience-state"><?php esc_html_e( 'Showing', 'texttango' ); ?></label>
						<select class="tt-input" id="texttango-audience-state" name="<?php echo esc_attr( AudienceFilter::STATE_ARG ); ?>">
							<option value=""><?php esc_html_e( 'Everyone', 'texttango' ); ?></option>
							<?php foreach ( $texttango_states as $texttango_key => $texttango_label ) : ?>
								<option
									value="<?php echo esc_attr( (string) $texttango_key ); ?>"
									<?php selected( $texttango_filter instanceof AudienceFilter ? $texttango_filter->state() : '', (string) $texttango_key ); ?>
								>
									<?php echo esc_html( (string) $texttango_label ); ?>
								</option>
							<?php endforeach; ?>
						</select>
					</div>

					<button type="submit" class="tt-btn tt-btn-secondary"><?php esc_html_e( 'Filter', 'texttango' ); ?></button>

					<?php if ( $texttango_active ) : ?>
						<a class="tt-btn tt-btn-secondary" href="<?php echo esc_url( $texttango_url ); ?>"><?php esc_html_e( 'Clear', 'texttango' ); ?></a>
					<?php endif; ?>
				</form>

				<?php if ( array() === $texttango_rows ) : ?>
					<?php
					load_template(
						TEXTTANGO_PATH . 'templates/admin/partials/empty-state.php',
						false,
						$texttango_active
							? array(
								'title'  => __( 'Nobody matches that.', 'texttango' ),
								'lead'   => __( 'Try a different number or name, or show everyone.', 'texttango' ),
								'action' => __( 'Show everyone', 'texttango' ),
								'url'    => $texttango_url,
							)
							: array(
								'title'  => __( 'Nobody has agreed to marketing yet.', 'texttango' ),
								'lead'   => __( 'Customers appear here once they agree — at checkout, in their account, or from a list you import.', 'texttango' ),
								'action' => __( 'Consent settings', 'texttango' ),
								'url'    => (string) ( $args['consent_url'] ?? '' ),
							)
					);
					?>
				<?php else : ?>
					<div class="tt-overflow-x-auto">
						<table class="tt-table">
							<thead>
								<tr>
									<th class="tt-th tt-pl-0"><?php esc_html_e( 'Number', 'texttango' ); ?></th>
									<th class="tt-th"><?php esc_html_e( 'Name', 'texttango' ); ?></th>
									<th class="tt-th"><?php esc_html_e( 'Status', 'texttango' ); ?></th>
									<th class="tt-th"><?php esc_html_e( 'Agreed', 'texttango' ); ?></th>
									<th class="tt-th tt-pr-0 tt-text-right"></th>
								</tr>
							</thead>
							<tbody>
								<?php foreach ( $texttango_rows as $texttango_row ) : ?>
									<?php
									$texttango_state  = (string) $texttango_row['state'];
									$texttango_number = (string) $texttango_row['number'];
									?>
									<tr>
										<td class="tt-td tt-whitespace-nowrap tt-pl-0 tt-font-medium tt-text-slate-700">
											<?php if ( '' === $texttango_number ) : ?>
												<span class="tt-td-muted"><?php esc_html_e( 'None on file', 'texttango' ); ?></span>
											<?php else : ?>
												<?php echo esc_html( $texttango_number ); ?>
											<?php endif; ?>
										</td>
										<td class="tt-td">
											<?php if ( '' === (string) $texttango_row['name'] ) : ?>
												<span class="tt-td-muted"><?php esc_html_e( 'From a list', 'texttango' ); ?></span>
											<?php else : ?>
												<?php echo esc_html( (string) $texttango_row['name'] ); ?>
											<?php endif; ?>
										</td>
										<td class="tt-td tt-whitespace-nowrap">
											<span class="tt-badge <?php echo esc_attr( (string) ( $texttango_tones[ $texttango_state ] ?? 'tt-badge-off' ) ); ?>">
												<?php echo esc_html( (string) ( $texttango_states[ $texttango_state ] ?? $texttango_state ) ); ?>
											</span>
										</td>
										<td class="tt-td tt-whitespace-nowrap tt-td-muted">
											<?php
											$texttango_at = (string) $texttango_row['at'];

											if ( '' !== $texttango_at ) {
												echo esc_html( (string) mysql2date( (string) get_option( 'date_format', 'Y-m-d' ), $texttango_at ) );
											}

											if ( '' !== (string) $texttango_row['source'] ) {
												printf(
													' <span class="tt-text-slate-400">%s</span>',
													esc_html( (string) $texttango_row['source'] )
												);
											}
											?>
										</td>
										<td class="tt-td tt-whitespace-nowrap tt-pr-0 tt-text-right">
											<?php if ( '' !== $texttango_number ) : ?>
												<?php
												$texttango_stop = Audience::STATE_SUPPRESSED !== $texttango_state;
												$texttango_act  = $texttango_stop
													? (string) ( $args['suppress_action'] ?? '' )
													: (string) ( $args['restore_action'] ?? '' );
												?>
												<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" class="tt-inline">
													<?php wp_nonce_field( $texttango_act ); ?>
													<input type="hidden" name="action" value="<?php echo esc_attr( $texttango_act ); ?>" />
													<input type="hidden" name="number" value="<?php echo esc_attr( $texttango_number ); ?>" />
													<?php
													// The filter travels with the action so pressing Stop on
													// page four of a search comes back to page four of it.
													?>
													<?php foreach ( $texttango_filter instanceof AudienceFilter ? $texttango_filter->query_args() : array() as $texttango_k => $texttango_v ) : ?>
														<input type="hidden" name="<?php echo esc_attr( (string) $texttango_k ); ?>" value="<?php echo esc_attr( (string) $texttango_v ); ?>" />
													<?php endforeach; ?>
													<?php
													// The same quiet row action the message log's "Send again"
													// uses. A filled button on every row of a long table reads
													// as the point of the table, and reading it is.
													?>
													<button
														type="submit"
														class="tt-cursor-pointer tt-border-0 tt-bg-transparent tt-p-0 tt-text-xs tt-font-medium tt-underline <?php echo $texttango_stop ? 'tt-text-slate-500' : 'tt-text-brand-600'; ?>"
													><?php echo $texttango_stop ? esc_html__( 'Stop messages', 'texttango' ) : esc_html__( 'Allow again', 'texttango' ); ?></button>
												</form>
											<?php endif; ?>
										</td>
									</tr>
								<?php endforeach; ?>
							</tbody>
						</table>
					</div>

					<?php
					if ( $texttango_paging instanceof Paging ) {
						load_template(
							TEXTTANGO_PATH . 'templates/admin/partials/pager.php',
							false,
							array(
								'paging' => $texttango_paging,
								'total'  => $texttango_total,
								'shown'  => count( $texttango_rows ),
								'url'    => $texttango_url,
								'keep'   => $texttango_filter instanceof AudienceFilter ? $texttango_filter->filter_args() : array(),
								'arg'    => AudienceFilter::PAGE_ARG,
							)
						);
					}
					?>
				<?php endif; ?>

				<?php if ( (int) ( $texttango_roster['at'] ?? 0 ) > 0 ) : ?>
					<p class="tt-mt-3 tt-mb-0 tt-text-xs tt-text-slate-400">
						<?php
						/*
						 * Said, because these are cached. Campaigns are not: they read
						 * the audience live, so a number stopped a minute ago is already
						 * excluded from a send even while this line is still catching up.
						 */
						echo esc_html(
							sprintf(
								/* translators: %s: human-readable time difference, e.g. "2 mins". */
								__( 'Counted %s ago. Campaigns always read this list fresh when they send.', 'texttango' ),
								human_time_diff( (int) $texttango_roster['at'] )
							)
						);
						?>
					</p>
				<?php endif; ?>
			</div>

		</div>
	</div>
</div>
