<?php

namespace HelpGent\Database\Migrations;

defined( 'ABSPATH' ) || exit;

class Query {
    public static function insert_data( $table_name, $data ) {
        global $wpdb;

        $table_name = "{$wpdb->prefix}$table_name";

        $columns = implode( ', ', array_keys( $data ) );
        $values  = implode( ', ', array_values( $data ) );

        return self::execute( "INSERT INTO %1s ( %1s ) VALUES ( %1s )", [ $table_name, $columns, $values ] );
    }

    public static function remove_tables( array $tables ): void {
        global $wpdb;

        $prefix = $wpdb->prefix;

        foreach ( $tables as $table_name ) {
            $table_name = "{$prefix}{$table_name}"; 
            self::execute( "DROP TABLE IF EXISTS %i", [ $table_name ] );
        }
    }

    public static function table_exists( string $table_name, string $prefix = '' ): bool {
        global $wpdb;

        $prefix = ! empty( $prefix ) ? $prefix : $wpdb->prefix;

        $result = self::execute( 
            "SELECT *  FROM information_schema.tables WHERE table_schema = '%s' AND table_name = '%s' LIMIT 1",
            [ DB_NAME, "{$prefix}{$table_name}" ]
        );

        return $result === 1;
    }

    public static function drop_table_columns( array $tables ): void {
        global $wpdb;

        $prefix = $wpdb->prefix;

        foreach ( array_keys( $tables ) as $table_key ) {
            $table_name = "{$prefix}{$table_key}";
            $columns    = $tables[ $table_key ];

            foreach ( $columns as $column ) {
                if ( self::execute( "SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = %s AND TABLE_SCHEMA = %s AND COLUMN_NAME = %s", [ $table_name, DB_NAME, $column ] ) ) {
                    self::execute( "ALTER TABLE %i DROP COLUMN %i", [ $table_name, $column ] );
                }
            }
        }
    }

    /**
     * Performs a database query, using current database connection.
     *
     * @param string $query Database query.
     * @return int|bool Boolean true for CREATE, ALTER, TRUNCATE and DROP queries. Number of rows
     *                  affected/selected for all other queries. Boolean false on error.
     */
    public static function execute( $query, ...$args ) {
        global $wpdb;

        if ( ! $wpdb->has_cap( 'identifier_placeholders' ) ) {
            $query = str_replace( '%i', '%s', $query );
        }

        if ( empty( $args ) ) {
            // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
            return $wpdb->query( $query );
        }

        // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnquotedComplexPlaceholder, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQLPlaceholders.UnsupportedPlaceholder, WordPress.DB.PreparedSQL.NotPrepared
        return $wpdb->query( $wpdb->prepare( $query, ...$args ) );
    }

    public static function safe_query( callable $callback, array $args = [], $default_value = null ) {
        ob_start();

        $result = call_user_func_array( $callback, $args );

        $content = ob_get_clean();

        if ( ! empty( $content ) ) {
            return $default_value;
        }

        return $result;
    }
}