<?php

namespace PixelYourSite;

class AnyFormScanner {

    private static $_instance;

    private $dom;

    public static function instance() {
        if ( is_null( self::$_instance ) ) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }
    public function __construct() {
        add_action( 'wp_ajax_pys_scan_any_form', [ $this, 'scan_handler' ] );

        add_action( 'template_redirect', function () {
            if ( isset( $_GET['pys_fake_cart'] ) && is_checkout() ) {
                if ( WC()->cart && WC()->cart->is_empty() ) {
                    $product_id = $this->pys_get_first_simple_product_id();

                    if ( $product_id ) {
                        WC()->cart->add_to_cart( $product_id, 1 );
                    }
                }
            }
            if ( isset($_GET['pys_fake_cart']) && function_exists( 'edd_is_checkout' ) &&
                edd_is_checkout() && !edd_get_cart_contents() ) {

                $download_id = $this->pys_get_first_edd_download_id();

                if ( $download_id ) {
                    edd_empty_cart(); // очистим на всякий случай
                    edd_add_to_cart( $download_id );
                }
            }
        }, 1 );
    }

    public function scan_handler() {
        if ( ! current_user_can( 'manage_pys' ) ) {
            wp_send_json_error( 'Unauthorized', 403 );
        }

        $nonce = $_REQUEST['_wpnonce'] ?? null;
        if ( ! wp_verify_nonce( $nonce, 'pys_update_event' ) && ! wp_verify_nonce( $nonce, 'pys_save_settings' ) ) {
            wp_send_json_error( 'Invalid nonce', 403 );
        }

        $urls = isset( $_POST['urls'] ) ? $_POST['urls'] : [];

        if ( empty( $urls ) || ! is_array( $urls ) ) {
            wp_send_json_error( 'Invalid URLs' );
        }

        $results = [];

        foreach ( $urls as $url ) {
            $parsed_url = wp_parse_url( $url );
            $clean_url = rtrim( $parsed_url['scheme'] . '://' . $parsed_url['host'] . $parsed_url['path'], '/' );
            $url_with_fake_cart = add_query_arg(
                [
                    'pys_fake_cart' => 1,
                    'ship_to_different_address' => 1
                ],
                $clean_url
            );

            $html = $this->fetch_url_content( $url_with_fake_cart );

            if ( ! $html ) {
                $results[] = [
                    'url' => $url_with_fake_cart,
                    'error' => 'Failed to fetch content'
                ];
                continue;
            }

            $forms_data = $this->parse_forms( $html );
            $results[] = [
                'url'   => $url,
                'forms' => $forms_data
            ];
        }

        wp_send_json_success( $results );
    }

    private function fetch_url_content( $url ) {
        $response = wp_safe_remote_get( $url, [
            'timeout' => 5,
        ] );
        if ( is_wp_error( $response ) ) {
            return false;
        }

        return wp_remote_retrieve_body( $response );
    }

    private function parse_forms( $html ) {
        libxml_use_internal_errors( true );
        $this->dom = new \DOMDocument();
        $this->dom->loadHTML( $html );
        $xpath = new \DOMXPath( $this->dom );

        $forms = $this->dom->getElementsByTagName( 'form' );

        $results = [];

        foreach ( $forms as $form ) {
            $form_info = [];

            // Найти заголовок формы: H1 > H2 > ID/class
            $form_info['title'] = $this->find_form_title( $form, $xpath );
            $form_info['attributes'] = [
                'id'    => $form->getAttribute( 'id' ),
                'class' => $form->getAttribute( 'class' ),
                'action' => $form->getAttribute( 'action' ),
                'method' => $form->getAttribute( 'method' ),
            ];
            $form_info['selector'] = $this->generate_css_selector( $form );


            $fields = [];
            $field_tags = ['input', 'textarea', 'select'];

            foreach ( $field_tags as $tag ) {
                $elements = $form->getElementsByTagName( $tag );

                foreach ( $elements as $el ) {
                    $type = '';

                    if($el->getAttribute('type') === 'hidden') {
                        continue; // Пропускаем скрытые поля
                    }

                    if ( $tag === 'input' ) {
                        // если не указан, по умолчанию — text
                        $type = $el->hasAttribute('type')
                            ? $el->getAttribute('type')
                            : 'text';
                    } elseif ( $tag === 'textarea' ) {
                        $type = 'textarea';
                    } elseif ( $tag === 'select' ) {
                        $type = 'select';
                    }

                    $field = [
                        'tag'         => $tag,
                        'name'        => $el->getAttribute( 'name' ),
                        'id'          => $el->getAttribute( 'id' ),
                        'class'       => $el->getAttribute( 'class' ),
                        'type'        => $type,
                    ];

                    // Уникальный селектор
                    $field['selector'] = $this->generate_css_selector( $el );

                    $fields[] = $field;
                }
            }

            $form_info['fields'] = $fields;
            $results[] = $form_info;
        }

        return $results;
    }

    private function find_form_title( \DOMElement $form ) {
        $max_depth = 2;
        $current   = $form->parentNode;

        for ( $i = 0; $i < $max_depth && $current instanceof \DOMElement; $i++ ) {
            foreach ( ['h1', 'h2'] as $tag ) {
                $headings = $current->getElementsByTagName( $tag );
                if ( $headings->length > 0 ) {
                    return trim( $headings->item(0)->textContent );
                }
            }

            $current = $current->parentNode;
        }

        // fallback: id или class формы
        $id    = $form->getAttribute( 'id' );
        $class = $form->getAttribute( 'class' );

        if ( ! empty( $id ) ) {
            return "Form #$id";
        } elseif ( ! empty( $class ) ) {
            return "Form .$class";
        }

        return 'Unnamed form';
    }

    private function generate_css_selector( \DOMElement $el ) {
        $parts = [];
        $depth = 0;
        $max_depth = 6;

        while ( $el && $el->nodeType === XML_ELEMENT_NODE && $depth < $max_depth ) {
            $selector = $el->nodeName;

            if ( $el->hasAttribute( 'id' ) ) {
                $selector .= '#' . $el->getAttribute( 'id' );
                $parts[] = $selector;
                break;
            } elseif ( $el->hasAttribute( 'class' ) ) {
                $class = preg_split( '/\s+/', $el->getAttribute( 'class' ) );
                $selector .= '.' . implode( '.', array_filter( $class ) );
            }

            $parts[] = $selector;
            $el = $el->parentNode;
            $depth++;
        }

        return implode( ' > ', array_reverse( $parts ) );
    }

    private function pys_get_first_simple_product_id() {
        $args = [
            'post_type'      => 'product',
            'post_status'    => 'publish',
            'posts_per_page' => 1,
            'orderby'        => 'date',
            'order'          => 'ASC',
            'meta_query'     => [
                [
                    'key'     => '_stock_status',
                    'value'   => 'instock',
                    'compare' => '='
                ]
            ],
            'tax_query' => [
                [
                    'taxonomy' => 'product_type',
                    'field'    => 'slug',
                    'terms'    => [ 'simple' ]
                ]
            ]
        ];

        $query = new \WP_Query( $args );

        if ( $query->have_posts() ) {
            return $query->posts[0]->ID;
        }

        return false;
    }

    function pys_get_first_edd_download_id() {
        $args = [
            'post_type'      => 'download',
            'post_status'    => 'publish',
            'posts_per_page' => 1,
            'orderby'        => 'date',
            'order'          => 'ASC',
        ];

        $query = new \WP_Query( $args );

        if ( $query->have_posts() ) {
            return $query->posts[0]->ID;
        }

        return false;
    }

}

/**
 * @return AnyFormScanner
 */
function AnyFormScanner() {
    return AnyFormScanner::instance();
}

AnyFormScanner();