<?php
/**
 * Svc_Teams — سلسله‌مراتب کارشناس ارشد / کارشناس میدانی
 */
if ( ! defined( 'ABSPATH' ) ) exit;

class Svc_Teams {

    public static function table(): string {
        global $wpdb;
        return $wpdb->prefix . 'svc_technician_teams';
    }

    public static function table_exists(): bool {
        global $wpdb;
        $t = self::table();
        return $wpdb->get_var( "SHOW TABLES LIKE '{$t}'" ) === $t;
    }

    /** آیا کاربر کارشناس ارشد است؟ */
    public static function is_senior( int $user_id ): bool {
        if ( $user_id <= 0 ) return false;
        if ( function_exists( 'acl_user_can' ) && acl_user_can( $user_id, 'service.senior.manage' ) ) {
            return true;
        }
        return self::_has_role( $user_id, 'service_senior' );
    }

    /** آیا کاربر کارشناس میدانی است؟ */
    public static function is_technician( int $user_id ): bool {
        if ( $user_id <= 0 ) return false;
        if ( self::is_senior( $user_id ) ) return false;
        if ( function_exists( 'acl_user_can' ) && acl_user_can( $user_id, 'service.technician.panel' ) ) {
            return true;
        }
        if ( self::_has_role( $user_id, 'service_technician' ) ) {
            return true;
        }
        // عضو فعال تیم یک کارشناس ارشد
        return self::senior_of_technician( $user_id ) !== null;
    }

    /** دسترسی کامل dispatch / همه تیم‌ها */
    public static function is_dispatcher( int $user_id ): bool {
        if ( $user_id <= 0 ) return false;
        if ( function_exists( 'acl_user_can' ) ) {
            if ( acl_user_can( $user_id, 'system.acl.manage' ) || acl_user_can( $user_id, 'service.dispatch' ) ) {
                return true;
            }
        }
        return self::_has_role( $user_id, 'super_admin' ) || self::_has_role( $user_id, 'manager' );
    }

    public static function can_see_all( int $user_id ): bool {
        return self::is_dispatcher( $user_id ) && ! self::is_senior( $user_id );
    }

    /** شناسه کارشناسان زیرمجموعه یک ارشد */
    public static function team_technician_ids( int $senior_user_id ): array {
        if ( ! self::table_exists() ) return [];
        global $wpdb;
        $rows = $wpdb->get_col( $wpdb->prepare(
            "SELECT technician_user_id FROM " . self::table() . "
             WHERE senior_user_id = %d AND status = 'active'",
            $senior_user_id
        ) ) ?: [];
        return array_map( 'intval', $rows );
    }

    /** ارشد یک کارشناس میدانی */
    public static function senior_of_technician( int $technician_user_id ): ?int {
        if ( ! self::table_exists() ) return null;
        global $wpdb;
        $id = $wpdb->get_var( $wpdb->prepare(
            "SELECT senior_user_id FROM " . self::table() . "
             WHERE technician_user_id = %d AND status = 'active' LIMIT 1",
            $technician_user_id
        ) );
        return $id ? (int) $id : null;
    }

    /**
     * محدوده کارشناسان قابل مشاهده برای کاربر جاری
     * null = همه | array = فقط این IDها
     */
    public static function scoped_technician_ids( int $viewer_id ): ?array {
        if ( self::can_see_all( $viewer_id ) || self::_has_role( $viewer_id, 'super_admin' ) ) {
            return null;
        }
        if ( self::is_senior( $viewer_id ) ) {
            return self::team_technician_ids( $viewer_id );
        }
        if ( self::is_technician( $viewer_id ) ) {
            return [ $viewer_id ];
        }
        return [];
    }

    public static function is_admin( int $user_id ): bool {
        return self::can_see_all( $user_id ) || self::_has_role( $user_id, 'super_admin' );
    }

    public static function can_access_technician( int $viewer_id, int $technician_id ): bool {
        $scope = self::scoped_technician_ids( $viewer_id );
        if ( $scope === null ) return true;
        return in_array( $technician_id, $scope, true );
    }

    public static function can_access_request( int $viewer_id, array $request ): bool {
        if ( self::can_see_all( $viewer_id ) || self::_has_role( $viewer_id, 'super_admin' ) ) {
            return true;
        }
        $tech_id = (int) ( $request['assigned_technician_id'] ?? 0 );
        if ( self::is_technician( $viewer_id ) ) {
            return $tech_id === $viewer_id;
        }
        if ( self::is_senior( $viewer_id ) ) {
            if ( ! $tech_id ) return true; // تخصیص‌نشده — ارشد می‌بیند
            return self::can_access_technician( $viewer_id, $tech_id );
        }
        return function_exists( 'acl_user_can' ) && acl_user_can( $viewer_id, 'service.view' );
    }

    public static function can_access_conversation( int $viewer_id, $conv ): bool {
        if ( self::can_see_all( $viewer_id ) || self::_has_role( $viewer_id, 'super_admin' ) ) {
            return true;
        }
        global $wpdb;
        $conv_id = is_array( $conv ) ? (int) ( $conv['id'] ?? 0 ) : (int) $conv;
        $agent_id = is_array( $conv ) ? (int) ( $conv['agent_id'] ?? 0 ) : 0;

        if ( self::is_technician( $viewer_id ) ) {
            if ( $agent_id && $agent_id !== $viewer_id ) {
                // هنوز تخصیص نشده به او
            }
            $req = $wpdb->get_row( $wpdb->prepare(
                "SELECT assigned_technician_id FROM {$wpdb->prefix}svc_requests
                 WHERE conversation_id = %d LIMIT 1",
                $conv_id
            ) );
            if ( $req ) {
                return (int) $req->assigned_technician_id === $viewer_id;
            }
            return $agent_id === $viewer_id || ! $agent_id;
        }

        if ( self::is_senior( $viewer_id ) ) {
            $team = self::team_technician_ids( $viewer_id );
            if ( $agent_id && in_array( $agent_id, $team, true ) ) return true;
            $req = $wpdb->get_row( $wpdb->prepare(
                "SELECT assigned_technician_id FROM {$wpdb->prefix}svc_requests
                 WHERE conversation_id = %d LIMIT 1",
                $conv_id
            ) );
            if ( $req ) {
                $tid = (int) $req->assigned_technician_id;
                if ( ! $tid ) return true;
                return in_array( $tid, $team, true );
            }
            return true; // گفتگوی عمومی بدون درخواست
        }

        return function_exists( 'acl_user_can' ) && acl_user_can( $viewer_id, 'service.view' );
    }

    /** SQL fragment برای فیلتر گفتگوها */
    public static function chat_filter_sql( int $viewer_id ): array {
        global $wpdb;
        $pre = $wpdb->prefix;

        if ( self::can_see_all( $viewer_id ) || self::_has_role( $viewer_id, 'super_admin' ) ) {
            return [ '', [] ];
        }

        if ( self::is_technician( $viewer_id ) ) {
            $sql = " AND (
                c.agent_id = %d
                OR c.id IN (
                    SELECT conversation_id FROM {$pre}svc_requests
                    WHERE assigned_technician_id = %d AND conversation_id IS NOT NULL
                )
            )";
            return [ $sql, [ $viewer_id, $viewer_id ] ];
        }

        if ( self::is_senior( $viewer_id ) ) {
            $team = self::team_technician_ids( $viewer_id );
            if ( ! $team ) {
                return [ " AND 1=0", [] ];
            }
            $placeholders = implode( ',', array_fill( 0, count( $team ), '%d' ) );
            $sql = " AND (
                c.agent_id IN ({$placeholders})
                OR c.id IN (
                    SELECT conversation_id FROM {$pre}svc_requests
                    WHERE (assigned_technician_id IN ({$placeholders}) OR assigned_technician_id IS NULL OR assigned_technician_id = 0)
                      AND conversation_id IS NOT NULL
                )
            )";
            return [ $sql, array_merge( $team, $team ) ];
        }

        return [ " AND 1=0", [] ];
    }

    public static function list_team( int $senior_user_id ): array {
        if ( ! self::table_exists() ) return [];
        global $wpdb;
        return $wpdb->get_results( $wpdb->prepare(
            "SELECT t.*, u.display_name AS technician_name, u.user_email AS technician_email
             FROM " . self::table() . " t
             INNER JOIN {$wpdb->users} u ON u.ID = t.technician_user_id
             WHERE t.senior_user_id = %d
             ORDER BY t.created_at DESC",
            $senior_user_id
        ), ARRAY_A ) ?: [];
    }

    public static function add_team_member( int $senior_user_id, int $technician_user_id ): bool {
        global $wpdb;
        if ( $senior_user_id === $technician_user_id ) return false;
        if ( ! self::table_exists() ) return false;

        $exists = $wpdb->get_var( $wpdb->prepare(
            "SELECT id FROM " . self::table() . " WHERE senior_user_id = %d AND technician_user_id = %d",
            $senior_user_id, $technician_user_id
        ) );
        if ( $exists ) {
            $wpdb->update( self::table(), [
                'status'     => 'active',
                'updated_at' => current_time( 'mysql' ),
            ], [ 'id' => (int) $exists ] );
            return true;
        }

        return (bool) $wpdb->insert( self::table(), [
            'senior_user_id'      => $senior_user_id,
            'technician_user_id'  => $technician_user_id,
            'status'              => 'active',
            'created_at'          => current_time( 'mysql' ),
            'updated_at'          => current_time( 'mysql' ),
        ] );
    }

    public static function remove_team_member( int $senior_user_id, int $technician_user_id ): bool {
        global $wpdb;
        if ( ! self::table_exists() ) return false;
        return (bool) $wpdb->update( self::table(), [
            'status'     => 'inactive',
            'updated_at' => current_time( 'mysql' ),
        ], [
            'senior_user_id'     => $senior_user_id,
            'technician_user_id' => $technician_user_id,
        ] );
    }

    private static function _has_role( int $user_id, string $slug ): bool {
        global $wpdb;
        $cnt = (int) $wpdb->get_var( $wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}acl_user_roles ur
             INNER JOIN {$wpdb->prefix}acl_roles r ON r.id = ur.role_id
             WHERE ur.user_id = %d AND r.slug = %s",
            $user_id, $slug
        ) );
        return $cnt > 0;
    }
}
