<?php
if ( ! defined( 'ABSPATH' ) ) {
	die( 'Direct access is not allowed.' );
}

/**
 * Dashboard Controller Class
 */
class FinalPOS_Dashboard {

	public static function init() {
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce is verified in handle_disconnect().
		if ( isset( $_POST['action'] ) && sanitize_text_field( wp_unslash( $_POST['action'] ) ) === FINALPOS_ACTION_DISCONNECT ) {
			self::handle_disconnect();
		}
	}


	private static function handle_disconnect() {
		// Verify nonce.
		if ( ! isset( $_POST['finalpos_disconnect_nonce'] ) ||
			! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['finalpos_disconnect_nonce'] ) ), FINALPOS_NONCE_DISCONNECT ) ) {
			wp_die( 'Security check failed.' );
		}

		FinalPOS_Common::disconnect_plugin();

		wp_redirect( add_query_arg( 'disconnected', '1', admin_url( 'admin.php?page=' . FINALPOS_PAGE_SETUP ) ) );
		exit;
	}

	/**
	 * Sanitized ecommerce log filters from request (source, type, entity_type, entity_id, sort_by).
	 * Source is only passed when it is woo-commerce or standalone.
	 * sort_by is 'asc' (oldest first) or 'desc' (newest first).
	 *
	 * @return array{source: string, type: string, entity_type: string, entity_id: string, sort_by: string}
	 */
	public static function get_ecommerce_log_filters() {
		$source    = isset( $_GET['source'] ) ? sanitize_text_field( wp_unslash( $_GET['source'] ) ) : '';
		$type      = isset( $_GET['type'] ) ? sanitize_text_field( wp_unslash( $_GET['type'] ) ) : '';
		$entity    = isset( $_GET['entity_type'] ) ? sanitize_text_field( wp_unslash( $_GET['entity_type'] ) ) : '';
		$entity_id = isset( $_GET['entity_id'] ) ? sanitize_text_field( wp_unslash( $_GET['entity_id'] ) ) : '';
		$sort_by   = isset( $_GET['sort_by'] ) ? sanitize_text_field( wp_unslash( $_GET['sort_by'] ) ) : 'desc';

		if ( $source !== '' && ! in_array( $source, FINALPOS_ECOMMERCE_LOG_SOURCE_OPTIONS, true ) ) {
			$source = '';
		}
		if ( $entity !== '' && ! array_key_exists( $entity, FINALPOS_ECOMMERCE_LOG_ENTITY_TYPES ) ) {
			$entity = '';
		}
		if ( $sort_by !== 'asc' && $sort_by !== 'desc' ) {
			$sort_by = 'desc';
		}

		return array(
			'source'      => $source,
			'type'        => $type,
			'entity_type' => $entity,
			'entity_id'   => $entity_id,
			'sort_by'     => $sort_by,
		);
	}

	/**
	 * Options for the ecommerce log filter dropdowns (value => label). Used by the logs tab view.
	 *
	 * @return array{source: array<string, string>, type: array<string, string>, entity_type: array<string, string>, sort_by: array<string, string>}
	 */
	public static function get_ecommerce_log_filter_options() {
		$entity_type_options = array( '' => __( 'All', 'finalpos' ) );
		foreach ( FINALPOS_ECOMMERCE_LOG_ENTITY_TYPES as $type => $label ) {
			$entity_type_options[ $type ] = __( $label, 'finalpos' );
		}

		return array(
			'source'      => array(
				''             => __( 'All', 'finalpos' ),
				'woo-commerce' => __( 'WooCommerce', 'finalpos' ),
				'standalone'   => __( 'Standalone', 'finalpos' ),
			),
			'type'        => array(
				''             => __( 'All', 'finalpos' ),
				'error'        => __( 'Error', 'finalpos' ),
				'warning'      => __( 'Warning', 'finalpos' ),
				'notification' => __( 'Notification', 'finalpos' ),
				'debug'        => __( 'Debug', 'finalpos' ),
			),
			'entity_type' => $entity_type_options,
			'sort_by'     => array(
				'desc' => __( 'Newest first', 'finalpos' ),
				'asc'  => __( 'Oldest first', 'finalpos' ),
			),
		);
	}

	/**
	 * Fetch ecommerce log list from hub API. Uses JWT auth.
	 *
	 * @param int    $page       Page number (1-based).
	 * @param array  $filters    Associative array with optional keys: source, type, entity_type, entity_id, sort_by.
	 * @param string $company_id Optional company ID to pass in query (required for Hub JWT auth).
	 * @return array{success: bool, body: array|null, status_code: int} Response or error structure.
	 */
	public static function fetch_ecommerce_logs( $page, $filters = array(), $company_id = '' ) {
		$query = array(
			'page'  => max( 1, (int) $page ),
			'limit' => FINALPOS_ECOMMERCE_LOG_PER_PAGE,
		);
		if ( $company_id !== '' && $company_id !== null ) {
			$query['companyId'] = $company_id;
		}
		if ( ! empty( $filters['source'] ) ) {
			$query['source'] = $filters['source'];
		}
		if ( ! empty( $filters['type'] ) ) {
			$query['type'] = $filters['type'];
		}
		if ( ! empty( $filters['entity_type'] ) ) {
			$query['entity_type'] = $filters['entity_type'];
		}
		if ( ! empty( $filters['entity_id'] ) ) {
			$query['entity_id'] = $filters['entity_id'];
		}
		if ( ! empty( $filters['sort_by'] ) && ( $filters['sort_by'] === 'asc' || $filters['sort_by'] === 'desc' ) ) {
			$query['sort'] = $filters['sort_by'];
		}

		$endpoint = FINALPOS_API_ECOMMERCE_LOG . '?' . http_build_query( $query );
		$headers  = FinalPOS_Common::get_auth_headers();

		$response = FinalPOS_Common::api_request( $endpoint, 'GET', null, $headers );

		if ( is_wp_error( $response ) ) {
			return array(
				'success'     => false,
				'body'        => null,
				'status_code' => 0,
			);
		}

		return array(
			'success'     => ! empty( $response['success'] ),
			'body'        => isset( $response['body'] ) ? $response['body'] : null,
			'status_code' => isset( $response['status_code'] ) ? $response['status_code'] : 0,
		);
	}

	public static function render() {
		$jwt_token     = get_option( FINALPOS_OPTION_JWT_TOKEN );
		$current_stage = get_option( FINALPOS_OPTION_CURRENT_STAGE );

		// Check if setup is complete.
		if ( $current_stage !== FINALPOS_STAGE_COMPLETE || ! $jwt_token ) {
			echo '<div class="notice notice-error"><p>';
			esc_html_e( 'Final POS setup is not complete. Please complete the setup wizard.', 'finalpos' );
			echo '</p><p><a href="' . esc_url( admin_url( 'admin.php?page=' . FINALPOS_PAGE_SETUP ) ) . '" class="button button-primary">';
			esc_html_e( 'Go to Setup', 'finalpos' );
			echo '</a></p></div>';
			return;
		}

		// Check for coming soon / maintenance mode.
		$site_status = FinalPOS_Common::get_site_status_warnings();

		$company_data  = FinalPOS_Common::get_parsed_jwt_data( 'company' );
		$company_id    = isset( $company_data['id'] ) ? $company_data['id'] : '';
		$sync_status   = null;
		$company_name  = null;
		$has_error     = false;
		$error_message = '';

		// Fetch API status.
		if ( $company_id ) {
			$endpoint = "v1/api/woo-sync/$company_id/status";
			$headers  = FinalPOS_Common::get_auth_headers();

			$response = FinalPOS_Common::api_request( $endpoint, 'GET', null, $headers );

			if ( is_wp_error( $response ) || ! $response['success'] || ! isset( $response['body']['syncStatus'] ) ) {
				$has_error     = true;
				$error_message = sprintf(
					esc_html__( 'Cannot connect to your Final account. Make sure the WooCommerce extension is configured in your Hub account at %s. If the error persists, try uninstalling and reinstalling the plugin.', 'finalpos' ),
					'<a href="https://hub.finalpos.com" target="_blank">hub.finalpos.com</a>'
				);
			} else {
				$sync_status  = $response['body']['syncStatus'];
				$body         = is_array( $response['body'] ) ? $response['body'] : array();
				$company_name = isset( $body['companyName'] ) && is_string( $body['companyName'] ) && $body['companyName'] !== ''
					? $body['companyName']
					: null;
			}
		} else {
			$has_error     = true;
			$error_message = sprintf(
				esc_html__( 'Cannot connect to your Final account. Make sure the WooCommerce extension is configured in your Hub account at %s. If the error persists, try uninstalling and reinstalling the plugin.', 'finalpos' ),
				'<a href="https://hub.finalpos.com" target="_blank">hub.finalpos.com</a>'
			);
		}

		// Check for disabled webhooks.
		$disabled_webhooks = self::get_disabled_webhooks();

		echo '<div class="finalpos-wrap finalpos-dashboard">';

		if ( $has_error ) {
			require_once FINALPOS_PLUGIN_DIR . 'includes/admin/dashboard/views/dashboard-error.php';
			echo '</div>';
			return;
		}

		echo '<div class="finalpos-logo"><img src="' . esc_url( FINALPOS_PLUGIN_URL ) . 'assets/img/final-logo.svg" alt="Final POS Logo"></div>';
		require_once FINALPOS_PLUGIN_DIR . 'includes/admin/dashboard/views/dashboard-content.php';

		if ( $sync_status ) {
			wp_enqueue_script( FINALPOS_HANDLE_DASHBOARD_POLLING, FINALPOS_PLUGIN_URL . 'assets/js/dashboard-polling.js', array( 'jquery' ), FINALPOS_VERSION, true );
			wp_localize_script(
				FINALPOS_HANDLE_DASHBOARD_POLLING,
				'finalposPolling',
				array(
					'ajaxurl'   => admin_url( 'admin-ajax.php' ),
					'nonce'     => wp_create_nonce( FINALPOS_NONCE_POLLING ),
					'companyId' => $company_id,
				)
			);
		}
		echo '</div>';
	}

	/**
	 * Render the Logs sub-menu page.
	 *
	 * @return void
	 */
	public static function render_logs() {
		$filters        = self::get_ecommerce_log_filters();
		$filter_options = self::get_ecommerce_log_filter_options();
		$company_data   = FinalPOS_Common::get_parsed_jwt_data( 'company' );
		$company_id     = isset( $company_data['id'] ) ? $company_data['id'] : '';

		require_once FINALPOS_PLUGIN_DIR . 'includes/admin/dashboard/class-finalpos-logs-list-table.php';
		$logs_list_table = new FinalPOS_Logs_List_Table( $filters, $company_id );

		echo '<div class="finalpos-wrap finalpos-dashboard">';
		echo '<div class="finalpos-logo"><img src="' . esc_url( FINALPOS_PLUGIN_URL ) . 'assets/img/final-logo.svg" alt="Final POS Logo"></div>';
		require_once FINALPOS_PLUGIN_DIR . 'includes/admin/dashboard/views/dashboard-logs-table.php';
		echo '</div>';
	}

	/**
	 * AJAX endpoint to check sync status
	 */
	public static function check_sync_status() {
		check_ajax_referer( FINALPOS_NONCE_POLLING, 'nonce' );

		$company_id    = isset( $_POST['company_id'] ) ? sanitize_text_field( $_POST['company_id'] ) : '';
		$sync_status   = null;
		$has_error     = false;
		$error_message = '';

		if ( $company_id ) {
			$endpoint = "v1/api/woo-sync/$company_id/status";
			$headers  = FinalPOS_Common::get_auth_headers();

			$response = FinalPOS_Common::api_request( $endpoint, 'GET', null, $headers );

			if ( ! is_wp_error( $response ) && $response['success'] && isset( $response['body']['syncStatus'] ) ) {
				$sync_status = $response['body']['syncStatus'];
			}
		}

		wp_send_json_success(
			array(
				'sync_status'   => $sync_status,
				'has_error'     => $has_error,
				'error_message' => $error_message,
			)
		);
	}

	/**
	 * Get all disabled FinalPOS webhooks.
	 *
	 * Uses WooCommerce data store API instead of direct database queries
	 * to ensure compatibility with future WooCommerce database structure changes.
	 *
	 * @return array Array of disabled webhook data.
	 */
	public static function get_disabled_webhooks() {
		if ( ! class_exists( 'WC_Webhook' ) || ! class_exists( 'WC_Data_Store' ) ) {
			return array();
		}

		$disabled_webhooks = array();

		// Use WooCommerce data store to get webhook IDs by status.
		$data_store = WC_Data_Store::load( 'webhook' );

		// Return empty array if data store is not available.
		if ( ! $data_store ) {
			return array();
		}

		// Get webhook IDs for both 'paused' and 'disabled' statuses.
		$paused_webhook_ids   = $data_store->get_webhooks_ids( 'paused' );
		$disabled_webhook_ids = $data_store->get_webhooks_ids( 'disabled' );

		// Ensure we have arrays (WooCommerce methods return arrays, but be defensive).
		$paused_webhook_ids   = is_array( $paused_webhook_ids ) ? $paused_webhook_ids : array();
		$disabled_webhook_ids = is_array( $disabled_webhook_ids ) ? $disabled_webhook_ids : array();

		// Combine and remove duplicates.
		$webhook_ids = array_unique( array_merge( $paused_webhook_ids, $disabled_webhook_ids ) );

		// Extract search term from FINALPOS_WEBHOOK_NAME_PATTERN (remove SQL wildcards).
		// Pattern is '%finalpos%' for SQL LIKE, we need 'finalpos' for string matching.
		$search_term = str_replace( '%', '', FINALPOS_WEBHOOK_NAME_PATTERN );
		$search_term = strtolower( trim( $search_term ) );

		// Check each webhook and collect FinalPOS ones.
		foreach ( $webhook_ids as $webhook_id ) {
			try {
				$webhook      = new WC_Webhook( $webhook_id );
				$webhook_name = $webhook->get_name();
				$status       = $webhook->get_status();

				// Only include FinalPOS webhooks using the constant pattern (case-insensitive check).
				if ( ! empty( $search_term ) && false !== strpos( strtolower( $webhook_name ), $search_term ) ) {
					$disabled_webhooks[ $webhook_id ] = array(
						'id'     => $webhook_id,
						'name'   => $webhook_name,
						'topic'  => $webhook->get_topic(),
						'status' => $status,
					);
				}
			} catch ( \Exception $e ) {
				// TODO: Add proper logging error.
				// Skip invalid webhooks.
				continue;
			}
		}

		return $disabled_webhooks;
	}
}
