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

namespace Hafenstudios\Kurato\Admin;

defined( 'ABSPATH' ) || exit;

/**
 * Top-Level-Menue "Kurato" im WP-Admin.
 *
 * Kontaktliste (K2, serverseitig), Pipeline-Board und Kontaktprofil (K3,
 * No-Build-React). Assets werden screen-gezielt geladen: board.js nur auf dem
 * Board, contact.js nur im Kontaktprofil, admin.css ueberall im Kurato-Bereich.
 */
final class Menu {

	public const MENU_SLUG  = 'kurato';
	public const BOARD_SLUG = 'kurato-pipeline';

	private ContactsListPage $contacts_page;

	private BoardPage $board_page;

	private ContactPage $contact_page;

	private ListsPage $lists_page;

	private ImportPage $import_page;

	private MailSettingsPage $mail_page;

	private CampaignsPage $campaigns_page;

	private SegmentsPage $segments_page;

	private BookingsPage $bookings_page;

	private HostsPage $hosts_page;

	private AiSettingsPage $ai_page;

	private InsightPage $insight_page;

	/**
	 * @var array<string, string>
	 */
	private array $hooks = array();

	/**
	 * @param ContactsListPage $contacts_page  Kontaktliste.
	 * @param BoardPage        $board_page     Pipeline-Board.
	 * @param ContactPage      $contact_page   Kontaktprofil.
	 * @param ListsPage        $lists_page     Listen-Verwaltung.
	 * @param ImportPage       $import_page    CSV-Import.
	 * @param MailSettingsPage $mail_page      Versand-Einstellungen.
	 * @param CampaignsPage    $campaigns_page Kampagnen-Verwaltung.
	 * @param SegmentsPage     $segments_page  Segment-Builder (K4d).
	 * @param BookingsPage     $bookings_page  Buchungsliste (K5b).
	 * @param HostsPage        $hosts_page     Buchungsseiten-Verwaltung (K5b).
	 * @param AiSettingsPage   $ai_page        KI-Einstellungen (H1).
	 * @param InsightPage      $insight_page   Kompass light (H2).
	 */
	public function __construct( ContactsListPage $contacts_page, BoardPage $board_page, ContactPage $contact_page, ListsPage $lists_page, ImportPage $import_page, MailSettingsPage $mail_page, CampaignsPage $campaigns_page, SegmentsPage $segments_page, BookingsPage $bookings_page, HostsPage $hosts_page, AiSettingsPage $ai_page, InsightPage $insight_page ) {
		$this->contacts_page  = $contacts_page;
		$this->board_page     = $board_page;
		$this->contact_page   = $contact_page;
		$this->lists_page     = $lists_page;
		$this->import_page    = $import_page;
		$this->mail_page      = $mail_page;
		$this->campaigns_page = $campaigns_page;
		$this->segments_page  = $segments_page;
		$this->bookings_page  = $bookings_page;
		$this->hosts_page     = $hosts_page;
		$this->ai_page        = $ai_page;
		$this->insight_page   = $insight_page;
	}

	/**
	 * Registriert die Admin-Hooks.
	 *
	 * @return void
	 */
	public function register(): void {
		add_action( 'admin_menu', array( $this, 'register_menu' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
	}

	/**
	 * Baut das Menue auf.
	 *
	 * @return void
	 */
	public function register_menu(): void {
		$this->hooks['contacts'] = (string) add_menu_page(
			__( 'Kurato', 'kurato' ),
			__( 'Kurato', 'kurato' ),
			'hs_view_contacts',
			self::MENU_SLUG,
			array( $this->contacts_page, 'render' ),
			'dashicons-groups',
			57
		);

		add_submenu_page(
			self::MENU_SLUG,
			__( 'Kontakte', 'kurato' ),
			__( 'Kontakte', 'kurato' ),
			'hs_view_contacts',
			self::MENU_SLUG,
			array( $this->contacts_page, 'render' )
		);

		$this->hooks['board'] = (string) add_submenu_page(
			self::MENU_SLUG,
			__( 'Pipeline', 'kurato' ),
			__( 'Pipeline', 'kurato' ),
			'hs_view_contacts',
			self::BOARD_SLUG,
			array( $this->board_page, 'render' )
		);

		$this->hooks['insight'] = (string) add_submenu_page(
			self::MENU_SLUG,
			__( 'Kompass', 'kurato' ),
			__( 'Kompass', 'kurato' ),
			'hs_view_contacts',
			InsightPage::SLUG,
			array( $this->insight_page, 'render' )
		);

		$this->hooks['lists'] = (string) add_submenu_page(
			self::MENU_SLUG,
			__( 'Listen', 'kurato' ),
			__( 'Listen', 'kurato' ),
			'hs_view_contacts',
			ListsPage::SLUG,
			array( $this->lists_page, 'render' )
		);

		$this->hooks['segments'] = (string) add_submenu_page(
			self::MENU_SLUG,
			__( 'Segmente', 'kurato' ),
			__( 'Segmente', 'kurato' ),
			'hs_view_contacts',
			SegmentsPage::SLUG,
			array( $this->segments_page, 'render' )
		);

		$this->hooks['campaigns'] = (string) add_submenu_page(
			self::MENU_SLUG,
			__( 'Kampagnen', 'kurato' ),
			__( 'Kampagnen', 'kurato' ),
			'hs_send_mails',
			CampaignsPage::SLUG,
			array( $this->campaigns_page, 'render' )
		);

		$this->hooks['bookings'] = (string) add_submenu_page(
			self::MENU_SLUG,
			__( 'Termine', 'kurato' ),
			__( 'Termine', 'kurato' ),
			'hs_manage_contacts',
			BookingsPage::SLUG,
			array( $this->bookings_page, 'render' )
		);

		$this->hooks['hosts'] = (string) add_submenu_page(
			self::MENU_SLUG,
			__( 'Buchungsseiten', 'kurato' ),
			__( 'Buchungsseiten', 'kurato' ),
			'hs_manage_contacts',
			HostsPage::SLUG,
			array( $this->hosts_page, 'render' )
		);

		$this->hooks['import'] = (string) add_submenu_page(
			self::MENU_SLUG,
			__( 'Kontakte importieren', 'kurato' ),
			__( 'Import', 'kurato' ),
			'hs_manage_contacts',
			ImportPage::SLUG,
			array( $this->import_page, 'render' )
		);

		$this->hooks['mail'] = (string) add_submenu_page(
			self::MENU_SLUG,
			__( 'Versand-Einstellungen', 'kurato' ),
			__( 'Versand', 'kurato' ),
			'hs_manage_settings',
			MailSettingsPage::SLUG,
			array( $this->mail_page, 'render' )
		);

		$this->hooks['ai'] = (string) add_submenu_page(
			self::MENU_SLUG,
			__( 'KI-Einstellungen', 'kurato' ),
			__( 'KI', 'kurato' ),
			'hs_manage_settings',
			AiSettingsPage::SLUG,
			array( $this->ai_page, 'render' )
		);

		$this->hooks['contact'] = (string) add_submenu_page(
			'',
			__( 'Kontakt', 'kurato' ),
			__( 'Kontakt', 'kurato' ),
			'hs_view_contacts',
			ContactPage::SLUG,
			array( $this->contact_page, 'render' )
		);

		$this->hooks['campaign'] = (string) add_submenu_page(
			'',
			__( 'Kampagne', 'kurato' ),
			__( 'Kampagne', 'kurato' ),
			'hs_view_contacts',
			CampaignsPage::DETAIL_SLUG,
			array( $this->campaigns_page, 'render_detail' )
		);

		$this->hooks['host'] = (string) add_submenu_page(
			'',
			__( 'Ansprechpartner', 'kurato' ),
			__( 'Ansprechpartner', 'kurato' ),
			'hs_manage_contacts',
			HostsPage::DETAIL_SLUG,
			array( $this->hosts_page, 'render_detail' )
		);
	}

	/**
	 * Laedt Admin-Assets gezielt je Screen.
	 *
	 * @param string $hook Aktueller Admin-Hook-Suffix.
	 * @return void
	 */
	public function enqueue_assets( string $hook ): void {
		if ( ! in_array( $hook, $this->hooks, true ) ) {
			return;
		}

		wp_enqueue_style( 'kurato-admin', KURATO_URL . 'assets/css/admin.css', array(), KURATO_VERSION );

		$can_manage = current_user_can( 'hs_manage_contacts' );
		$rest_base  = esc_url_raw( rest_url( 'kurato/v1' ) );
		$nonce      = wp_create_nonce( 'wp_rest' );

		if ( isset( $this->hooks['board'] ) && $hook === $this->hooks['board'] ) {
			wp_enqueue_script( 'kurato-board', KURATO_URL . 'assets/js/board.js', array( 'wp-element' ), KURATO_VERSION, true );
			wp_set_script_translations( 'kurato-board', 'kurato' );
			wp_localize_script(
				'kurato-board',
				'kuratoBoard',
				array(
					'restBase'       => $rest_base,
					'nonce'          => $nonce,
					'canManage'      => $can_manage,
					'contactBaseUrl' => admin_url( 'admin.php?page=' . ContactPage::SLUG ),
					'i18n'           => $this->board_i18n(),
				)
			);
		}

		if ( isset( $this->hooks['segments'] ) && $hook === $this->hooks['segments'] ) {
			wp_enqueue_script( 'kurato-segments', KURATO_URL . 'assets/js/segments.js', array( 'wp-element' ), KURATO_VERSION, true );
			wp_set_script_translations( 'kurato-segments', 'kurato' );
			wp_localize_script(
				'kurato-segments',
				'kuratoSegments',
				array(
					'restBase'  => $rest_base,
					'nonce'     => $nonce,
					'canManage' => $can_manage,
					'lists'     => $this->segment_lists(),
					'i18n'      => $this->segments_i18n(),
				)
			);
		}

		if ( isset( $this->hooks['contact'] ) && $hook === $this->hooks['contact'] ) {
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nur Auswahl der zu ladenden Ressource; Schreibzugriff laeuft nonce-geschuetzt ueber REST.
			$contact_id = isset( $_GET['contact'] ) ? absint( wp_unslash( $_GET['contact'] ) ) : 0;
			wp_enqueue_script( 'kurato-contact', KURATO_URL . 'assets/js/contact.js', array( 'wp-element' ), KURATO_VERSION, true );
			wp_set_script_translations( 'kurato-contact', 'kurato' );
			wp_localize_script(
				'kurato-contact',
				'kuratoContact',
				array(
					'restBase'  => $rest_base,
					'nonce'     => $nonce,
					'canManage' => $can_manage,
					'contactId' => $contact_id,
					'boardUrl'  => admin_url( 'admin.php?page=' . self::BOARD_SLUG ),
					'i18n'      => $this->contact_i18n(),
				)
			);
		}
	}

	/**
	 * Listen fuer den Segment-Builder (kein oeffentlicher Listen-REST vorhanden,
	 * daher per Localize mitgegeben). Nur id und label.
	 *
	 * @return array<int, array{id:int,label:string}>
	 */
	private function segment_lists(): array {
		$out = array();
		foreach ( ( new \Hafenstudios\Kurato\Db\ListRepository() )->all() as $list ) {
			$out[] = array(
				'id'    => (int) $list['id'],
				'label' => (string) $list['label'],
			);
		}
		return $out;
	}

	/**
	 * Segment-Builder-Strings.
	 *
	 * @return array<string, string>
	 */
	private function segments_i18n(): array {
		return array(
			'loading'       => __( 'Wird geladen.', 'kurato' ),
			'segments'      => __( 'Segmente', 'kurato' ),
			'newSegment'    => __( 'Neues Segment', 'kurato' ),
			'name'          => __( 'Name', 'kurato' ),
			'namePlaceholder' => __( 'Name des Segments', 'kurato' ),
			'save'          => __( 'Speichern', 'kurato' ),
			'saved'         => __( 'Gespeichert.', 'kurato' ),
			'cancel'        => __( 'Abbrechen', 'kurato' ),
			'rename'        => __( 'Umbenennen', 'kurato' ),
			'delete'        => __( 'Loeschen', 'kurato' ),
			'confirmDelete' => __( 'Dieses Segment wirklich loeschen?', 'kurato' ),
			'noSegments'    => __( 'Noch keine Segmente. Legen Sie Ihr erstes an.', 'kurato' ),
			'conditions'    => __( 'Bedingungen', 'kurato' ),
			'addCondition'  => __( 'Bedingung hinzufuegen', 'kurato' ),
			'removeCondition' => __( 'Bedingung entfernen', 'kurato' ),
			'allMatch'      => __( 'Ein Kontakt passt, wenn ALLE Bedingungen zutreffen.', 'kurato' ),
			'noConditions'  => __( 'Ohne Bedingungen trifft das Segment alle Kontakte.', 'kurato' ),
			'fieldTag'      => __( 'Tag', 'kurato' ),
			'fieldStage'    => __( 'Pipeline-Stufe', 'kurato' ),
			'fieldList'     => __( 'Liste', 'kurato' ),
			'opHas'         => __( 'hat', 'kurato' ),
			'opHasNot'      => __( 'hat nicht', 'kurato' ),
			'opIn'          => __( 'ist in', 'kurato' ),
			'opNotIn'       => __( 'ist nicht in', 'kurato' ),
			'opSubscribed'  => __( 'abonniert (bestaetigt)', 'kurato' ),
			'field'         => __( 'Feld', 'kurato' ),
			'operator'      => __( 'Operator', 'kurato' ),
			'value'         => __( 'Wert', 'kurato' ),
			'chooseValue'   => __( 'Bitte waehlen', 'kurato' ),
			/* translators: %s: Anzahl Kontakte */
			'matchCount'    => __( 'Segment trifft aktuell %s Kontakte', 'kurato' ),
			'counting'      => __( 'Trefferzahl wird ermittelt.', 'kurato' ),
			'error'         => __( 'Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.', 'kurato' ),
			'readOnly'      => __( 'Sie koennen Segmente ansehen, aber nicht aendern.', 'kurato' ),
		);
	}

	/**
	 * Board-Strings.
	 *
	 * @return array<string, string>
	 */
	private function board_i18n(): array {
		return array(
			'loading'     => __( 'Wird geladen.', 'kurato' ),
			'contact'     => __( 'Kontakt', 'kurato' ),
			'moveTo'      => __( 'Verschieben nach', 'kurato' ),
			'columnEmpty' => __( 'Keine Kontakte', 'kurato' ),
			'moveError'   => __( 'Der Kontakt konnte nicht verschoben werden. Bitte versuchen Sie es erneut.', 'kurato' ),
		);
	}

	/**
	 * Kontaktprofil-Strings.
	 *
	 * @return array<string, string>
	 */
	private function contact_i18n(): array {
		return array(
			'loading'     => __( 'Wird geladen.', 'kurato' ),
			'contact'     => __( 'Kontakt', 'kurato' ),
			'backToBoard' => __( 'Zurueck zur Pipeline', 'kurato' ),
			'details'     => __( 'Stammdaten', 'kurato' ),
			'displayName' => __( 'Anzeigename', 'kurato' ),
			'firstName'   => __( 'Vorname', 'kurato' ),
			'lastName'    => __( 'Nachname', 'kurato' ),
			'email'       => __( 'E-Mail', 'kurato' ),
			'phone'       => __( 'Telefon', 'kurato' ),
			'save'        => __( 'Speichern', 'kurato' ),
			'saved'       => __( 'Gespeichert.', 'kurato' ),
			'stage'       => __( 'Pipeline-Stufe', 'kurato' ),
			'noStage'     => __( 'Ohne Stufe', 'kurato' ),
			'timeline'    => __( 'Verlauf', 'kurato' ),
			'noHistory'   => __( 'Noch keine Stufenwechsel.', 'kurato' ),
			'tags'        => __( 'Tags', 'kurato' ),
			'noTags'      => __( 'Keine Tags', 'kurato' ),
			'newTag'      => __( 'Neuer Tag', 'kurato' ),
			'removeTag'   => __( 'Tag entfernen', 'kurato' ),
			'add'         => __( 'Hinzufuegen', 'kurato' ),
			'tasks'       => __( 'Wiedervorlagen', 'kurato' ),
			'noTasks'     => __( 'Keine offenen Wiedervorlagen.', 'kurato' ),
			'taskTitle'   => __( 'Was ist zu tun?', 'kurato' ),
			'taskDue'     => __( 'Faellig am', 'kurato' ),
			'markDone'    => __( 'Als erledigt markieren', 'kurato' ),
			'subscriptions'   => __( 'Newsletter-Abos', 'kurato' ),
			'noSubscriptions' => __( 'Keine Abos.', 'kurato' ),
			'subPending'      => __( 'Wartet auf Bestaetigung', 'kurato' ),
			'subConfirmed'    => __( 'Bestaetigt', 'kurato' ),
			'subUnsubscribed' => __( 'Abgemeldet', 'kurato' ),
			'bookings'        => __( 'Termine', 'kurato' ),
			'noBookings'      => __( 'Keine Termine.', 'kurato' ),
			'bookingConfirmed' => __( 'Bestaetigt', 'kurato' ),
			'bookingCancelled' => __( 'Storniert', 'kurato' ),
			'deliveryBounce'    => __( 'Adresse unzustellbar', 'kurato' ),
			'deliveryComplaint' => __( 'Beschwerde eingegangen', 'kurato' ),
			'deliverySince'     => __( 'seit', 'kurato' ),
		);
	}
}
