<?php

namespace Booktics\Module\Stripe_Addon\Service;

use Booktics\Models\Order_Model;
use Booktics\Module\Stripe_Addon\Handler\Stripe_Handler;
use Booktics\Payment\Payment_Methods\Abstract_Payment_Method;
use Booktics\Payment\Payment_Status;
use Exception;
use Stripe\PaymentIntent;
use Stripe\Refund;
use Stripe\Stripe;

class Stripe_Payment_Method extends Abstract_Payment_Method {

    /**
     * Initialize the Stripe SDK with the secret key.
     *
     * @return void
     */
    private function init_stripe_sdk() {
        Stripe::setApiKey( Stripe_Handler::get_stripe_secret_key() );
    }

    /**
     * Get the Stripe connect account URL.
     *
     * @return string The connect URL
     */
    public static function connect_account( $type = 'test' ) {
        return ( new Stripe_Handler() )->get_connect_url( $type );
    }

    /**
     * Get the Stripe account ID from settings.
     *
     * @return string|null The account ID
     */
    public static function account_id() {
        return booktics_get_option( 'stripe_account_id' );
    }

    /**
     * Get the Stripe account type from settings.
     *
     * @return string|null The account type
     */
    public static function account_type() {
        return booktics_get_option( 'stripe_account_type', 'test');
    }

    /**
     * Process a payment through Stripe.
     *
     * @param Order_Model $order The order to process payment for
     *
     * @return array The payment processing result
     */
    public function process_payment( $order ): array {
        $this->init_stripe_sdk();

        $amount   = $order->total ?? 0;
        $currency = $order->currency ?? strtolower( booktics_get_option( 'currency', 'USD' ) );
        try {
            $intent = PaymentIntent::create( [
                'amount'                    => $amount * 100,
                'currency'                  => $currency,
                'description'               => $order->order_no ?? '',
                'automatic_payment_methods' => [
                    'enabled' => true,
                ],
                'metadata'                 => [
                    'order_id' => $order->id,
                ],
            ] );

            return [
                'status'         => 'success',
                'payment_intent' => $intent->id,
                'client_secret'  => $intent->client_secret,
            ];
        } catch ( Exception $e ) {
            if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
                error_log($e->getMessage()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            }
            return [
                'status'  => 'error',
                'message' => $e->getMessage(),
            ];
        }
    }

    /**
     * Validate the payment data.
     *
     * @return array Validation result
     */
    public function validate_payment_data(): array {
        $client_secret = $this->request_data['client_secret'] ?? null;

        if ( empty( $client_secret ) ) {
            return [
                'status'  => 'error',
                'message' => __( 'Missing client_secret for Stripe payment.', 'booktics' )
            ];
        }

        return [ 'status' => 'success' ];
    }

    /**
     * Get the payment status from Stripe.
     *
     * @param Order_Model $order The order to check status for
     *
     * @return string The payment status
     */
    public function get_payment_status( $order ): string {
        $this->init_stripe_sdk();

        $payment_intent_id = $order->payment_intent_id ?? null;

        if ( ! $payment_intent_id ) {
            return Payment_Status::FAILED;
        }

        try {
            $intent = PaymentIntent::retrieve( $payment_intent_id );

            // Map Stripe status to Booktics status
            switch ($intent->status) {
                case 'succeeded':
                    return Payment_Status::COMPLETED;
                case 'processing':
                case 'requires_payment_method':
                case 'requires_confirmation':
                case 'requires_action':
                case 'requires_capture':
                    return Payment_Status::PROCESSING;
                case 'canceled':
                    return Payment_Status::FAILED;
                case 'requires_refund':
                case 'refunded':
                    return Payment_Status::REFUNDED;
                default:
                    return Payment_Status::FAILED;
            }
        } catch ( Exception $e ) {
            return Payment_Status::FAILED;
        }
    }

    /**
     * Process a refund through Stripe.
     *
     * @param Order_Model $order The order to process refund for
     *
     * @return array The refund processing result
     */
    public function process_refund( $order ) {
        $this->init_stripe_sdk();
        $payment_intent_id = $order->payment_intent_id ?? null;

        if ( ! $payment_intent_id ) {
            return [
                'status'  => 'error',
                'message' => __( 'Missing payment_intent_id for Stripe payment.', 'booktics' )
            ];
        }
        $amount = $order->total ?? 0;
        try {
            $refund = Refund::create( [
                'payment_intent' => $payment_intent_id,
                'amount'         => $amount ? intval( $amount * 100 ) : null,
                'stripe_account' => self::account_id(),
            ] );

            return [
                'status'        => 'success',
                'refund_id'     => $refund->id,
                'refund_status' => $refund->status,
                'message' => __( 'Refund initiated successfully.', 'booktics' ),
            ];
        } catch ( \Exception $e ) {
            return [
                'status'  => 'error',
                'message' => $e->getMessage(),
            ];
        }
    }
}