<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

add_action( 'admin_post_nopriv_elementsell_thepay_picker', 'elementsell_handle_thepay_picker' );
add_action( 'admin_post_elementsell_thepay_picker', 'elementsell_handle_thepay_picker' );

/**
 * Mezistránka výběru platby běží na vašem webu (plugin), ne na gate.thepay.cz.
 * Odkazy vede ThePay API endpoint payment_urls – stejný zdroj jako getPaymentButtonsForPayment().
 *
 * @param string $payment_uid
 * @return string
 */
function elementsell_get_thepay_picker_url( $payment_uid ) {
    return add_query_arg(
        [
            'action'      => 'elementsell_thepay_picker',
            'payment_uid' => rawurlencode( (string) $payment_uid ),
        ],
        admin_url( 'admin-post.php' )
    );
}

/**
 * @param object $order
 * @return \ThePay\ApiClient\TheClient|WP_Error
 */
function elementsell_get_thepay_client_for_order( $order ) {
    elementsell_load_thepay_autoload();

    $credentials = elementsell_get_thepay_credentials_for_order( $order );

    if (
        $credentials['merchant_id'] === ''
        || $credentials['project_id'] <= 0
        || $credentials['api_password'] === ''
    ) {
        return new WP_Error( 'elementsell_thepay_credentials', 'Chybí údaje k ThePay.' );
    }

    return elementsell_create_thepay_client(
        $credentials['merchant_id'],
        $credentials['project_id'],
        $credentials['api_password'],
        $credentials['api_url'],
        $credentials['gate_url']
    );
}

/**
 * @param \ThePay\ApiClient\Model\PaymentMethodWithPayUrl $method
 * @return bool
 */
function elementsell_thepay_method_is_excluded( $method ) {
    $tags = $method->getTags();

    foreach ( [ 'alternative_method', 'deferred_payment' ] as $tag ) {
        if ( in_array( $tag, $tags, true ) ) {
            return true;
        }
    }

    return false;
}

/**
 * @param \ThePay\ApiClient\Model\PaymentMethodWithPayUrl $method
 * @return bool
 */
function elementsell_thepay_method_is_individual_bank( $method ) {
    $code = $method->getCode();
    $tags = $method->getTags();

    if ( in_array( 'card', $tags, true ) ) {
        return false;
    }

    if ( stripos( $code, 'apple' ) !== false || stripos( $code, 'google' ) !== false ) {
        return false;
    }

    if ( $code === 'platba_24' ) {
        return false;
    }

    // Ruční převod ("Platba z jiné banky") nemá tag online – není to banka,
    // ale stránka s číslem účtu a variabilním symbolem. Řešíme ji zvlášť.
    if ( ! in_array( 'online', $tags, true ) ) {
        return false;
    }

    return in_array( 'access_account_owner', $tags, true );
}

/**
 * Otisk loga pro odhalení vizuálních duplicit.
 *
 * ThePay dává do URL parametr `id`, což je hash obsahu obrázku. Dvě různé metody
 * tak můžou mít jiný název souboru i jiný titulek, ale stejné logo – např. `ekonto`
 * („ePlatby") a `rb` („Raiffeisenbank"), protože eKonto je produkt Raiffeisenbank.
 * V nabídce by se pak Raiffeisen ukázal dvakrát a zákazník nepozná rozdíl.
 *
 * @param string $logo
 * @return string
 */
function elementsell_thepay_logo_fingerprint( $logo ) {
    $logo = (string) $logo;

    if ( $logo === '' ) {
        return '';
    }

    $query = (string) wp_parse_url( $logo, PHP_URL_QUERY );

    if ( $query !== '' ) {
        $args = [];
        wp_parse_str( $query, $args );

        if ( ! empty( $args['id'] ) ) {
            return (string) $args['id'];
        }
    }

    return $logo;
}

/**
 * @param string $title
 * @return bool
 */
function elementsell_thepay_title_looks_like_bank( $title ) {
    return (bool) preg_match( '/bank|spořitel|sporitel|kampelič|kampelic/iu', (string) $title );
}

/**
 * Ruční převod – zákazník dostane číslo účtu a variabilní symbol.
 * V ThePay je to metoda `transfer` (bank_transfer bez tagu online).
 *
 * @param \ThePay\ApiClient\Model\PaymentMethodWithPayUrl $method
 * @return bool
 */
function elementsell_thepay_method_is_manual_transfer( $method ) {
    $tags = $method->getTags();

    return in_array( 'bank_transfer', $tags, true )
        && ! in_array( 'online', $tags, true )
        && ! in_array( 'card', $tags, true );
}

/**
 * @param array<\ThePay\ApiClient\Model\PaymentMethodWithPayUrl> $methods
 * @return array<int, array{label: string, subtitle: string, method: \ThePay\ApiClient\Model\PaymentMethodWithPayUrl}>
 */
function elementsell_build_simplified_thepay_method_groups( $methods ) {
    $available = [];

    foreach ( $methods as $method ) {
        if ( elementsell_thepay_method_is_excluded( $method ) ) {
            continue;
        }

        $available[ $method->getCode() ] = $method;
    }

    // Banky vytáhneme vždy (ne jen když existuje platba_24) a necháme si u nich
    // i odkaz – zákazník tak klikne rovnou na svou banku, bez mezikroku na bráně.
    $banks      = [];
    $manual     = null;
    $seen_logos = [];

    foreach ( $available as $code => $method ) {
        if ( elementsell_thepay_method_is_individual_bank( $method ) ) {
            $logo        = (string) $method->getImageUrl();
            $title       = (string) $method->getTitle();
            $fingerprint = elementsell_thepay_logo_fingerprint( $logo );

            // Stejné logo už v nabídce je – druhá dlaždice by byla k nerozeznání.
            if ( $fingerprint !== '' && isset( $seen_logos[ $fingerprint ] ) ) {
                $kept = $seen_logos[ $fingerprint ];

                // Z dvojice se stejným logem chceme tu, která se jmenuje jako banka
                // ("Raiffeisenbank"), ne jako produkt ("ePlatby") – tu lidé hledají.
                if (
                    elementsell_thepay_title_looks_like_bank( $title )
                    && ! elementsell_thepay_title_looks_like_bank( $banks[ $kept ]['title'] )
                ) {
                    $banks[ $kept ] = [
                        'title' => $title,
                        'logo'  => $logo,
                        'url'   => (string) $method->getPayUrl(),
                    ];
                }

                unset( $available[ $code ] );
                continue;
            }

            $banks[] = [
                'title' => $title,
                'logo'  => $logo,
                'url'   => (string) $method->getPayUrl(),
            ];

            if ( $fingerprint !== '' ) {
                $seen_logos[ $fingerprint ] = array_key_last( $banks );
            }

            unset( $available[ $code ] );
            continue;
        }

        if ( ! $manual && elementsell_thepay_method_is_manual_transfer( $method ) ) {
            $manual = [
                'title' => (string) $method->getTitle(),
                'url'   => (string) $method->getPayUrl(),
            ];

            unset( $available[ $code ] );
        }
    }

    $groups = [];
    $used   = [];
    $pick   = static function ( $codes ) use ( $available, &$used ) {
        foreach ( (array) $codes as $code ) {
            if ( isset( $available[ $code ] ) && ! in_array( $code, $used, true ) ) {
                $used[] = $code;
                return $available[ $code ];
            }
        }

        return null;
    };
    $pick_match = static function ( $callback ) use ( $available, &$used ) {
        foreach ( $available as $code => $method ) {
            if ( in_array( $code, $used, true ) ) {
                continue;
            }

            if ( $callback( $method ) ) {
                $used[] = $code;
                return $method;
            }
        }

        return null;
    };
    $add = static function ( $method, $label, $subtitle = '', $badge = '' ) use ( &$groups ) {
        if ( ! $method ) {
            return;
        }

        $groups[] = [
            'type'     => 'method',
            'label'    => $label,
            'subtitle' => $subtitle,
            'badge'    => (string) $badge,
            'method'   => $method,
        ];
    };

    // Platba 24 (když ji projekt má) zvládne výběr banky sama za jedním odkazem.
    $instant = $pick( [ 'platba_24', 'payment_button' ] );

    if ( $instant ) {
        $add( $instant, 'Zaplatit převodem', 'a další banky', 'QR kód' );
    } elseif ( $banks || $manual ) {
        // Jinak nabídneme banky rovnou tady – jeden klik na svou banku.
        $groups[] = [
            'type'   => 'banks',
            'label'  => 'Zaplatit převodem',
            'badge'  => 'QR kód',
            'banks'  => $banks,
            'manual' => $manual,
        ];
    }

    $add( $pick( [ 'card' ] ), 'Zaplatit platební kartou' );
    $add(
        $pick_match(
            static function ( $method ) {
                return stripos( $method->getCode(), 'apple' ) !== false;
            }
        ),
        'Zaplatit přes Apple Pay'
    );
    $add(
        $pick_match(
            static function ( $method ) {
                return stripos( $method->getCode(), 'google' ) !== false;
            }
        ),
        'Zaplatit přes Google Pay'
    );

    return $groups;
}

/**
 * @param object $order
 * @return array<\ThePay\ApiClient\Model\PaymentMethodWithPayUrl>|WP_Error
 */
function elementsell_get_thepay_payment_methods_for_order( $order ) {
    $client = elementsell_get_thepay_client_for_order( $order );

    if ( is_wp_error( $client ) ) {
        return $client;
    }

    try {
        return $client->getPaymentUrlsForPayment( (string) $order->payment_uid, 'cs' );
    } catch ( Exception $e ) {
        return new WP_Error( 'elementsell_thepay_methods', $e->getMessage() );
    }
}

/**
 * Odkaz z oficiálního ThePay SDK pro existující platbu (bez POST formuláře).
 *
 * @param \ThePay\ApiClient\Model\PaymentMethodWithPayUrl $method
 * @param string                                          $label
 * @param string                                          $subtitle
 * @return string
 */
function elementsell_render_thepay_method_link( $method, $label, $subtitle = '', $badge = '' ) {
    $url = (string) $method->getPayUrl();

    if ( $url === '' ) {
        return '';
    }

    $logo = (string) $method->getImageUrl();

    $html  = '<a class="elementsell-thepay-option" href="' . esc_url( $url ) . '"';
    $html .= ' data-thepay="payment-button" data-payment-method="' . esc_attr( $method->getCode() ) . '">';
    $html .= '<p class="elementsell-thepay-option__title">' . esc_html( $label );
    $html .= elementsell_render_thepay_badge( $badge );
    $html .= '</p>';

    if ( $logo !== '' ) {
        $html .= '<span class="elementsell-thepay-option__logos">'
            . '<img class="elementsell-thepay-option__logo" src="' . esc_url( $logo ) . '" alt="">'
            . '</span>';
    }

    if ( $subtitle !== '' ) {
        $html .= '<span class="elementsell-thepay-option__subtitle">' . esc_html( $subtitle ) . '</span>';
    }

    $html .= '</a>';

    return $html;
}

/**
 * @param string $badge
 * @return string
 */
function elementsell_render_thepay_badge( $badge ) {
    if ( (string) $badge === '' ) {
        return '';
    }

    return ' <span class="elementsell-thepay-option__badge">'
        . '<span class="elementsell-thepay-option__badge-icon" aria-hidden="true">&#9635;</span>'
        . esc_html( $badge ) . '</span>';
}

/**
 * Dlaždice s výběrem banky – každá banka je vlastní odkaz, takže zákazník
 * klikne rovnou na svou a nemusí ji hledat o patro níž na bráně ThePay.
 *
 * @param array{label: string, badge: string, banks: array<int, array{title: string, logo: string, url: string}>, manual: array{title: string, url: string}|null} $group
 * @return string
 */
function elementsell_render_thepay_bank_picker( $group ) {
    $banks  = isset( $group['banks'] ) ? (array) $group['banks'] : [];
    $manual = isset( $group['manual'] ) ? $group['manual'] : null;

    if ( empty( $banks ) && empty( $manual ) ) {
        return '';
    }

    $html  = '<div class="elementsell-thepay-option elementsell-thepay-option--banks">';
    $html .= '<p class="elementsell-thepay-option__title">' . esc_html( $group['label'] );
    $html .= elementsell_render_thepay_badge( isset( $group['badge'] ) ? $group['badge'] : '' );
    $html .= '</p>';

    if ( ! empty( $banks ) ) {
        $html .= '<span class="elementsell-thepay-banks">';

        foreach ( $banks as $bank ) {
            if ( empty( $bank['url'] ) ) {
                continue;
            }

            $html .= '<a class="elementsell-thepay-bank" href="' . esc_url( $bank['url'] ) . '"'
                . ' title="' . esc_attr( $bank['title'] ) . '" data-thepay="payment-button">';

            if ( ! empty( $bank['logo'] ) ) {
                $html .= '<img class="elementsell-thepay-bank__logo" src="' . esc_url( $bank['logo'] ) . '"'
                    . ' alt="' . esc_attr( $bank['title'] ) . '">';
            } else {
                $html .= esc_html( $bank['title'] );
            }

            $html .= '</a>';
        }

        $html .= '</span>';
    }

    if ( ! empty( $manual['url'] ) ) {
        $html .= '<a class="elementsell-thepay-manual" href="' . esc_url( $manual['url'] ) . '" data-thepay="payment-button">'
            . 'Nemám tu svou banku – chci číslo účtu a variabilní symbol'
            . '</a>';
    }

    $html .= '</div>';

    return $html;
}

/**
 * @param object $order
 * @param array<int, array{label: string, subtitle: string, method: \ThePay\ApiClient\Model\PaymentMethodWithPayUrl}> $groups
 * @return void
 */
function elementsell_render_thepay_method_picker( $order, $groups ) {
    $amount = number_format( (float) $order->amount, 0, ',', ' ' );
    $back   = elementsell_get_order_source_page_url_with_form( $order );

    status_header( 200 );
    nocache_headers();
    ?>
    <!DOCTYPE html>
    <html <?php language_attributes(); ?>>
    <head>
        <meta charset="<?php bloginfo( 'charset' ); ?>">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title><?php esc_html_e( 'Výběr platby', 'platebni-formular' ); ?></title>
        <style>
            * { box-sizing: border-box; }
            body {
                margin: 0;
                min-height: 100vh;
                background: #2f3136;
                color: #1f2a44;
                font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
            }
            .elementsell-thepay-shell {
                min-height: 100vh;
                display: flex;
                flex-direction: column;
            }
            .elementsell-thepay-top {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 18px 24px;
            }
            .elementsell-thepay-back {
                display: inline-flex;
                align-items: center;
                gap: 8px;
                padding: 10px 14px;
                border: 1px solid #d7dbe7;
                border-radius: 8px;
                background: #fff;
                color: #1f2a44;
                text-decoration: none;
                font-size: 14px;
            }
            .elementsell-thepay-amount {
                margin: 0;
                padding: 0 24px 12px;
                text-align: center;
                color: #f3f4f6;
                font-size: 15px;
            }
            .elementsell-thepay-main {
                flex: 1;
                display: flex;
                align-items: flex-start;
                justify-content: center;
                padding: 8px 16px 32px;
            }
            .elementsell-thepay-card {
                width: 100%;
                max-width: 570px;
                display: flex;
                flex-direction: column;
                gap: 12px;
                padding: 16px;
                background: #fff;
                border-radius: 12px;
                box-shadow: 0 8px 28px rgba(0, 0, 0, 0.18);
            }
            .elementsell-thepay-option {
                display: block;
                padding: 20px 24px 18px;
                border: 0;
                border-radius: 10px;
                background: #eef1fd;
                color: inherit;
                text-decoration: none;
                text-align: center;
                transition: background 0.15s ease;
            }
            .elementsell-thepay-option:hover {
                background: #e4e9fc;
            }
            .elementsell-thepay-option__title {
                display: flex;
                align-items: center;
                justify-content: center;
                flex-wrap: wrap;
                gap: 10px;
                margin: 0 0 14px;
                font-size: 19px;
                font-weight: 700;
                color: #64708a;
            }
            .elementsell-thepay-option__badge {
                display: inline-flex;
                align-items: center;
                gap: 5px;
                padding: 5px 10px;
                border-radius: 6px;
                background: #d8dffb;
                color: #3a4a7a;
                font-size: 14px;
                font-weight: 600;
                white-space: nowrap;
            }
            .elementsell-thepay-option__badge-icon {
                font-size: 13px;
                line-height: 1;
            }
            .elementsell-thepay-option__logos {
                display: flex;
                align-items: center;
                justify-content: center;
                flex-wrap: wrap;
                gap: 12px;
            }
            /* Loga musí být malá, aby se pětice bank vešla do jedné řady. */
            .elementsell-thepay-option__logo {
                display: block;
                max-width: 84px;
                max-height: 28px;
                width: auto;
                height: auto;
            }
            /* Jediné logo (karta, Apple Pay, Google Pay) může být větší. */
            .elementsell-thepay-option__logos > .elementsell-thepay-option__logo:only-child {
                max-width: 200px;
                max-height: 40px;
            }
            .elementsell-thepay-option__subtitle {
                display: block;
                margin-top: 10px;
                font-size: 14px;
                color: #5f6b7a;
            }
            /* Výběr banky – dlaždice není odkaz, klikací jsou jednotlivé banky. */
            .elementsell-thepay-option--banks:hover {
                background: #eef1fd;
            }
            .elementsell-thepay-banks {
                display: grid;
                grid-template-columns: repeat(5, 1fr);
                gap: 6px;
            }
            .elementsell-thepay-bank {
                display: flex;
                align-items: center;
                justify-content: center;
                padding: 5px 4px;
                min-height: 34px;
                border-radius: 6px;
                background: #fff;
                border: 1px solid #dfe4f7;
                text-decoration: none;
                color: #3a4a7a;
                font-size: 11px;
                font-weight: 600;
                text-align: center;
                transition: border-color 0.15s ease, box-shadow 0.15s ease;
            }
            .elementsell-thepay-bank:hover {
                border-color: #7c8fd6;
                box-shadow: 0 2px 8px rgba(31, 42, 68, 0.12);
            }
            .elementsell-thepay-bank__logo {
                display: block;
                max-width: 100%;
                max-height: 17px;
                width: auto;
                height: auto;
            }
            .elementsell-thepay-manual {
                display: block;
                margin-top: 14px;
                color: #3a4a7a;
                font-size: 14px;
                font-weight: 600;
                text-decoration: underline;
            }
            .elementsell-thepay-manual:hover {
                color: #1f2a44;
            }
            @media (max-width: 480px) {
                .elementsell-thepay-option {
                    padding: 18px 14px 16px;
                }
                .elementsell-thepay-option__title {
                    font-size: 17px;
                }
                .elementsell-thepay-option__logos {
                    gap: 8px;
                }
                .elementsell-thepay-option__logo {
                    max-width: 64px;
                    max-height: 22px;
                }
                .elementsell-thepay-option__logos > .elementsell-thepay-option__logo:only-child {
                    max-width: 160px;
                    max-height: 34px;
                }
                .elementsell-thepay-banks {
                    grid-template-columns: repeat(4, 1fr);
                    gap: 5px;
                }
                .elementsell-thepay-bank {
                    min-height: 32px;
                    padding: 4px 3px;
                }
                .elementsell-thepay-bank__logo {
                    max-height: 15px;
                }
                .elementsell-thepay-manual {
                    font-size: 13px;
                }
            }
            .elementsell-thepay-footer {
                padding: 24px 16px 32px;
                text-align: center;
                color: #d1d5db;
                font-size: 13px;
            }
        </style>
    </head>
    <body>
        <div class="elementsell-thepay-shell">
            <div class="elementsell-thepay-top">
                <a class="elementsell-thepay-back" href="<?php echo esc_url( $back ); ?>">&times; Návrat na web</a>
            </div>
            <p class="elementsell-thepay-amount"><?php echo esc_html( $amount ); ?> Kč</p>
            <div class="elementsell-thepay-main">
                <div class="elementsell-thepay-card">
                    <?php
                    foreach ( $groups as $group ) {
                        if ( isset( $group['type'] ) && $group['type'] === 'banks' ) {
                            echo elementsell_render_thepay_bank_picker( $group );
                            continue;
                        }

                        echo elementsell_render_thepay_method_link(
                            $group['method'],
                            $group['label'],
                            $group['subtitle'],
                            isset( $group['badge'] ) ? $group['badge'] : ''
                        );
                    }
                    ?>
                </div>
            </div>
            <div class="elementsell-thepay-footer">Bezpečnou a rychlou platbu zařídí ThePay</div>
        </div>
    </body>
    </html>
    <?php
}

/**
 * @param string $fallback_url
 * @return void
 */
function elementsell_redirect_to_thepay_fallback( $fallback_url ) {
    if ( $fallback_url !== '' ) {
        wp_safe_redirect( $fallback_url );
        exit;
    }

    wp_die( 'Platební metody se nepodařilo načíst. Zkuste to prosím znovu.' );
}

/**
 * @return void
 */
function elementsell_handle_thepay_picker() {
    $payment_uid = isset( $_GET['payment_uid'] ) ? sanitize_text_field( wp_unslash( $_GET['payment_uid'] ) ) : '';
    $order       = $payment_uid ? elementsell_get_order_by_payment_uid( $payment_uid ) : null;

    if ( ! $order ) {
        wp_die( 'Objednávka nebyla nalezena.' );
    }

    $fallback_url = trim( (string) $order->pay_url );
    $methods      = elementsell_get_thepay_payment_methods_for_order( $order );

    if ( is_wp_error( $methods ) ) {
        error_log( 'ElementSell ThePay picker: ' . $methods->get_error_message() );
        elementsell_redirect_to_thepay_fallback( $fallback_url );
    }

    $groups = elementsell_build_simplified_thepay_method_groups( $methods );

    // Jediná metoda → rovnou na ni. Výběr banky ale musí zůstat na stránce,
    // jinak by zákazník skončil u jedné konkrétní banky bez možnosti volby.
    if ( count( $groups ) === 1 && ( $groups[0]['type'] ?? 'method' ) === 'method' ) {
        $url = (string) $groups[0]['method']->getPayUrl();

        if ( $url !== '' ) {
            wp_safe_redirect( $url );
            exit;
        }

        elementsell_redirect_to_thepay_fallback( $fallback_url );
    }

    if ( empty( $groups ) ) {
        elementsell_redirect_to_thepay_fallback( $fallback_url );
    }

    elementsell_render_thepay_method_picker( $order, $groups );
    exit;
}
