<?php

namespace Twnt4All\Backend;

use Twnt4All\Support\Paths;
use Twnt4All\Support\MigrationRunner;

class SchemaMigrator
{
    public static function init()
    {
        add_action( 'wp_ajax_' . T4A_PREFIX . '_db_update', __CLASS__ . '::ajax_apply_db_update' );
        add_action( 'admin_notices', __CLASS__ . '::show_update_admin_notice' );
        add_action( 'init', __CLASS__ . '::apply_db_update' );
    }

    /**
     * Displays the DB update notice if there is a newer version.
     *
     * Guideline 11 : only render on the plugin's own screens plus the
     * generic `plugins.php` listing. Prevents the notice from squatting
     * every admin page while still surfacing on the natural places a user
     * would look to update a plugin.
     */
    public static function show_update_admin_notice()
    {
        $last_db_version = get_option( T4A_PREFIX . '_db_version' );

        if ( empty( $last_db_version ) ) {
            // Initial setup.
            static::update_db();
            return;
        }

        $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
        $allowed = $screen instanceof \WP_Screen && (
            in_array( $screen->id, [ 'plugins', 'plugins-network' ], true )
            || strpos( (string) $screen->id, 'pay4all' ) !== false
            || $screen->post_type === 'p4all_order'
        );
        if ( ! $allowed ) {
            return;
        }

        if ( version_compare( T4A_DB_VERSION, $last_db_version, ">" ) ) {

            $progress = get_option( T4A_PREFIX . '_db_update_progress_' . T4A_DB_VERSION );

            if ( !$progress ) {
                $class   = 'notice notice-warning';
                $message = __( 'Please update the database of the TWINT plugin.', 'pay4all-for-twint' );
                $url     = wp_nonce_url(
                    add_query_arg( [ T4A_PREFIX . "-update" => '1' ], get_admin_url() ),
                    T4A_PREFIX . '_db_update'
                );
                printf(
                    '<div id="' . esc_attr( T4A_PREFIX ) . '-update-notice" class="%1$s"><p>%2$s</p><a href="' . esc_url( $url ) . '" id="' . esc_attr( T4A_PREFIX ) . '-update-db-btn">%3$s</a></div>',
                    esc_attr( $class ),
                    esc_html( $message ),
                    esc_html__( 'Update now', 'pay4all-for-twint' )
                );

            } elseif ( $progress == 'processing' ) {
                $class   = 'notice notice-info';
                $message = __( 'The TWINT database update is in progress. The update is complete when this message disappears', 'pay4all-for-twint' );
                printf( '<div id="' . esc_attr( T4A_PREFIX ) . '-update-notice" class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), esc_html( $message ) );
            }
        }
    }

    /**
     * Applies the TWINT database update.
     */
    public static function apply_db_update()
    {
        // Fast bail-out : keeps this init hook cheap on every unrelated page.
        if ( ! isset( $_GET[ T4A_PREFIX . '-update' ] ) ) {
            return;
        }
        if ( ! current_user_can( 'administrator' ) ) {
            return;
        }
        $nonce = isset( $_GET[ '_wpnonce' ] ) ? sanitize_text_field( wp_unslash( (string) $_GET[ '_wpnonce' ] ) ) : '';
        if ( ! wp_verify_nonce( $nonce, T4A_PREFIX . '_db_update' ) ) {
            return;
        }
        self::update_db();
    }

    /**
     * Applies the TWINT database updat via AJAX request.
     */
    public static function ajax_apply_db_update()
    {
        if ( !check_ajax_referer( T4A_PREFIX . '_update_nonce', 'security' ) )
            return;

        self::update_db();
    }

    /**
     * Contains the database update.
     */
    public static function update_db()
    {
        $progress   = get_option( T4A_PREFIX . '_db_update_progress_' . T4A_DB_VERSION );
        $db_version = get_option( T4A_PREFIX . '_db_version' );
        if ( !$progress && version_compare( T4A_DB_VERSION, $db_version, ">" ) ) {

            flush_rewrite_rules();
            update_option( T4A_PREFIX . '_db_update_progress_' . T4A_DB_VERSION, 'processing' );

            Paths::create_dirs();;

            MigrationRunner::run( T4A_DB_VERSION, $db_version );

            update_option( T4A_PREFIX . '_db_update_progress_' . T4A_DB_VERSION, 'complete' );
            update_option( T4A_PREFIX . '_db_version', T4A_DB_VERSION );

        }
    }

    /**
     * Notice is displayed when the update was successful.
     */
    public static function success_notice()
    {
        ?>
        <div class="notice notice-success is-dismissible">
            <p><?php esc_html_e( 'Database update successful.', 'pay4all-for-twint' ); ?></p>
        </div>
        <?php
    }

}

