<?php
/**
 * Chat_Controller.php
 * Live Chat (پشتیبانی بازدیدکننده) + Internal Chat (ERP)
 * Long Polling — بدون WebSocket
 *
 * جداول واقعی:
 *   wp_chat_visitors      : id, visitor_id(varchar64), ip_address, user_agent, created_at
 *   wp_chat_conversations : id, visitor_id, agent_id, status, source, created_at, updated_at
 *   wp_chat_messages      : id, conversation_id, sender_type, sender_id(varchar64), message, created_at
 *   wp_chat_rooms         : id, type, name, project_id, created_by, status, last_msg_at, created_at
 *   wp_chat_participants  : id, room_id, user_id, role, last_read_at, joined_at
 */

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

class Chat_Controller {

    /* ══════════════════════════════════════════════
       ROUTE REGISTRATION
    ══════════════════════════════════════════════ */

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

        /* ── Live Chat بازدیدکننده (بدون JWT) ── */
        register_rest_route( $ns, '/chat/support/start',   [ 'methods' => 'POST', 'callback' => [ __CLASS__, 'visitor_start'   ], 'permission_callback' => '__return_true' ] );
        register_rest_route( $ns, '/chat/visitor/message', [ 'methods' => 'POST', 'callback' => [ __CLASS__, 'visitor_message' ], 'permission_callback' => '__return_true' ] );
        register_rest_route( $ns, '/chat/visitor/poll',    [ 'methods' => 'GET',  'callback' => [ __CLASS__, 'visitor_poll'    ], 'permission_callback' => '__return_true' ] );

        /* ── ERP Internal Chat (با JWT) ── */
        register_rest_route( $ns, '/chat/rooms',                           [ 'methods' => 'GET',  'callback' => [ __CLASS__, 'get_rooms'    ], 'permission_callback' => 'acc_jwt_check_permission' ] );
        register_rest_route( $ns, '/chat/rooms',                           [ 'methods' => 'POST', 'callback' => [ __CLASS__, 'create_room'  ], 'permission_callback' => 'acc_jwt_check_permission' ] );
        register_rest_route( $ns, '/chat/rooms/(?P<id>\d+)/messages',      [ 'methods' => 'GET',  'callback' => [ __CLASS__, 'get_messages' ], 'permission_callback' => 'acc_jwt_check_permission' ] );
        register_rest_route( $ns, '/chat/rooms/(?P<id>\d+)/messages',      [ 'methods' => 'POST', 'callback' => [ __CLASS__, 'send_message' ], 'permission_callback' => 'acc_jwt_check_permission' ] );
        register_rest_route( $ns, '/chat/rooms/(?P<id>\d+)/read',          [ 'methods' => 'POST', 'callback' => [ __CLASS__, 'mark_read'    ], 'permission_callback' => 'acc_jwt_check_permission' ] );
        register_rest_route( $ns, '/chat/poll',                            [ 'methods' => 'GET',  'callback' => [ __CLASS__, 'erp_poll'     ], 'permission_callback' => 'acc_jwt_check_permission' ] );

        /* ── پنل پشتیبانی ERP ── */
        register_rest_route( $ns, '/chat/support/rooms',                       [ 'methods' => 'GET',  'callback' => [ __CLASS__, 'support_rooms' ], 'permission_callback' => 'acc_jwt_check_permission' ] );
        register_rest_route( $ns, '/chat/support/rooms/(?P<id>\d+)',           [ 'methods' => 'GET',  'callback' => [ __CLASS__, 'support_room'  ], 'permission_callback' => 'acc_jwt_check_permission' ] );
        register_rest_route( $ns, '/chat/support/rooms/(?P<id>\d+)/reply',     [ 'methods' => 'POST', 'callback' => [ __CLASS__, 'support_reply' ], 'permission_callback' => 'acc_jwt_check_permission' ] );
        register_rest_route( $ns, '/chat/support/rooms/(?P<id>\d+)/close',     [ 'methods' => 'POST', 'callback' => [ __CLASS__, 'support_close' ], 'permission_callback' => 'acc_jwt_check_permission' ] );

        /* ── Settings ── */
        register_rest_route( $ns, '/chat/settings', [ 'methods' => 'GET',  'callback' => [ __CLASS__, 'get_settings'  ], 'permission_callback' => 'acc_jwt_check_permission' ] );
        register_rest_route( $ns, '/chat/settings', [ 'methods' => 'POST', 'callback' => [ __CLASS__, 'save_settings' ], 'permission_callback' => 'acc_jwt_check_permission' ] );
    }

    /* ══════════════════════════════════════════════
       VISITOR — شروع live chat
    ══════════════════════════════════════════════ */

    public static function visitor_start( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;

        $session_key   = sanitize_text_field( $req->get_param('session_key')    ?? '' );
        $tracking_code = strtoupper( sanitize_text_field( $req->get_param('tracking_code') ?? '' ) );
        $portal        = sanitize_text_field( $req->get_param('portal') ?? $req->get_param('source') ?? 'website' );
        $name          = sanitize_text_field( $req->get_param('name')           ?? 'بازدیدکننده' );
        $phone         = sanitize_text_field( $req->get_param('phone')          ?? '' );
        $email         = sanitize_email(      $req->get_param('email')          ?? '' );
        $page_url      = esc_url_raw(         $req->get_param('page_url')       ?? '' );
        $ip            = self::_get_ip();
        $ua            = substr( sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] ?? '' ), 0, 500 );

        if ( empty( $session_key ) )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'session_key الزامی است' ], 400 );

        // ─── بازگشایی با کد پیگیری ───────────────────────────────
        if ( $tracking_code ) {
            $conv = $wpdb->get_row( $wpdb->prepare(
                "SELECT * FROM {$wpdb->prefix}chat_conversations WHERE tracking_code = %s LIMIT 1",
                $tracking_code
            ) );
            if ( ! $conv )
                return new WP_REST_Response( [ 'success' => false, 'message' => 'کد پیگیری یافت نشد' ], 404 );

            // session جدید را به conversation وصل کن (visitor_id به‌روز می‌شود)
            $wpdb->query( $wpdb->prepare(
                "UPDATE {$wpdb->prefix}chat_conversations SET visitor_id = %s WHERE id = %d",
                $session_key, (int) $conv->id
            ) );
            // visitor record برای session جدید ثبت کن
            $wpdb->query( $wpdb->prepare(
                "INSERT IGNORE INTO {$wpdb->prefix}chat_visitors (visitor_id, name, phone, email, ip_address, user_agent, created_at)
                 VALUES (%s, %s, %s, %s, %s, %s, %s)",
                $session_key, $name, $phone, $email, $ip, $ua, current_time('mysql')
            ) );

            return new WP_REST_Response( [ 'success' => true, 'data' => [
                'room_id'       => (int) $conv->id,
                'tracking_code' => $conv->tracking_code,
                'visitor_name'  => $name,
                'resumed'       => true,
            ] ], 200 );
        }

        // ─── بررسی session موجود (همان مرورگر + همان پورتال) ─────
        if ( $portal === 'service' ) {
            $conv = $wpdb->get_row( $wpdb->prepare(
                "SELECT c.* FROM {$wpdb->prefix}chat_conversations c
                 INNER JOIN {$wpdb->prefix}chat_visitors v ON v.visitor_id = c.visitor_id
                 WHERE v.visitor_id = %s AND c.status != 'closed' AND c.source IN ('service','website')
                 ORDER BY c.id DESC LIMIT 1",
                $session_key
            ) );
        } else {
            $conv = $wpdb->get_row( $wpdb->prepare(
                "SELECT c.* FROM {$wpdb->prefix}chat_conversations c
                 INNER JOIN {$wpdb->prefix}chat_visitors v ON v.visitor_id = c.visitor_id
                 WHERE v.visitor_id = %s AND c.status != 'closed' AND c.source = %s
                 ORDER BY c.id DESC LIMIT 1",
                $session_key, $portal
            ) );
        }

        if ( $conv ) {
            return new WP_REST_Response( [ 'success' => true, 'data' => [
                'room_id'       => (int) $conv->id,
                'tracking_code' => $conv->tracking_code,
                'visitor_name'  => $name,
                'resumed'       => true,
            ] ], 200 );
        }

        // ─── ثبت بازدیدکننده جدید (با نام، موبایل و ایمیل) ─────
        $wpdb->query( $wpdb->prepare(
            "INSERT INTO {$wpdb->prefix}chat_visitors (visitor_id, name, phone, email, ip_address, user_agent, created_at)
             VALUES (%s, %s, %s, %s, %s, %s, %s)
             ON DUPLICATE KEY UPDATE
                 name  = IF(name  IS NULL OR name ='', VALUES(name),  name),
                 phone = IF(phone IS NULL OR phone='', VALUES(phone), phone),
                 email = IF(email IS NULL OR email='', VALUES(email), email)",
            $session_key, $name, $phone, $email, $ip, $ua, current_time('mysql')
        ) );

        // ─── تولید کد پیگیری یکتا ────────────────────────────────
        $new_code = self::_generate_tracking_code();

        // ─── ساخت گفتگوی جدید ────────────────────────────────────
        $now = current_time('mysql');
        $inserted = $wpdb->query( $wpdb->prepare(
            "INSERT INTO {$wpdb->prefix}chat_conversations
             (visitor_id, tracking_code, agent_id, status, source, created_at, updated_at)
             VALUES (%s, %s, NULL, 'open', %s, %s, %s)",
            $session_key, $new_code, $portal === 'website' ? 'service' : $portal, $now, $now
        ) );

        if ( ! $inserted ) {
            return new WP_REST_Response( [
                'success' => false,
                'message' => 'خطا در ایجاد گفتگو: ' . $wpdb->last_error,
            ], 500 );
        }

        $conv_id = (int) $wpdb->insert_id;

        if ( $conv_id <= 0 ) {
            return new WP_REST_Response( [
                'success' => false,
                'message' => 'شناسه گفتگو دریافت نشد',
            ], 500 );
        }

        // پیام خوش‌آمد + اطلاع‌رسانی کد پیگیری
        $welcome = get_option( 'acc_chat_welcome_msg', 'سلام! به پشتیبانی خوش آمدید.' );
        $code_msg = "🎫 کد پیگیری شما: {$new_code}\nاین کد را ذخیره کنید تا از هر دستگاهی ادامه گفتگو را داشته باشید.";

        $wpdb->query( $wpdb->prepare(
            "INSERT INTO {$wpdb->prefix}chat_messages (conversation_id, sender_type, sender_id, message, created_at)
             VALUES (%d, 'agent', '0', %s, %s)",
            $conv_id, $welcome, current_time('mysql')
        ) );
        $wpdb->query( $wpdb->prepare(
            "INSERT INTO {$wpdb->prefix}chat_messages (conversation_id, sender_type, sender_id, message, created_at)
             VALUES (%d, 'system', '0', %s, %s)",
            $conv_id, $code_msg, current_time('mysql')
        ) );

        return new WP_REST_Response( [ 'success' => true, 'data' => [
            'room_id'       => $conv_id,
            'tracking_code' => $new_code,
            'visitor_name'  => $name,
            'resumed'       => false,
        ] ], 201 );
    }

    /* ══════════════════════════════════════════════
       VISITOR — ارسال پیام
    ══════════════════════════════════════════════ */

    public static function visitor_message( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;

        $session_key = sanitize_text_field( $req->get_param('session_key') ?? '' );
        $conv_id     = (int) ( $req->get_param('room_id') ?? 0 );
        $body        = sanitize_textarea_field( $req->get_param('body') ?? '' );

        if ( empty($session_key) || empty($body) || ! $conv_id )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'پارامترهای ناقص' ], 400 );

        // بررسی مالکیت
        $conv = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}chat_conversations WHERE id = %d AND visitor_id = %s",
            $conv_id, $session_key
        ) );
        if ( ! $conv )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'دسترسی غیرمجاز' ], 403 );

        $wpdb->insert( "{$wpdb->prefix}chat_messages", [
            'conversation_id' => $conv_id,
            'sender_type'     => 'visitor',
            'sender_id'       => $session_key,
            'message'         => $body,
            'created_at'      => current_time('mysql'),
        ] );
        $msg_id = (int) $wpdb->insert_id;

        // آپدیت updated_at و status
        $wpdb->update( "{$wpdb->prefix}chat_conversations",
            [ 'status' => 'open', 'updated_at' => current_time('mysql') ],
            [ 'id' => $conv_id ]
        );

        return new WP_REST_Response( [ 'success' => true, 'data' => [ 'id' => $msg_id ] ], 201 );
    }

    /* ══════════════════════════════════════════════
       VISITOR POLL — Long Polling
    ══════════════════════════════════════════════ */

    public static function visitor_poll( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;

        $session_key = sanitize_text_field( $req->get_param('session_key') ?? '' );
        $conv_id     = (int) ( $req->get_param('room_id') ?? 0 );
        $last_id     = (int) ( $req->get_param('last_id') ?? 0 );

        if ( ! $conv_id || ! $session_key ) {
            return new WP_REST_Response( [ 'success' => true, 'data' => [ 'messages' => [] ] ], 200 );
        }

        // فقط صاحب session می‌تواند پیام‌های همان گفتگو را بخواند
        $owns = (int) $wpdb->get_var( $wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}chat_conversations
             WHERE id = %d AND visitor_id = %s LIMIT 1",
            $conv_id, $session_key
        ) );
        if ( $owns < 1 ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'دسترسی غیرمجاز' ], 403 );
        }

        $messages = $wpdb->get_results( $wpdb->prepare(
            "SELECT id, sender_type, sender_id, message AS body, created_at
             FROM {$wpdb->prefix}chat_messages
             WHERE conversation_id = %d AND id > %d
             ORDER BY id ASC LIMIT 50",
            $conv_id, $last_id
        ), ARRAY_A );

        return new WP_REST_Response( [ 'success' => true, 'data' => [ 'messages' => $messages ?: [] ] ], 200 );
    }

    /* ══════════════════════════════════════════════
       ERP — لیست اتاق‌ها (چت داخلی)
    ══════════════════════════════════════════════ */

    public static function get_rooms( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $user_id = get_current_user_id();

        $rooms = $wpdb->get_results( $wpdb->prepare(
            "SELECT r.*,
                    (SELECT m.message FROM {$wpdb->prefix}chat_messages m WHERE m.conversation_id = r.id ORDER BY m.id DESC LIMIT 1) AS last_body,
                    (SELECT COUNT(*) FROM {$wpdb->prefix}chat_messages unr
                     WHERE unr.conversation_id = r.id
                       AND unr.created_at > COALESCE((SELECT cp.last_read_at FROM {$wpdb->prefix}chat_participants cp WHERE cp.room_id = r.id AND cp.user_id = %d LIMIT 1), '1970-01-01 00:00:00')
                       AND unr.sender_id != %s
                    ) AS unread_count
             FROM {$wpdb->prefix}chat_rooms r
             INNER JOIN {$wpdb->prefix}chat_participants p ON p.room_id = r.id AND p.user_id = %d
             WHERE r.type IN ('direct','group')
             ORDER BY r.last_msg_at DESC LIMIT 50",
            $user_id, (string) $user_id, $user_id
        ), ARRAY_A );

        return new WP_REST_Response( [ 'success' => true, 'data' => $rooms ?: [] ], 200 );
    }

    /* ══════════════════════════════════════════════
       ERP — ساخت اتاق جدید
    ══════════════════════════════════════════════ */

    public static function create_room( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $user_id = get_current_user_id();
        $type    = in_array( $req->get_param('type'), ['direct','group'] ) ? $req->get_param('type') : 'direct';
        $name    = sanitize_text_field( $req->get_param('name') ?? '' );
        $members = array_map( 'intval', (array)( $req->get_param('members') ?? [] ) );

        if ( $type === 'direct' && count($members) !== 1 )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'برای چت مستقیم باید یک عضو مشخص شود' ], 400 );

        // بررسی تکراری نبودن direct
        if ( $type === 'direct' ) {
            $other   = $members[0];
            $existing = $wpdb->get_var( $wpdb->prepare(
                "SELECT r.id FROM {$wpdb->prefix}chat_rooms r
                 INNER JOIN {$wpdb->prefix}chat_participants p1 ON p1.room_id = r.id AND p1.user_id = %d
                 INNER JOIN {$wpdb->prefix}chat_participants p2 ON p2.room_id = r.id AND p2.user_id = %d
                 WHERE r.type = 'direct' LIMIT 1",
                $user_id, $other
            ) );
            if ( $existing )
                return new WP_REST_Response( [ 'success' => true, 'data' => [ 'room_id' => (int)$existing ] ], 200 );
        }

        $wpdb->insert( "{$wpdb->prefix}chat_rooms", [
            'type'       => $type,
            'name'       => $name,
            'created_by' => $user_id,
            'status'     => 'open',
            'created_at' => current_time('mysql'),
        ] );
        $room_id = (int) $wpdb->insert_id;

        $all_members = array_unique( array_merge( [$user_id], $members ) );
        foreach ( $all_members as $uid ) {
            $wpdb->insert( "{$wpdb->prefix}chat_participants", [
                'room_id'  => $room_id,
                'user_id'  => $uid,
                'role'     => $uid === $user_id ? 'admin' : 'member',
            ] );
        }

        return new WP_REST_Response( [ 'success' => true, 'data' => [ 'room_id' => $room_id ] ], 201 );
    }

    /* ══════════════════════════════════════════════
       ERP — پیام‌های یک اتاق
    ══════════════════════════════════════════════ */

    public static function get_messages( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $user_id = get_current_user_id();
        $room_id = (int) $req->get_param('id');
        $before  = (int) ( $req->get_param('before') ?? 0 );
        $limit   = min( (int)( $req->get_param('limit') ?? 50 ), 100 );

        if ( ! self::_is_member( $room_id, $user_id ) )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'دسترسی غیرمجاز' ], 403 );

        $where = $before ? $wpdb->prepare( " AND m.id < %d", $before ) : '';
        $msgs  = $wpdb->get_results( $wpdb->prepare(
            "SELECT m.id, m.sender_type, m.sender_id, m.message AS body, m.created_at,
                    u.display_name AS sender_name
             FROM {$wpdb->prefix}chat_messages m
             LEFT JOIN {$wpdb->users} u ON u.ID = CAST(m.sender_id AS UNSIGNED) AND m.sender_type = 'user'
             WHERE m.conversation_id = %d {$where}
             ORDER BY m.id DESC LIMIT %d",
            $room_id, $limit
        ), ARRAY_A );

        return new WP_REST_Response( [ 'success' => true, 'data' => array_reverse( $msgs ?: [] ) ], 200 );
    }

    /* ══════════════════════════════════════════════
       ERP — ارسال پیام داخلی
    ══════════════════════════════════════════════ */

    public static function send_message( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $user_id = get_current_user_id();
        $room_id = (int) $req->get_param('id');
        $body    = sanitize_textarea_field( $req->get_param('body') ?? '' );

        if ( ! self::_is_member( $room_id, $user_id ) )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'دسترسی غیرمجاز' ], 403 );
        if ( empty( $body ) )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'متن پیام الزامی است' ], 400 );

        $wpdb->insert( "{$wpdb->prefix}chat_messages", [
            'conversation_id' => $room_id,
            'sender_type'     => 'user',
            'sender_id'       => (string) $user_id,
            'message'         => $body,
            'created_at'      => current_time('mysql'),
        ] );
        $msg_id = (int) $wpdb->insert_id;
        $wpdb->update( "{$wpdb->prefix}chat_rooms", [ 'last_msg_at' => current_time('mysql') ], [ 'id' => $room_id ] );

        return new WP_REST_Response( [ 'success' => true, 'data' => [ 'id' => $msg_id ] ], 201 );
    }

    /* ══════════════════════════════════════════════
       ERP POLL — پیام‌های جدید همه اتاق‌ها
    ══════════════════════════════════════════════ */

    public static function erp_poll( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $user_id = get_current_user_id();
        $last_id = (int) ( $req->get_param('last_id') ?? 0 );

        $msgs = $wpdb->get_results( $wpdb->prepare(
            "SELECT m.id, m.conversation_id AS room_id, m.sender_type, m.sender_id,
                    m.message AS body, m.created_at,
                    r.name AS room_name, r.type AS room_type,
                    u.display_name AS sender_name
             FROM {$wpdb->prefix}chat_messages m
             INNER JOIN {$wpdb->prefix}chat_rooms r ON r.id = m.conversation_id
             INNER JOIN {$wpdb->prefix}chat_participants p ON p.room_id = m.conversation_id AND p.user_id = %d
             LEFT JOIN {$wpdb->users} u ON u.ID = CAST(m.sender_id AS UNSIGNED)
             WHERE m.id > %d AND m.sender_id != %d
             ORDER BY m.id ASC LIMIT 100",
            $user_id, $last_id, (string) $user_id
        ), ARRAY_A );

        return new WP_REST_Response( [ 'success' => true, 'data' => [ 'messages' => $msgs ?: [] ] ], 200 );
    }

    /* ══════════════════════════════════════════════
       ERP — علامت‌گذاری خوانده‌شدن
    ══════════════════════════════════════════════ */

    public static function mark_read( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $user_id = get_current_user_id();
        $room_id = (int) $req->get_param('id');

        $wpdb->update(
            "{$wpdb->prefix}chat_participants",
            [ 'last_read_at' => current_time('mysql') ],
            [ 'room_id' => $room_id, 'user_id' => $user_id ]
        );

        return new WP_REST_Response( [ 'success' => true ], 200 );
    }

    /* ══════════════════════════════════════════════
       SUPPORT — لیست گفتگوهای live
    ══════════════════════════════════════════════ */

    public static function support_rooms( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        require_once ACC_PATH . 'includes/helpers/svc-teams.php';

        $user_id = (int) get_current_user_id();
        if ( ! $user_id && isset( $GLOBALS['acc_jwt_user_id'] ) ) {
            $user_id = (int) $GLOBALS['acc_jwt_user_id'];
        }

        $status = sanitize_text_field( $req->get_param('status') ?? 'all' );
        $source = sanitize_text_field( $req->get_param('source') ?? '' );
        $page   = max( 1, (int)( $req->get_param('page') ?? 1 ) );
        $limit  = 20;
        $offset = ( $page - 1 ) * $limit;

        $where  = $status !== 'all' ? $wpdb->prepare( " AND c.status = %s", $status ) : '';
        if ( $source ) {
            $where .= $wpdb->prepare( " AND c.source = %s", $source );
        }
        [ $team_sql, $team_params ] = Svc_Teams::chat_filter_sql( $user_id );

        $count_sql = "SELECT COUNT(*) FROM {$wpdb->prefix}chat_conversations c WHERE 1=1{$where}{$team_sql}";
        $total = $team_params
            ? (int) $wpdb->get_var( $wpdb->prepare( $count_sql, ...$team_params ) )
            : (int) $wpdb->get_var( $count_sql );

        $rooms_sql = "SELECT c.*,
                    COALESCE(v.name, 'بازدیدکننده') AS visitor_name,
                    v.phone         AS visitor_phone,
                    v.email         AS visitor_email,
                    v.ip_address    AS visitor_ip,
                    (SELECT m.message FROM {$wpdb->prefix}chat_messages m WHERE m.conversation_id = c.id ORDER BY m.id DESC LIMIT 1) AS last_body,
                    (SELECT COUNT(*) FROM {$wpdb->prefix}chat_messages mc WHERE mc.conversation_id = c.id AND mc.sender_type = 'visitor') AS visitor_msg_count,
                    (SELECT COUNT(*) FROM {$wpdb->prefix}chat_messages ma WHERE ma.conversation_id = c.id) AS total_msg_count
             FROM {$wpdb->prefix}chat_conversations c
             LEFT JOIN {$wpdb->prefix}chat_visitors v ON v.visitor_id = c.visitor_id
             WHERE 1=1{$where}{$team_sql}
             ORDER BY c.updated_at DESC
             LIMIT %d OFFSET %d";

        $rooms_params = array_merge( $team_params, [ $limit, $offset ] );
        $rooms = $wpdb->get_results( $wpdb->prepare( $rooms_sql, ...$rooms_params ), ARRAY_A );

        return new WP_REST_Response( [
            'success' => true,
            'data'    => $rooms ?: [],
            'total'   => $total,
            'pages'   => ceil( $total / $limit ),
        ], 200 );
    }

    /* ══════════════════════════════════════════════
       SUPPORT — جزئیات یک گفتگو
    ══════════════════════════════════════════════ */

    public static function support_room( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        require_once ACC_PATH . 'includes/helpers/svc-teams.php';

        $user_id = (int) get_current_user_id();
        if ( ! $user_id && isset( $GLOBALS['acc_jwt_user_id'] ) ) {
            $user_id = (int) $GLOBALS['acc_jwt_user_id'];
        }

        $conv_id = (int) $req->get_param('id');
        $last_id = (int) ( $req->get_param('last_id') ?? 0 );

        $conv = $wpdb->get_row( $wpdb->prepare(
            "SELECT c.*,
                    COALESCE(v.name, 'بازدیدکننده') AS visitor_name,
                    v.phone      AS visitor_phone,
                    v.email      AS visitor_email,
                    v.ip_address AS visitor_ip,
                    v.user_agent
             FROM {$wpdb->prefix}chat_conversations c
             LEFT JOIN {$wpdb->prefix}chat_visitors v ON v.visitor_id = c.visitor_id
             WHERE c.id = %d",
            $conv_id
        ), ARRAY_A );

        if ( ! $conv )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'گفتگو یافت نشد' ], 404 );

        if ( ! Svc_Teams::can_access_conversation( $user_id, $conv ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'دسترسی به این گفتگو مجاز نیست' ], 403 );
        }

        $msgs = $wpdb->get_results( $wpdb->prepare(
            "SELECT id, sender_type, sender_id, message AS body, created_at
             FROM {$wpdb->prefix}chat_messages
             WHERE conversation_id = %d AND id > %d
             ORDER BY id ASC LIMIT 100",
            $conv_id, $last_id
        ), ARRAY_A );

        return new WP_REST_Response( [ 'success' => true, 'data' => array_merge( $conv, [ 'messages' => $msgs ?: [] ] ) ], 200 );
    }

    /* ══════════════════════════════════════════════
       SUPPORT — پاسخ اپراتور
    ══════════════════════════════════════════════ */

    public static function support_reply( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        require_once ACC_PATH . 'includes/helpers/svc-teams.php';

        $user_id = get_current_user_id();
        if ( ! $user_id && isset( $GLOBALS['acc_jwt_user_id'] ) ) {
            $user_id = (int) $GLOBALS['acc_jwt_user_id'];
        }
        $conv_id = (int) $req->get_param('id');
        $body    = sanitize_textarea_field( $req->get_param('body') ?? '' );

        if ( empty( $body ) )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'متن پیام الزامی است' ], 400 );

        $conv = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}chat_conversations WHERE id = %d", $conv_id
        ) );
        if ( ! $conv )
            return new WP_REST_Response( [ 'success' => false, 'message' => 'گفتگو یافت نشد' ], 404 );

        if ( ! Svc_Teams::can_access_conversation( (int) $user_id, (array) $conv ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'دسترسی به این گفتگو مجاز نیست' ], 403 );
        }

        $wpdb->insert( "{$wpdb->prefix}chat_messages", [
            'conversation_id' => $conv_id,
            'sender_type'     => 'agent',
            'sender_id'       => (string) $user_id,
            'message'         => $body,
            'created_at'      => current_time('mysql'),
        ] );
        $msg_id = (int) $wpdb->insert_id;

        $wpdb->update( "{$wpdb->prefix}chat_conversations",
            [ 'agent_id' => $user_id, 'updated_at' => current_time('mysql') ],
            [ 'id' => $conv_id ]
        );

        return new WP_REST_Response( [ 'success' => true, 'data' => [ 'id' => $msg_id ] ], 201 );
    }

    /* ══════════════════════════════════════════════
       SUPPORT — بستن گفتگو
    ══════════════════════════════════════════════ */

    public static function support_close( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $conv_id = (int) $req->get_param('id');
        $wpdb->update(
            "{$wpdb->prefix}chat_conversations",
            [ 'status' => 'closed', 'updated_at' => current_time('mysql') ],
            [ 'id' => $conv_id ]
        );
        return new WP_REST_Response( [ 'success' => true ], 200 );
    }

    /* ══════════════════════════════════════════════
       SETTINGS
    ══════════════════════════════════════════════ */

    public static function get_settings(): WP_REST_Response {
        return new WP_REST_Response( [ 'success' => true, 'data' => [
            'site_name'   => get_option( 'acc_chat_site_name',   'پشتیبانی آنلاین' ),
            'welcome_msg' => get_option( 'acc_chat_welcome_msg', 'سلام! چطور می‌تونم کمکتون کنم؟' ),
            'phone'       => get_option( 'acc_chat_phone',       '' ),
            'whatsapp'    => get_option( 'acc_chat_whatsapp',    '' ),
            'telegram'    => get_option( 'acc_chat_telegram',    '' ),
            'instagram'   => get_option( 'acc_chat_instagram',   '' ),
            'enabled'     => (bool) get_option( 'acc_chat_enabled', 1 ),
        ] ], 200 );
    }

    public static function save_settings( WP_REST_Request $req ): WP_REST_Response {
        $fields = [ 'site_name', 'welcome_msg', 'phone', 'whatsapp', 'telegram', 'instagram', 'enabled' ];
        foreach ( $fields as $f ) {
            $val = $req->get_param( $f );
            if ( $val !== null )
                update_option( "acc_chat_{$f}", sanitize_text_field( $val ) );
        }
        return new WP_REST_Response( [ 'success' => true ], 200 );
    }

    /* ══════════════════════════════════════════════
       HELPERS
    ══════════════════════════════════════════════ */

    private static function _is_member( int $room_id, int $user_id ): bool {
        global $wpdb;
        return (bool) $wpdb->get_var( $wpdb->prepare(
            "SELECT id FROM {$wpdb->prefix}chat_participants WHERE room_id = %d AND user_id = %d",
            $room_id, $user_id
        ) );
    }

    private static function _generate_tracking_code(): string {
        global $wpdb;
        $chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
        $len   = strlen( $chars );
        do {
            $code = '';
            for ( $i = 0; $i < 6; $i++ )
                $code .= $chars[ random_int( 0, $len - 1 ) ];
            $exists = $wpdb->get_var( $wpdb->prepare(
                "SELECT id FROM {$wpdb->prefix}chat_conversations WHERE tracking_code = %s", $code
            ) );
        } while ( $exists );
        return $code;
    }

    private static function _get_ip(): string {
        foreach ( [ 'HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR' ] as $k ) {
            if ( ! empty( $_SERVER[$k] ) )
                return sanitize_text_field( explode( ',', $_SERVER[$k] )[0] );
        }
        return '';
    }
}

/* ── تزریق ویجت به front-end ── */
add_action( 'wp_footer', function() {
    // در WordPress واقعی: صفحات ادمین نیاز به ویجت ندارند
    if ( function_exists( 'is_admin' ) && is_admin() ) return;

    if ( ! get_option( 'acc_chat_enabled', 1 ) ) return;

    $spa_slug = get_option( 'acc_spa_slug', 'app' );

    // محاسبه api_base بر اساس محیط
    if ( defined( 'WP_CONTENT_DIR' ) && function_exists( 'get_rest_url' ) ) {
        // حالت وردپرس واقعی
        $api_base = rtrim( get_rest_url( null, 'acc/v1' ), '/' );
        $nonce    = function_exists( 'wp_create_nonce' ) ? wp_create_nonce( 'wp_rest' ) : '';
    } else {
        // حالت standalone
        $api_base = rtrim( ( defined('ACC_URL') ? ACC_URL : '/acc-engine/' ) . 'api.php/acc/v1', '/' );
        $nonce    = '';
    }

    $cfg = [
        'api_base'      => $api_base,
        'nonce'         => $nonce,
        'portal'        => 'erp',
        'site_name'     => get_option( 'acc_chat_erp_name', 'پشتیبانی ERP' ),
        'welcome_msg'   => get_option( 'acc_chat_erp_welcome', 'سلام! برای ماژول‌های ERP یا پشتیبانی فنی پیام بدهید.' ),
        'phone'         => get_option( 'acc_chat_phone', '' ),
        'whatsapp'      => get_option( 'acc_chat_whatsapp', '' ),
        'telegram'      => get_option( 'acc_chat_telegram', '' ),
        'instagram'     => get_option( 'acc_chat_instagram', '' ),
        'poll_ms'       => 4000,
        'spa_slug'      => $spa_slug,
        'wizards_js'    => 'assets/js/chat-widget/erp-wizards.js',
        'tabs'          => [ 'home', 'chat', 'contact' ],
        'theme_color'   => '#1e3a5f',
        'launcher_icon' => '⚙️',
        'wp_user'       => ( function_exists('is_user_logged_in') && is_user_logged_in() ) ? [
            'id'   => get_current_user_id(),
            'name' => function_exists('wp_get_current_user') ? wp_get_current_user()->display_name : '',
        ] : null,
    ];

    $base = ACC_URL;
    echo "\n<!-- ACC Chat Widget [erp] -->\n";
    echo '<link rel="manifest" href="' . esc_url( $base . 'assets/pwa/manifest.json' ) . '">' . "\n";
    echo '<meta name="theme-color" content="#1e3a5f">' . "\n";
    echo '<meta name="apple-mobile-web-app-capable" content="yes">' . "\n";
    echo '<link rel="apple-touch-icon" href="' . esc_url( $base . 'assets/pwa/icon.svg' ) . '">' . "\n";
    echo '<link rel="stylesheet" href="' . esc_url( $base . 'assets/css/base/chat-widget.css' ) . '" media="all">' . "\n";
    echo '<script src="' . esc_url( $base . 'assets/js/chat-widget/erp-wizards.js' ) . '"></script>' . "\n";
    echo '<script>window.ACC_CHAT_CFG = ' . wp_json_encode( $cfg, JSON_UNESCAPED_UNICODE ) . ';</script>' . "\n";
    echo '<script>if("serviceWorker" in navigator){navigator.serviceWorker.register("' . esc_url( $base . 'assets/pwa/service-worker.js' ) . '",{scope:"' . esc_url( $base ) . '"}).catch(function(){});}</script>' . "\n";
    echo '<script src="' . esc_url( $base . 'assets/js/chat-widget/widget.js' ) . '"></script>' . "\n";
} );
