<?php
/**
 * BankTransferGateway — offline payment via bank/wire transfer.
 *
 * @package TitanCart\Modules\Payments\Gateways
 */

namespace TitanCart\Modules\Payments\Gateways;

use TitanCart\Modules\Payments\AbstractGateway;

defined( 'ABSPATH' ) || exit;

class BankTransferGateway extends AbstractGateway {

    const SLUG = 'bank_transfer';

    // ══════════════════════════════════════════════════════════════════════════
    // INTERFACE IMPLEMENTATION
    // ══════════════════════════════════════════════════════════════════════════

    public function get_label(): string {
        return __( 'Bank / Wire Transfer', 'titancart-lite' );
    }

    public function get_settings_fields(): array {
        return [
            [
                'key'   => 'account_name',
                'label' => __( 'Account Name', 'titancart-lite' ),
                'type'  => 'text',
                'hint'  => __( 'The name on the bank account customers will send payment to.', 'titancart-lite' ),
            ],
            [
                'key'   => 'account_number',
                'label' => __( 'Account Number / IBAN', 'titancart-lite' ),
                'type'  => 'text',
                'hint'  => __( 'Your bank account number. For international transfers, use your IBAN.', 'titancart-lite' ),
            ],
            [
                'key'   => 'bank_name',
                'label' => __( 'Bank Name', 'titancart-lite' ),
                'type'  => 'text',
                'hint'  => __( 'Full name of your bank (e.g. "Chase Bank", "Barclays").', 'titancart-lite' ),
            ],
            [
                'key'   => 'routing_number',
                'label' => __( 'Routing / SWIFT / BIC', 'titancart-lite' ),
                'type'  => 'text',
                'hint'  => __( 'US: 9-digit routing number. International: SWIFT/BIC code (e.g. CHASUS33).', 'titancart-lite' ),
            ],
            [
                'key'   => 'additional_instructions',
                'label' => __( 'Additional Instructions', 'titancart-lite' ),
                'type'  => 'textarea',
                'hint'  => __( 'Any extra info customers need (e.g. "Include your order number as payment reference").', 'titancart-lite' ),
            ],
        ];
    }

    /**
     * Bank transfer is always available — no external charge is taken here.
     * The order is placed in 'open' (awaiting payment) status.
     *
     * {@inheritdoc}
     */
    public function process_payment( int $order_id, array $order, array $settings ): array {
        // Log a zero-value pending transaction for audit trail consistency.
        $this->log_transaction(
            $order_id,
            (int) ( $order['payment_method_id'] ?? 0 ),
            self::SLUG,
            'bt-' . $order_id,
            (float) ( $order['total'] ?? 0 ),
            $order['currency'] ?? 'USD',
            'charge',
            'pending',
            [ 'note' => 'Bank transfer — awaiting manual payment.' ]
        );

        // Leave order in 'open' status; admin will manually mark as paid.
        $this->set_order_status(
            $order_id,
            'open',
            __( 'Order placed via Bank Transfer. Awaiting receipt of payment.', 'titancart-lite' ),
            true
        );

        return $this->success_result(
            'bt-' . $order_id,
            __( 'Thank you. Please transfer the funds to the bank account below. Your order will be confirmed once payment is received.', 'titancart-lite' ),
            [ 'instructions' => $this->build_instructions( $settings ) ]
        );
    }

    /**
     * Bank transfer refunds are manual — record the refund and update status.
     *
     * {@inheritdoc}
     */
    public function refund( int $order_id, string $transaction_id, float $amount, array $settings ): array {
        $order_row = $this->db->getRow(
            "SELECT * FROM {$this->db->table('orders')} WHERE id = ?i",
            $order_id
        );

        $this->log_transaction(
            $order_id,
            (int) ( $order_row['payment_method_id'] ?? 0 ),
            self::SLUG,
            'bt-refund-' . $order_id . '-' . time(),
            $amount,
            $order_row['currency'] ?? 'USD',
            'refund',
            'completed',
            [ 'note' => 'Manual bank transfer refund recorded.' ]
        );

        $this->set_order_status(
            $order_id,
            'refunded',
            __( 'Bank transfer refund recorded manually.', 'titancart-lite' ),
            true
        );

        return [
            'success'   => true,
            'refund_id' => 'bt-refund-' . $order_id,
            'message'   => __( 'Refund recorded. Please ensure the funds are returned to the customer via bank transfer.', 'titancart-lite' ),
        ];
    }

    // ══════════════════════════════════════════════════════════════════════════
    // POST-CHECKOUT INSTRUCTIONS
    // ══════════════════════════════════════════════════════════════════════════

    /**
     * Render bank-transfer instructions on order-received + account order-detail
     * pages. Delegates to the existing build_instructions() helper so the
     * checkout response and post-checkout pages emit identical markup.
     *
     * {@inheritdoc}
     */
    public function render_post_checkout_instructions( array $order, array $settings ): string {
        return $this->build_instructions( $settings );
    }

    // ══════════════════════════════════════════════════════════════════════════
    // PRIVATE HELPERS
    // ══════════════════════════════════════════════════════════════════════════

    /**
     * Build HTML instructions from gateway settings for the checkout page
     * and order-received / account order-detail pages.
     *
     * Uses semantic <dl> definition-list markup so labels (Bank, Account Name,
     * Account/IBAN, Routing/SWIFT/BIC) pair to values in a screen-reader-friendly
     * structure and CSS can lay them out as either inline rows or grid columns
     * without restructuring markup.
     *
     * @param  array $settings Decoded settings array.
     * @return string HTML snippet.
     */
    private function build_instructions( array $settings ): string {
        $rows = [];

        if ( ! empty( $settings['bank_name'] ) ) {
            $rows[] = [
                'label' => __( 'Bank', 'titancart-lite' ),
                'value' => esc_html( $settings['bank_name'] ),
            ];
        }
        if ( ! empty( $settings['account_name'] ) ) {
            $rows[] = [
                'label' => __( 'Account Name', 'titancart-lite' ),
                'value' => esc_html( $settings['account_name'] ),
            ];
        }
        if ( ! empty( $settings['account_number'] ) ) {
            $rows[] = [
                'label' => __( 'Account / IBAN', 'titancart-lite' ),
                'value' => esc_html( $settings['account_number'] ),
            ];
        }
        if ( ! empty( $settings['routing_number'] ) ) {
            $rows[] = [
                'label' => __( 'Routing / SWIFT / BIC', 'titancart-lite' ),
                'value' => esc_html( $settings['routing_number'] ),
            ];
        }

        $html = '<div class="tc-bank-transfer-details">';

        if ( $rows ) {
            $html .= '<dl class="tc-payment-instructions__dl">';
            foreach ( $rows as $row ) {
                $html .= '<dt class="tc-payment-instructions__label">'
                       . esc_html( $row['label'] )
                       . '</dt>';
                // $row['value'] is already esc_html'd above.
                $html .= '<dd class="tc-payment-instructions__value">'
                       . $row['value']
                       . '</dd>';
            }
            $html .= '</dl>';
        }

        if ( ! empty( $settings['additional_instructions'] ) ) {
            $html .= '<p class="tc-payment-instructions__notes">'
                   . wp_kses_post( nl2br( $settings['additional_instructions'] ) )
                   . '</p>';
        }

        $html .= '<p class="tc-payment-instructions__note">'
               . esc_html__( 'Your order will be confirmed once payment is received.', 'titancart-lite' )
               . '</p></div>';

        return $html;
    }
}
