<?php
/**
 * @package Hafenstudios\Wellenbrecher
 */

namespace Hafenstudios\Wellenbrecher\Admin;

use Hafenstudios\Core\Core;
use Hafenstudios\Core\Settings\Settings;
use Hafenstudios\Wellenbrecher\Db\SpamLogRepository;
use Hafenstudios\Wellenbrecher\Db\StatsRepository;
use Hafenstudios\Wellenbrecher\Support\ObservationMode;
use Hafenstudios\Wellenbrecher\Support\SpamRecorder;

defined( 'ABSPATH' ) || exit;

/**
 * Uebersichts-Seite (Bauplan Kap. 8) - die Hauptseite des Wellenbrecher-Menues.
 *
 * Zeigt: Beobachtungsmodus-Banner (aus W2 wiederverwendet), Kennzahlen aus dem
 * StatsRepository (heute / 7 Tage / 30 Tage, je Kanal und Verdict), die letzten
 * Blockierungen aus dem Log, Kacheln zu Spam-Ordner/Quarantaene/Block-Log/
 * Einstellungen sowie Hans-Karten (Leerzustand und einmaliger Meilenstein bei
 * der ersten Blockierung, dismissible, Ein-Karte-pro-Screen).
 */
class OverviewPage {

	public const SLUG = 'wellenbrecher';

	protected Settings $settings;

	protected StatsRepository $stats;

	protected SpamLogRepository $log;

	protected ObservationMode $observation;

	/**
	 * Pro-Reports (Zeitraum-Filter + CSV-Export) nur bei aktivem Pro-Gate.
	 */
	protected bool $pro;

	/**
	 * @param Settings          $settings    Wellenbrecher-Settings.
	 * @param StatsRepository   $stats       Tageszaehler.
	 * @param SpamLogRepository $log         Spam-Log.
	 * @param ObservationMode   $observation Beobachtungsmodus.
	 * @param bool              $pro         Pro-Gate aktiv (blendet die Reports ein).
	 */
	public function __construct( Settings $settings, StatsRepository $stats, SpamLogRepository $log, ObservationMode $observation, bool $pro = false ) {
		$this->settings    = $settings;
		$this->stats       = $stats;
		$this->log         = $log;
		$this->observation = $observation;
		$this->pro         = $pro;
	}

	/**
	 * Rendert die Seite.
	 *
	 * @return void
	 */
	public function render(): void {
		if ( ! current_user_can( 'hs_manage_spam' ) ) {
			wp_die( esc_html__( 'Sie haben keine Berechtigung fuer die Wellenbrecher-Uebersicht.', 'wellenbrecher' ) );
		}

		echo '<div class="wrap">';
		echo '<h1 class="wp-heading-inline">' . esc_html__( 'Wellenbrecher: Uebersicht', 'wellenbrecher' ) . '</h1>';
		echo '<hr class="wp-header-end" />';

		ObservationNotice::render( $this->settings, $this->stats, $this->observation );

		// Onboarding-Checkliste: rendert die Schritte, oder - wenn alles erledigt
		// ist - die Hans-Abschluss-Karte (die dann den Ein-Karte-Slot belegt und
		// render_hans() unten unterdrueckt).
		( new SetupChecklist( $this->observation ) )->render();

		$this->render_hans();
		$this->render_metrics();
		if ( $this->pro ) {
			$this->render_reports();
		}
		$this->render_recent_blocks();
		$this->render_tiles();

		echo '</div>';
	}

	/**
	 * Pro-Reports: Zeitraum-Filter (7/30/90 Tage) mit Kanal-Aufschluesselung und
	 * CSV-Export der aggregierten Statistik (ohne Personenbezug).
	 *
	 * @return void
	 */
	protected function render_reports(): void {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nur Anzeige-Auswahl des Zeitraums (GET).
		$days = isset( $_GET['wb_days'] ) ? (int) $_GET['wb_days'] : 30;
		if ( ! in_array( $days, ReportsExport::RANGES, true ) ) {
			$days = 30;
		}

		echo '<h2>' . esc_html__( 'Berichte (Pro)', 'wellenbrecher' ) . '</h2>';

		echo '<form method="get" action="' . esc_url( admin_url( 'admin.php' ) ) . '" style="margin-bottom:12px;">';
		echo '<input type="hidden" name="page" value="' . esc_attr( self::SLUG ) . '" />';
		echo '<label for="wb-days">' . esc_html__( 'Zeitraum:', 'wellenbrecher' ) . ' </label>';
		echo '<select id="wb-days" name="wb_days" onchange="this.form.submit()">';
		foreach ( ReportsExport::RANGES as $choice ) {
			echo '<option value="' . esc_attr( (string) $choice ) . '"' . selected( $days, $choice, false ) . '>';
			/* translators: %d: Anzahl Tage */
			echo esc_html( sprintf( __( 'Letzte %d Tage', 'wellenbrecher' ), $choice ) );
			echo '</option>';
		}
		echo '</select> ';
		echo '<noscript><button type="submit" class="button">' . esc_html__( 'Anzeigen', 'wellenbrecher' ) . '</button></noscript>';
		echo '</form>';

		$summary  = $this->stats->summary( $days );
		$channels = (array) ( $summary['channels'] ?? array() );

		echo '<table class="wp-list-table widefat fixed striped"><thead><tr>';
		echo '<th scope="col">' . esc_html__( 'Kanal', 'wellenbrecher' ) . '</th>';
		echo '<th scope="col">' . esc_html__( 'Blockiert', 'wellenbrecher' ) . '</th>';
		echo '<th scope="col">' . esc_html__( 'Quarantaene', 'wellenbrecher' ) . '</th>';
		echo '<th scope="col">' . esc_html__( 'Markiert (Beobachtung)', 'wellenbrecher' ) . '</th>';
		echo '</tr></thead><tbody>';
		if ( array() === $channels ) {
			echo '<tr><td colspan="4">' . esc_html__( 'Keine Daten im gewaehlten Zeitraum.', 'wellenbrecher' ) . '</td></tr>';
		} else {
			foreach ( $channels as $channel => $verdicts ) {
				echo '<tr><td>' . esc_html( ChannelLabels::label( (string) $channel ) ) . '</td>';
				echo '<td>' . esc_html( (string) (int) ( $verdicts['blocked'] ?? 0 ) ) . '</td>';
				echo '<td>' . esc_html( (string) (int) ( $verdicts['quarantined'] ?? 0 ) ) . '</td>';
				echo '<td>' . esc_html( (string) (int) ( $verdicts['flagged'] ?? 0 ) ) . '</td></tr>';
			}
		}
		echo '</tbody></table>';

		$export = wp_nonce_url(
			admin_url( 'admin-post.php?action=' . ReportsExport::ACTION . '&days=' . $days ),
			ReportsExport::ACTION
		);
		echo '<p><a class="button" href="' . esc_url( $export ) . '">' . esc_html__( 'Statistik als CSV exportieren', 'wellenbrecher' ) . '</a></p>';
	}

	/**
	 * Hans-Karte: einmaliger Meilenstein bei der ersten Blockierung, sonst der
	 * Leerzustand, wenn noch nichts passiert ist. Ein-Karte-pro-Screen regelt
	 * das Hans-Framework selbst (render_card gibt danach Leerstring zurueck).
	 *
	 * @return void
	 */
	protected function render_hans(): void {
		$hans = Core::instance()->hans();

		if ( false !== get_option( SpamRecorder::FIRST_BLOCK_OPTION, false ) ) {
			$hans->card(
				array(
					'id'    => 'wellenbrecher_first_block',
					'motif' => 27,
					'title' => __( 'Der erste Treffer', 'wellenbrecher' ),
					'text'  => __( 'Wellenbrecher hat zum ersten Mal Spam abgewehrt. Werfen Sie ab und zu einen Blick ins Block-Log - dort sehen Sie jede Entscheidung mit Begruendung.', 'wellenbrecher' ),
					'tone'  => 'success',
				)
			);
			return;
		}

		$totals = (array) ( $this->stats->summary( 3650 )['totals'] ?? array() );
		if ( array_sum( array_map( 'intval', $totals ) ) > 0 ) {
			return;
		}

		$hans->card(
			array(
				'id'    => 'wellenbrecher_calm_sea',
				'motif' => 30,
				'title' => __( 'Noch kein Spam - die See ist ruhig', 'wellenbrecher' ),
				'text'  => __( 'Wellenbrecher wacht ueber Kommentare, Registrierungen und Ihre Leadlotse-Formulare. Sobald etwas auffaellt, erscheint es hier und im Block-Log.', 'wellenbrecher' ),
				'tone'  => 'info',
			)
		);
	}

	/**
	 * Kennzahlen-Block: heute / 7 Tage / 30 Tage, je Verdict, plus die
	 * Aufschluesselung nach Kanal fuer die 30 Tage.
	 *
	 * @return void
	 */
	protected function render_metrics(): void {
		$today = $this->stats->summary( 1 );
		$week  = $this->stats->summary( 7 );
		$month = $this->stats->summary( 30 );

		echo '<h2>' . esc_html__( 'Kennzahlen', 'wellenbrecher' ) . '</h2>';
		echo '<table class="wp-list-table widefat fixed striped"><thead><tr>';
		echo '<th scope="col">' . esc_html__( 'Zeitraum', 'wellenbrecher' ) . '</th>';
		echo '<th scope="col">' . esc_html__( 'Blockiert', 'wellenbrecher' ) . '</th>';
		echo '<th scope="col">' . esc_html__( 'Quarantaene', 'wellenbrecher' ) . '</th>';
		echo '<th scope="col">' . esc_html__( 'Markiert (Beobachtung)', 'wellenbrecher' ) . '</th>';
		echo '</tr></thead><tbody>';
		$this->metrics_row( __( 'Heute', 'wellenbrecher' ), $today );
		$this->metrics_row( __( 'Letzte 7 Tage', 'wellenbrecher' ), $week );
		$this->metrics_row( __( 'Letzte 30 Tage', 'wellenbrecher' ), $month );
		echo '</tbody></table>';

		$channels = (array) ( $month['channels'] ?? array() );
		if ( array() === $channels ) {
			return;
		}

		echo '<h3>' . esc_html__( 'Nach Kanal (letzte 30 Tage)', 'wellenbrecher' ) . '</h3>';
		echo '<table class="wp-list-table widefat fixed striped"><thead><tr>';
		echo '<th scope="col">' . esc_html__( 'Kanal', 'wellenbrecher' ) . '</th>';
		echo '<th scope="col">' . esc_html__( 'Blockiert', 'wellenbrecher' ) . '</th>';
		echo '<th scope="col">' . esc_html__( 'Quarantaene', 'wellenbrecher' ) . '</th>';
		echo '<th scope="col">' . esc_html__( 'Markiert (Beobachtung)', 'wellenbrecher' ) . '</th>';
		echo '</tr></thead><tbody>';
		foreach ( $channels as $channel => $verdicts ) {
			echo '<tr><td>' . esc_html( ChannelLabels::label( (string) $channel ) ) . '</td>';
			echo '<td>' . esc_html( (string) (int) ( $verdicts['blocked'] ?? 0 ) ) . '</td>';
			echo '<td>' . esc_html( (string) (int) ( $verdicts['quarantined'] ?? 0 ) ) . '</td>';
			echo '<td>' . esc_html( (string) (int) ( $verdicts['flagged'] ?? 0 ) ) . '</td></tr>';
		}
		echo '</tbody></table>';
	}

	/**
	 * Eine Kennzahlen-Zeile (Gesamtsummen je Verdict).
	 *
	 * @param string               $label   Zeitraum-Label.
	 * @param array<string, mixed> $summary Ergebnis von StatsRepository::summary.
	 * @return void
	 */
	protected function metrics_row( string $label, array $summary ): void {
		$totals = (array) ( $summary['totals'] ?? array() );
		echo '<tr><td>' . esc_html( $label ) . '</td>';
		echo '<td>' . esc_html( (string) (int) ( $totals['blocked'] ?? 0 ) ) . '</td>';
		echo '<td>' . esc_html( (string) (int) ( $totals['quarantined'] ?? 0 ) ) . '</td>';
		echo '<td>' . esc_html( (string) (int) ( $totals['flagged'] ?? 0 ) ) . '</td></tr>';
	}

	/**
	 * Die letzten Blockierungen (aus dem Log), damit unsichtbare False Positives
	 * sofort ins Auge fallen.
	 *
	 * @return void
	 */
	protected function render_recent_blocks(): void {
		$result = $this->log->query(
			array(
				'verdict'  => SpamLogRepository::VERDICT_BLOCKED,
				'page'     => 1,
				'per_page' => 5,
			)
		);
		$items = (array) ( $result['items'] ?? array() );

		echo '<h2>' . esc_html__( 'Letzte Blockierungen', 'wellenbrecher' ) . '</h2>';

		if ( array() === $items ) {
			echo '<p>' . esc_html__( 'Noch nichts blockiert. Sobald Wellenbrecher etwas abweist, erscheint es hier.', 'wellenbrecher' ) . '</p>';
			return;
		}

		echo '<table class="wp-list-table widefat fixed striped"><thead><tr>';
		echo '<th scope="col">' . esc_html__( 'Zeit (UTC)', 'wellenbrecher' ) . '</th>';
		echo '<th scope="col">' . esc_html__( 'Kanal', 'wellenbrecher' ) . '</th>';
		echo '<th scope="col">' . esc_html__( 'Punkte', 'wellenbrecher' ) . '</th>';
		echo '<th scope="col">' . esc_html__( 'Gruende', 'wellenbrecher' ) . '</th>';
		echo '</tr></thead><tbody>';
		foreach ( $items as $item ) {
			$item    = (array) $item;
			$reasons = is_array( $item['reasons'] ?? null ) ? $item['reasons'] : array();
			echo '<tr>';
			echo '<td>' . esc_html( (string) ( $item['created_at'] ?? '' ) ) . '</td>';
			echo '<td>' . esc_html( ChannelLabels::label( (string) ( $item['channel'] ?? '' ) ) ) . '</td>';
			echo '<td>' . esc_html( (string) (int) ( $item['score'] ?? 0 ) ) . '</td>';
			echo '<td>' . esc_html( $this->reasons_text( $reasons ) ) . '</td>';
			echo '</tr>';
		}
		echo '</tbody></table>';

		echo '<p><a href="' . esc_url( admin_url( 'admin.php?page=' . LogPage::SLUG ) ) . '">' . esc_html__( 'Zum vollstaendigen Block-Log', 'wellenbrecher' ) . '</a></p>';
	}

	/**
	 * Kacheln zu den wichtigsten Zielen.
	 *
	 * @return void
	 */
	protected function render_tiles(): void {
		$tiles = array(
			array(
				'label' => __( 'Spam-Ordner (Kommentare)', 'wellenbrecher' ),
				'desc'  => __( 'Quarantinierte Kommentare liegen im nativen WordPress-Spam-Ordner.', 'wellenbrecher' ),
				'url'   => admin_url( 'edit-comments.php?comment_status=spam' ),
			),
			array(
				'label' => __( 'Formular-Quarantaene', 'wellenbrecher' ),
				'desc'  => __( 'Abgefangene Leadlotse-Formulare pruefen und bei Bedarf wiederherstellen.', 'wellenbrecher' ),
				'url'   => admin_url( 'admin.php?page=' . QuarantinePage::SLUG ),
			),
			array(
				'label' => __( 'Block-Log', 'wellenbrecher' ),
				'desc'  => __( 'Jede Entscheidung mit Begruendung - macht False Positives sichtbar.', 'wellenbrecher' ),
				'url'   => admin_url( 'admin.php?page=' . LogPage::SLUG ),
			),
			array(
				'label' => __( 'Einstellungen', 'wellenbrecher' ),
				'desc'  => __( 'Zonen, Regeln, Aufbewahrung und den Beobachtungsmodus anpassen.', 'wellenbrecher' ),
				'url'   => admin_url( 'admin.php?page=' . SettingsPage::SLUG ),
			),
		);

		echo '<h2>' . esc_html__( 'Schnellzugriff', 'wellenbrecher' ) . '</h2>';
		echo '<div style="display:flex;flex-wrap:wrap;gap:16px;">';
		foreach ( $tiles as $tile ) {
			echo '<a href="' . esc_url( $tile['url'] ) . '" class="card" style="flex:1 1 220px;min-width:220px;max-width:320px;padding:16px;border:1px solid #dcdcde;border-radius:4px;text-decoration:none;">';
			echo '<strong style="display:block;margin-bottom:6px;">' . esc_html( $tile['label'] ) . '</strong>';
			echo '<span style="color:#50575e;">' . esc_html( $tile['desc'] ) . '</span>';
			echo '</a>';
		}
		echo '</div>';
	}

	/**
	 * Gruende lesbar: "Label (+Punkte)", kommagetrennt.
	 *
	 * @param array<string, mixed> $reasons Breakdown rule_id => Punkte.
	 * @return string
	 */
	protected function reasons_text( array $reasons ): string {
		$parts = array();
		foreach ( $reasons as $id => $points ) {
			$parts[] = RuleLabels::label( (string) $id ) . ' (' . sprintf( '%+d', (int) $points ) . ')';
		}
		return implode( ', ', $parts );
	}
}
