<?php
/**
 * WP_Orders_Controller.php
 * سیکل کامل خرید: سبد → پرداخت زرین‌پال → تأیید → ثبت سفارش WC
 *
 * POST /acc/v1/public/orders/create   → ساخت سفارش + لینک پرداخت
 * GET  /acc/v1/public/orders/verify   → callback زرین‌پال
 * GET  /acc/v1/public/orders/{id}     → جزئیات سفارش
 * GET  /acc/v1/orders                 → لیست سفارشات ERP (JWT)
 */

if ( ! defined( 'ABSPATH' ) ) exit;

class WP_Orders_Controller {

    /* تنظیمات زرین‌پال — sandbox */
    const ZP_MERCHANT   = '1344b5d4-0048-11e8-94db-005056a205be'; // sandbox merchant
    const ZP_REQUEST    = 'https://sandbox.zarinpal.com/pg/v4/payment/request.json';
    const ZP_VERIFY     = 'https://sandbox.zarinpal.com/pg/v4/payment/verify.json';
    const ZP_STARTPAY   = 'https://sandbox.zarinpal.com/pg/StartPay/';

    public static function register_routes(): void {
        $ns = 'acc/v1';

        register_rest_route( $ns, '/public/orders/create', [
            'methods'             => 'POST',
            'callback'            => [ __CLASS__, 'create_order' ],
            'permission_callback' => '__return_true',
        ] );

        register_rest_route( $ns, '/public/orders/verify', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'verify_payment' ],
            'permission_callback' => '__return_true',
        ] );

        register_rest_route( $ns, '/public/orders/(?P<id>\d+)', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'get_order' ],
            'permission_callback' => '__return_true',
        ] );

        /* ERP — لیست سفارشات (JWT) */
        register_rest_route( $ns, '/orders', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'list_orders' ],
            'permission_callback' => 'acc_jwt_check_permission',
        ] );
    }

    /* ══════════════════════════════════════════════════════
       ساخت سفارش + درخواست پرداخت
    ══════════════════════════════════════════════════════ */
    public static function create_order( WP_REST_Request $req ): WP_REST_Response {
        $items    = $req->get_param('items');     // [{id, qty}]
        $billing  = $req->get_param('billing');   // {name, phone, email, address, city}
        $note     = sanitize_textarea_field( $req->get_param('note') ?? '' );

        /* ── اعتبارسنجی ── */
        if ( empty($items) || ! is_array($items) )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'سبد خرید خالی است' ], 400 );

        if ( empty($billing['name']) || empty($billing['phone']) )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'نام و شماره موبایل الزامی است' ], 400 );

        /* ── محاسبه مبلغ ── */
        $line_items = [];
        $total      = 0;

        foreach ( $items as $item ) {
            $product_id = (int) ($item['id'] ?? 0);
            $qty        = max( 1, (int) ($item['qty'] ?? 1) );

            if ( class_exists('WooCommerce') ) {
                $product = wc_get_product( $product_id );
                if ( ! $product || ! $product->is_purchasable() ) continue;
                $price = (float) $product->get_price();
                $line_items[] = [ 'product_id' => $product_id, 'qty' => $qty, 'price' => $price, 'name' => $product->get_name() ];
                $total += $price * $qty;
            } else {
                $post = get_post( $product_id );
                if ( ! $post || $post->post_type !== 'product' ) continue;
                $price = (float) get_post_meta( $product_id, '_price', true );
                $line_items[] = [ 'product_id' => $product_id, 'qty' => $qty, 'price' => $price, 'name' => $post->post_title ];
                $total += $price * $qty;
            }
        }

        if ( empty($line_items) )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'محصولات نامعتبر' ], 400 );

        if ( $total <= 0 )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'مبلغ سفارش نامعتبر است' ], 400 );

        /* ── ساخت سفارش WooCommerce ── */
        $wc_order_id = null;
        if ( class_exists('WooCommerce') ) {
            $order = wc_create_order();
            foreach ( $line_items as $li ) {
                $product = wc_get_product( $li['product_id'] );
                if ( $product ) $order->add_product( $product, $li['qty'] );
            }
            $order->set_billing_first_name( sanitize_text_field( $billing['name'] ) );
            $order->set_billing_phone(      sanitize_text_field( $billing['phone'] ) );
            $order->set_billing_email(      sanitize_email(      $billing['email'] ?? '' ) );
            $order->set_billing_address_1(  sanitize_text_field( $billing['address'] ?? '' ) );
            $order->set_billing_city(       sanitize_text_field( $billing['city'] ?? '' ) );
            $order->set_customer_note( $note );
            $order->set_status( 'pending' );
            $order->calculate_totals();
            $order->save();
            $wc_order_id = $order->get_id();
        }

        /* ── ذخیره pending order در options ── */
        $order_key = 'acc_order_' . bin2hex( random_bytes( 16 ) );
        $order_data = [
            'key'        => $order_key,
            'wc_id'      => $wc_order_id,
            'items'      => $line_items,
            'total'      => $total,
            'billing'    => array_map( 'sanitize_text_field', (array)$billing ),
            'note'       => $note,
            'status'     => 'pending',
            'created_at' => current_time('mysql'),
        ];
        set_transient( $order_key, $order_data, 2 * HOUR_IN_SECONDS );

        /* ── درخواست پرداخت زرین‌پال ── */
        $callback_url = add_query_arg( [
            'acc_order_key' => $order_key,
        ], get_rest_url( null, 'acc/v1/public/orders/verify' ) );

        $merchant = get_option( 'acc_zarinpal_merchant', self::ZP_MERCHANT );
        $zp_endpoint = get_option( 'acc_zarinpal_sandbox', '1' ) === '1'
            ? self::ZP_REQUEST
            : 'https://api.zarinpal.com/pg/v4/payment/request.json';

        $zp_response = wp_remote_post( $zp_endpoint, [
            'headers'     => [ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ],
            'body'        => wp_json_encode( [
                'merchant_id'  => $merchant,
                'amount'       => (int)($total * 10), // تومان → ریال
                'callback_url' => $callback_url,
                'description'  => 'خرید از فروشگاه — ' . sanitize_text_field( $billing['name'] ),
                'mobile'       => sanitize_text_field( $billing['phone'] ),
                'email'        => sanitize_email( $billing['email'] ?? '' ),
            ] ),
            'timeout' => 15,
        ] );

        if ( is_wp_error( $zp_response ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'خطا در اتصال به درگاه پرداخت: ' . $zp_response->get_error_message() ], 500 );
        }

        $zp_body = json_decode( wp_remote_retrieve_body( $zp_response ), true );

        if ( empty($zp_body['data']['authority']) ) {
            $err = $zp_body['errors']['message'] ?? 'خطای ناشناخته درگاه';
            return new WP_REST_Response( [ 'success' => false, 'message' => 'خطای زرین‌پال: ' . $err ], 502 );
        }

        $authority = sanitize_text_field( $zp_body['data']['authority'] );

        /* ذخیره authority در transient */
        $order_data['authority'] = $authority;
        set_transient( $order_key, $order_data, 2 * HOUR_IN_SECONDS );
        set_transient( 'acc_zp_auth_' . $authority, $order_key, 2 * HOUR_IN_SECONDS );

        $start_pay = ( get_option('acc_zarinpal_sandbox','1') === '1' ? self::ZP_STARTPAY : 'https://www.zarinpal.com/pg/StartPay/' ) . $authority;

        return new WP_REST_Response( [
            'success'     => true,
            'data'        => [
                'order_key'   => $order_key,
                'wc_order_id' => $wc_order_id,
                'total'       => $total,
                'payment_url' => $start_pay,
            ],
        ], 201 );
    }

    /* ══════════════════════════════════════════════════════
       Callback زرین‌پال — تأیید پرداخت
    ══════════════════════════════════════════════════════ */
    public static function verify_payment( WP_REST_Request $req ) {
        $authority = sanitize_text_field( $req->get_param('Authority') ?? '' );
        $status    = sanitize_text_field( $req->get_param('Status')    ?? '' );
        $order_key = sanitize_text_field( $req->get_param('acc_order_key') ?? '' );

        /* پیدا کردن order key */
        if ( ! $order_key && $authority ) {
            $order_key = get_transient( 'acc_zp_auth_' . $authority ) ?: '';
        }

        $spa_base = home_url( '/' . get_option( 'acc_spa_slug', 'app' ) );

        if ( ! $order_key || ! ( $order_data = get_transient( $order_key ) ) ) {
            wp_redirect( add_query_arg( ['payment' => 'error', 'msg' => 'order_not_found'], $spa_base ) );
            exit;
        }

        /* پرداخت لغو شد */
        if ( $status !== 'OK' ) {
            self::_update_order_status( $order_key, $order_data, 'cancelled' );
            wp_redirect( add_query_arg( [ 'payment' => 'cancelled', 'order' => $order_key ], $spa_base ) );
            exit;
        }

        /* تأیید با زرین‌پال */
        $merchant = get_option( 'acc_zarinpal_merchant', self::ZP_MERCHANT );
        $zp_verify = get_option( 'acc_zarinpal_sandbox', '1' ) === '1'
            ? self::ZP_VERIFY
            : 'https://api.zarinpal.com/pg/v4/payment/verify.json';

        $zp_response = wp_remote_post( $zp_verify, [
            'headers' => [ 'Content-Type' => 'application/json', 'Accept' => 'application/json' ],
            'body'    => wp_json_encode( [
                'merchant_id' => $merchant,
                'amount'      => (int)( $order_data['total'] * 10 ),
                'authority'   => $authority,
            ] ),
            'timeout' => 15,
        ] );

        if ( is_wp_error( $zp_response ) ) {
            wp_redirect( add_query_arg( [ 'payment' => 'error', 'msg' => 'verify_failed' ], $spa_base ) );
            exit;
        }

        $zp_body = json_decode( wp_remote_retrieve_body( $zp_response ), true );
        $ref_id  = $zp_body['data']['ref_id'] ?? null;
        $code    = $zp_body['data']['code']   ?? -1;

        if ( $code == 100 || $code == 101 ) {
            /* موفق */
            $order_data['ref_id']    = $ref_id;
            $order_data['authority'] = $authority;
            self::_update_order_status( $order_key, $order_data, 'paid' );

            /* WooCommerce order complete */
            if ( $order_data['wc_id'] && class_exists('WooCommerce') ) {
                $wc_order = wc_get_order( $order_data['wc_id'] );
                if ( $wc_order ) {
                    $wc_order->payment_complete( $ref_id );
                    $wc_order->add_order_note( 'پرداخت موفق — کد پیگیری: ' . $ref_id );
                }
            }

            wp_redirect( add_query_arg( [ 'payment' => 'success', 'ref' => $ref_id, 'order' => $order_key ], $spa_base ) );
            exit;
        }

        /* ناموفق */
        self::_update_order_status( $order_key, $order_data, 'failed' );
        wp_redirect( add_query_arg( [ 'payment' => 'failed', 'code' => $code, 'order' => $order_key ], $spa_base ) );
        exit;
    }

    /* ══════════════════════════════════════════════════════
       جزئیات سفارش
    ══════════════════════════════════════════════════════ */
    public static function get_order( WP_REST_Request $req ): WP_REST_Response {
        $id    = (int) $req->get_param('id');
        $key   = sanitize_text_field( (string) ( $req->get_param('key') ?? $req->get_param('order_key') ?? '' ) );

        if ( $key === '' ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'کلید سفارش الزامی است' ], 403 );
        }

        if ( class_exists('WooCommerce') ) {
            $order = wc_get_order( $id );
            if ( ! $order ) {
                return new WP_REST_Response( [ 'success' => false, 'message' => 'سفارش یافت نشد' ], 404 );
            }
            $order_key = (string) $order->get_order_key();
            if ( $order_key === '' || ! hash_equals( $order_key, $key ) ) {
                return new WP_REST_Response( [ 'success' => false, 'message' => 'دسترسی غیرمجاز' ], 403 );
            }
            return new WP_REST_Response( [ 'success' => true, 'data' => self::_format_wc_order( $order ) ] );
        }

        $order_data = get_transient( $key );
        if ( ! is_array( $order_data ) ) {
            $by_id = get_transient( 'acc_order_' . $id );
            if ( is_array( $by_id ) && ! empty( $by_id['key'] ) && hash_equals( (string) $by_id['key'], $key ) ) {
                $order_data = $by_id;
            }
        }
        if ( ! is_array( $order_data ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'سفارش یافت نشد' ], 404 );
        }
        if ( ! empty( $order_data['key'] ) && ! hash_equals( (string) $order_data['key'], $key ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'دسترسی غیرمجاز' ], 403 );
        }
        return new WP_REST_Response( [ 'success' => true, 'data' => $order_data ] );
    }

    /* ══════════════════════════════════════════════════════
       ERP — لیست سفارشات
    ══════════════════════════════════════════════════════ */
    public static function list_orders( WP_REST_Request $req ): WP_REST_Response {
        if ( ! class_exists('WooCommerce') )
            return new WP_REST_Response( [ 'success' => true, 'data' => [], 'message' => 'WooCommerce فعال نیست' ], 200 );

        $page     = max( 1, (int)( $req->get_param('page') ?? 1 ) );
        $per_page = min( 50, (int)( $req->get_param('per_page') ?? 20 ) );
        $status   = sanitize_text_field( $req->get_param('status') ?? 'any' );

        $orders = wc_get_orders( [
            'status'     => $status,
            'limit'      => $per_page,
            'offset'     => ( $page - 1 ) * $per_page,
            'orderby'    => 'date',
            'order'      => 'DESC',
        ] );

        $total = (int) wc_get_orders( [ 'status' => $status, 'limit' => -1, 'return' => 'ids' ] );

        return new WP_REST_Response( [
            'success'     => true,
            'data'        => array_map( [ __CLASS__, '_format_wc_order' ], $orders ),
            'total'       => $total,
            'total_pages' => ceil( $total / $per_page ),
        ] );
    }

    /* ══════════════════════════════════════════════════════
       Helpers
    ══════════════════════════════════════════════════════ */
    private static function _update_order_status( string $key, array $data, string $status ): void {
        $data['status']     = $status;
        $data['updated_at'] = current_time('mysql');
        set_transient( $key, $data, DAY_IN_SECONDS );
    }

    private static function _format_wc_order( $order ): array {
        $items = [];
        foreach ( $order->get_items() as $item ) {
            $items[] = [
                'name'  => $item->get_name(),
                'qty'   => $item->get_quantity(),
                'total' => $item->get_total(),
            ];
        }
        return [
            'id'         => $order->get_id(),
            'status'     => $order->get_status(),
            'total'      => $order->get_total(),
            'currency'   => $order->get_currency(),
            'name'       => $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(),
            'phone'      => $order->get_billing_phone(),
            'email'      => $order->get_billing_email(),
            'address'    => $order->get_billing_address_1(),
            'city'       => $order->get_billing_city(),
            'note'       => $order->get_customer_note(),
            'items'      => $items,
            'created_at' => $order->get_date_created()?->date('Y-m-d H:i:s') ?? '',
        ];
    }
}
