<?php
/**
 * Bootstrap KSeF API v2 — rejestruje cron i wystawia fabryki.
 *
 * @package KSEF\WordPress\V2
 */

declare(strict_types=1);

namespace KSEF\WordPress\V2;

// phpcs:disable WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders, WordPress.DB.SlowDBQuery, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Wlasne tabele gksef_*: wartosci przez $wpdb->prepare()/esc_like(), nazwy tabel z $wpdb->prefix, paginacja rzutowana (int); nonce weryfikowany w handlerze (check_ajax_referer/check_admin_referer).

final class Bootstrap {

	public static function register(): void {
		// Filter MUSI być NAJPIERW — inaczej wp_schedule_event nie wie o naszym custom schedule.
		add_filter( 'cron_schedules', static function ( $schedules ) {
			$schedules['ksef_v2_quarter_hourly'] = [
				'interval' => 15 * MINUTE_IN_SECONDS,
				'display'  => 'KSeF v2 — co 15 min',
			];
			return $schedules;
		} );

		// Cron polling statusu sesji (potwierdzanie wysłanych faktur + UPO).
		if ( ! wp_next_scheduled( 'ksef_v2_poll_status_cron' ) ) {
			wp_schedule_event( time() + 60, 'ksef_v2_quarter_hourly', 'ksef_v2_poll_status_cron' );
		}
		add_action( 'ksef_v2_poll_status_cron', [ self::class, 'run_poll_cron' ] );

		// Wyczyść crony pobierania faktur (zakup / sprzedaż z KSeF) — funkcje Pro,
		// nieobecne w wersji darmowej.
		wp_clear_scheduled_hook( 'ksef_v2_fetch_incoming_cron' );
		wp_clear_scheduled_hook( 'ksef_v2_fetch_outgoing_cron' );
	}

	public static function client_for_credential( array $credential ): Ksef_Client {
		$env = (string) ( $credential['ksef_environment'] ?? 'test' );
		return new Ksef_Client( $env );
	}

	public static function auth_for_credential( array $credential ): Auth {
		$client      = self::client_for_credential( $credential );
		$public_keys = new Public_Keys( $client, (string) ( $credential['ksef_environment'] ?? 'test' ) );
		return new Auth( $client, $public_keys );
	}

	public static function invoice_sender_for_credential( array $credential ): Invoice_Sender {
		$client      = self::client_for_credential( $credential );
		$public_keys = new Public_Keys( $client, (string) ( $credential['ksef_environment'] ?? 'test' ) );
		$auth        = new Auth( $client, $public_keys );
		$builder     = new Fa3_Builder();
		return new Invoice_Sender( $client, $auth, $public_keys, $builder );
	}

	public static function poller_for_credential( array $credential ): Status_Poller {
		$client      = self::client_for_credential( $credential );
		$public_keys = new Public_Keys( $client, (string) ( $credential['ksef_environment'] ?? 'test' ) );
		$auth        = new Auth( $client, $public_keys );
		return new Status_Poller( $client, $auth, new Upo_Parser() );
	}

	public static function run_poll_cron(): void {
		global $wpdb;
		$rows = $wpdb->get_results(
			"SELECT DISTINCT credential_id FROM {$wpdb->prefix}gksef_outgoing_invoices
			 WHERE status IN ('sent','pending')",
			ARRAY_A
		);
		foreach ( $rows as $row ) {
			$credential = $wpdb->get_row(
				$wpdb->prepare( "SELECT * FROM {$wpdb->prefix}gksef_credentials WHERE id = %d", (int) $row['credential_id'] ),
				ARRAY_A
			);
			if ( $credential ) {
				self::poller_for_credential( $credential )->cron_poll();
			}
		}
	}
}
