<?php
/**
 * SR_Reward_Controller — API پاداش HVAC
 */
if ( ! defined( 'ABSPATH' ) ) exit;

require_once ACC_PATH . 'includes/helpers/svc-rewards.php';

class SR_Reward_Controller {

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

        register_rest_route( $ns, '/service/rewards/catalog', [
            'methods' => 'GET', 'callback' => [ self::class, 'catalog' ], 'permission_callback' => '__return_true',
        ] );
        register_rest_route( $ns, '/service/rewards/customer/login', [
            'methods' => 'POST', 'callback' => [ self::class, 'customer_login' ], 'permission_callback' => '__return_true',
        ] );
        register_rest_route( $ns, '/service/rewards/me', [
            'methods' => 'GET', 'callback' => [ self::class, 'get_me' ], 'permission_callback' => '__return_true',
        ] );
        register_rest_route( $ns, '/service/rewards/redeem', [
            'methods' => 'POST', 'callback' => [ self::class, 'redeem' ], 'permission_callback' => '__return_true',
        ] );
        register_rest_route( $ns, '/service/rewards/referral', [
            'methods' => 'POST', 'callback' => [ self::class, 'apply_referral' ], 'permission_callback' => '__return_true',
        ] );
        register_rest_route( $ns, '/service/rewards/leaderboard', [
            'methods' => 'GET', 'callback' => [ self::class, 'leaderboard' ], 'permission_callback' => '__return_true',
        ] );
        register_rest_route( $ns, '/service/rewards/staff/login', [
            'methods' => 'POST', 'callback' => [ self::class, 'staff_context' ], 'permission_callback' => [ self::class, 'perm_staff' ],
        ] );
    }

    public static function perm_staff(): bool {
        return is_user_logged_in() && acl_user_can( acl_current_user_id(), 'service.view' );
    }

    public static function catalog(): WP_REST_Response {
        return new WP_REST_Response( [
            'activities'  => Svc_Rewards::activity_catalog(),
            'tiers'       => Svc_Rewards::tier_config(),
            'redeem'      => Svc_Rewards::redeem_catalog(),
            'credit_label'=> Svc_Rewards::CREDIT_LABEL,
        ] );
    }

    public static function customer_login( WP_REST_Request $req ): WP_REST_Response {
        $phone = Svc_Rewards::normalize_phone( (string) ( $req->get_param( 'phone' ) ?? '' ) );
        $name  = sanitize_text_field( $req->get_param( 'name' ) ?? '' );
        $ref   = strtoupper( sanitize_text_field( $req->get_param( 'referral_code' ) ?? '' ) );

        if ( strlen( $phone ) < 10 ) {
            return new WP_REST_Response( [ 'message' => 'شماره موبایل معتبر نیست' ], 400 );
        }

        $referred_by = 0;
        if ( $ref ) {
            global $wpdb;
            $referred_by = (int) $wpdb->get_var( $wpdb->prepare(
                "SELECT id FROM {$wpdb->prefix}svc_reward_accounts WHERE referral_code=%s", $ref
            ) );
        }

        $account = Svc_Rewards::get_or_create_account( 'customer', [
            'phone' => $phone, 'display_name' => $name, 'referred_by' => $referred_by,
        ] );

        if ( $referred_by && empty( $account['referred_by'] ) ) {
            global $wpdb;
            $wpdb->update( "{$wpdb->prefix}svc_reward_accounts", [ 'referred_by' => $referred_by ], [ 'id' => (int) $account['id'] ] );
            Svc_Rewards::process_referral( $referred_by, (int) $account['id'] );
            $account = $wpdb->get_row( $wpdb->prepare(
                "SELECT * FROM {$wpdb->prefix}svc_reward_accounts WHERE id=%d", (int) $account['id']
            ), ARRAY_A );
        }

        $dash = Svc_Rewards::dashboard( (int) $account['id'] );
        return new WP_REST_Response( [
            'success' => true,
            'account_id' => (int) $account['id'],
            'session' => self::_session_token( (int) $account['id'] ),
            'data' => $dash,
        ] );
    }

    public static function get_me( WP_REST_Request $req ): WP_REST_Response {
        $account_id = self::_resolve_account_id( $req );
        if ( ! $account_id ) {
            return new WP_REST_Response( [ 'message' => 'احراز هویت لازم است' ], 401 );
        }
        return new WP_REST_Response( [ 'data' => Svc_Rewards::dashboard( $account_id ) ] );
    }

    public static function redeem( WP_REST_Request $req ): WP_REST_Response {
        $account_id = self::_resolve_account_id( $req );
        if ( ! $account_id ) {
            return new WP_REST_Response( [ 'message' => 'احراز هویت لازم است' ], 401 );
        }
        $key = sanitize_key( $req->get_param( 'redeem_key' ) ?? '' );
        $result = Svc_Rewards::redeem( $account_id, $key );
        if ( empty( $result['success'] ) ) {
            return new WP_REST_Response( $result, 400 );
        }
        $result['data'] = Svc_Rewards::dashboard( $account_id );
        return new WP_REST_Response( $result );
    }

    public static function apply_referral( WP_REST_Request $req ): WP_REST_Response {
        $account_id = self::_resolve_account_id( $req );
        $ref = strtoupper( sanitize_text_field( $req->get_param( 'referral_code' ) ?? '' ) );
        if ( ! $account_id || ! $ref ) {
            return new WP_REST_Response( [ 'message' => 'اطلاعات ناقص' ], 400 );
        }
        global $wpdb;
        $referrer = (int) $wpdb->get_var( $wpdb->prepare(
            "SELECT id FROM {$wpdb->prefix}svc_reward_accounts WHERE referral_code=%s", $ref
        ) );
        if ( ! $referrer || $referrer === $account_id ) {
            return new WP_REST_Response( [ 'message' => 'کد معرف نامعتبر' ], 400 );
        }
        Svc_Rewards::process_referral( $referrer, $account_id );
        return new WP_REST_Response( [ 'success' => true, 'data' => Svc_Rewards::dashboard( $account_id ) ] );
    }

    public static function leaderboard( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $actor = sanitize_key( $req->get_param( 'actor_type' ) ?? 'technician' );
        if ( ! in_array( $actor, [ 'customer', 'technician', 'supplier' ], true ) ) $actor = 'technician';

        $rows = $wpdb->get_results( $wpdb->prepare(
            "SELECT id, display_name, tier, rank_score, lifetime_earned, points_available
             FROM {$wpdb->prefix}svc_reward_accounts WHERE actor_type=%s
             ORDER BY rank_score DESC LIMIT 20", $actor
        ), ARRAY_A );

        return new WP_REST_Response( [ 'data' => $rows ?: [] ] );
    }

    public static function staff_context( WP_REST_Request $req ): WP_REST_Response {
        $uid = acl_current_user_id();
        $actor = sanitize_key( $req->get_param( 'actor_type' ) ?? 'technician' );
        if ( ! in_array( $actor, [ 'technician', 'supplier' ], true ) ) $actor = 'technician';

        if ( acl_user_is_super_admin( $uid ) || acl_user_can( $uid, 'service.requests.manage' ) ) {
            $actor = $actor;
        } elseif ( function_exists( 'Svc_Teams' ) && Svc_Teams::is_technician( $uid ) ) {
            $actor = 'technician';
        }

        $account = Svc_Rewards::get_or_create_account( $actor, [ 'user_id' => $uid ] );
        return new WP_REST_Response( [
            'success' => true,
            'account_id' => (int) $account['id'],
            'data' => Svc_Rewards::dashboard( (int) $account['id'] ),
        ] );
    }

    private static function _resolve_account_id( WP_REST_Request $req ): int {
        $hdr = $req->get_header( 'x-reward-session' ) ?? '';
        if ( $hdr && str_starts_with( $hdr, 'rw_' ) && function_exists( 'acc_resolve_opaque_token' ) ) {
            $id = acc_resolve_opaque_token( 'rw_', $hdr );
            if ( $id > 0 ) {
                return $id;
            }
        }

        $uid = function_exists( 'acl_current_user_id' ) ? (int) acl_current_user_id() : (int) get_current_user_id();
        if ( $uid ) {
            global $wpdb;
            foreach ( [ 'technician', 'supplier', 'customer' ] as $actor ) {
                $id = (int) $wpdb->get_var( $wpdb->prepare(
                    "SELECT id FROM {$wpdb->prefix}svc_reward_accounts WHERE user_id=%d AND actor_type=%s LIMIT 1",
                    $uid, $actor
                ) );
                if ( $id ) {
                    return $id;
                }
            }
        }
        return 0;
    }

    private static function _session_token( int $account_id ): string {
        if ( function_exists( 'acc_issue_opaque_token' ) ) {
            return acc_issue_opaque_token( 'rw_', $account_id, 7 * DAY_IN_SECONDS );
        }
        return 'rw_' . bin2hex( random_bytes( 32 ) );
    }
}
