<?php
namespace App\Controllers;

require_once BASE_PATH . '/app/helpers/view_compat.php';

require_once BASE_PATH . '/app/helpers/permissions.php';

use App\Core\Database;
use App\Services\TrackChairScope;

class AdminBusinessToolsController
{
    protected function db()
    {
        return Database::getInstance();
    }

    private function startSession(): void
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }
    }

    private function role(): string
    {
        return (string)($_SESSION['conference_role'] ?? $_SESSION['role'] ?? $_SESSION['user_role'] ?? '');
    }

    private function requireAccess(): void
    {
        $this->startSession();

        if (empty($_SESSION['user_id'])) {
            header("Location: /easychair/login");
            exit;
        }

        if (empty($_SESSION['conference_id'])) {
            header("Location: /easychair/select-conference");
            exit;
        }

        if (!in_array($this->role(), ['superadmin','org_admin','admin','organizer','conference_chair','track_chair','section_editor'], true)) {
            http_response_code(403);
            exit(function_exists('t') ? t('msg.access_denied', 'Access denied.') : 'Access denied.');
        }
    }

    private function conference(): array
    {
        $stmt = $this->db()->prepare("SELECT * FROM conferences WHERE id=? LIMIT 1");
        $stmt->execute([(int)$_SESSION['conference_id']]);
        $c = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$c) {
            exit('Conference not found.');
        }

        if (!ec_is_superadmin() && (int)$c['org_id'] !== (int)($_SESSION['org_id'] ?? 0)) {
            http_response_code(403);
            exit(function_exists('t') ? t('msg.access_denied', 'Access denied.') : 'Access denied.');
        }

        return $c;
    }

    private function cols(string $table): array
    {
        try {
            $stmt = $this->db()->query("DESCRIBE {$table}");
            return array_map(fn($r) => $r['Field'], $stmt->fetchAll(\PDO::FETCH_ASSOC));
        } catch (\Throwable $e) {
            return [];
        }
    }

    private function insertDynamic(string $table, array $data): void
    {
        $cols = $this->cols($table);
        $data = array_filter($data, fn($k) => in_array($k, $cols, true), ARRAY_FILTER_USE_KEY);

        if (!$data) {
            return;
        }

        $names = array_keys($data);
        $sql = "INSERT INTO {$table} (`" . implode('`,`', $names) . "`) VALUES (" . implode(',', array_fill(0, count($names), '?')) . ")";
        $stmt = $this->db()->prepare($sql);
        $stmt->execute(array_values($data));
    }

    private function deleteById(string $table, int $id, array $conference): void
    {
        $stmt = $this->db()->prepare("DELETE FROM {$table} WHERE id=? AND conference_id=? AND org_id=?");
        $stmt->execute([$id, (int)$conference['id'], (int)$conference['org_id']]);
    }

    private function view(string $tool, array $data = []): void
    {
        extract($data);

        ob_start();
        require BASE_PATH . '/app/views/admin/business_tools/index.php';
        $content = ob_get_clean();

        require BASE_PATH . '/app/views/layouts/admin_layout.php';
    }

    public function committeeImages()
    {
        $this->requireAccess();
        $conference = $this->conference();

        $stmt = $this->db()->prepare("
            SELECT *
            FROM conference_committee_people
            WHERE conference_id=? AND org_id=?
            ORDER BY sort_order, id DESC
        ");
        $stmt->execute([(int)$conference['id'], (int)$conference['org_id']]);
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        //$this->view('committee_images', compact('conference','rows'));

$tool = 'committee_images';

$this->view(
    $tool,
    compact(
        'tool',
        'conference',
        'rows'
    )
);

    }



    public function saveCommitteeImage()
    {
        $this->requireAccess();
        $conference = $this->conference();

        $imagePath = null;

        if (!empty($_FILES['image']['name']) && is_uploaded_file($_FILES['image']['tmp_name'])) {

            //$dir = BASE_PATH . 'uploads/committee/' . (int)$conference['id'];

$dir =
    BASE_PATH .
    '/public/uploads/committee/' .
    (int)$conference['id'];

if (!is_dir($dir)) {
                mkdir($dir, 0775, true);
            }

            $ext = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));
            if (!in_array($ext, ['jpg','jpeg','png','webp','gif'], true)) {
                $ext = 'jpg';
            }

            $name = 'committee_' . time() . '_' . mt_rand(1000,9999) . '.' . $ext;
            move_uploaded_file($_FILES['image']['tmp_name'], $dir . '/' . $name);
            $imagePath = 'uploads/committee/' . (int)$conference['id'] . '/' . $name;
        }

        $this->insertDynamic('conference_committee_people', [
            'org_id' => (int)$conference['org_id'],
            'conference_id' => (int)$conference['id'],
            'committee_type' => trim((string)($_POST['committee_type'] ?? 'other')),
            'full_name_ar' => trim((string)($_POST['full_name_ar'] ?? '')),
            'full_name_en' => trim((string)($_POST['full_name_en'] ?? '')),
            'email' => trim((string)($_POST['email'] ?? '')),
            'affiliation_ar' => trim((string)($_POST['affiliation_ar'] ?? '')),
            'affiliation_en' => trim((string)($_POST['affiliation_en'] ?? '')),
            'role_title_ar' => trim((string)($_POST['role_title_ar'] ?? '')),
            'role_title_en' => trim((string)($_POST['role_title_en'] ?? '')),
            'image_path' => $imagePath,
            'sort_order' => (int)($_POST['sort_order'] ?? 0),
            'is_visible' => !empty($_POST['is_visible']) ? 1 : 0,
            'created_by' => (int)$_SESSION['user_id'],
        ]);

$titleAr =
trim((string)($_POST['role_title_ar'] ?? ''));

$titleEn =
trim((string)($_POST['role_title_en'] ?? ''));

if ($titleAr === '') {

    $mapAr = [
        'tpc'        => 'عضو اللجنة العلمية',
        'chair'      => 'رئيس مؤتمر',
        'editor'     => 'محرر',
        'organizing' => 'عضو اللجنة المنظمة',
        'scientific' => 'عضو اللجنة العلمية',
        'reviewer'   => 'محكم',
        'patron'     => 'راعي المؤتمر',
    ];

    $titleAr =
        $mapAr[$_POST['committee_type'] ?? '']
        ?? 'عضو لجنة';
}

if ($titleEn === '') {

    $mapEn = [
        'tpc'        => 'Technical Program Committee',
        'chair'      => 'Conference Chair',
        'editor'     => 'Editor',
        'organizing' => 'Organizing Committee',
        'scientific' => 'Scientific Committee',
        'reviewer'   => 'Reviewer',
        'patron'     => 'Patron',
    ];

    $titleEn =
        $mapEn[$_POST['committee_type'] ?? '']
        ?? 'Committee Member';
}

$this->insertDynamic('conference_committees', [

    'org_id' =>
        (int)$conference['org_id'],

    'conference_id' =>
        (int)$conference['id'],

    'committee_type' =>
        trim((string)($_POST['committee_type'] ?? 'other')),

    'full_name_ar' =>
        trim((string)($_POST['full_name_ar'] ?? '')),

    'full_name_en' =>
        trim((string)($_POST['full_name_en'] ?? '')),


    'affiliation_ar' =>
        trim((string)($_POST['affiliation_ar'] ?? '')),

    'affiliation_en' =>
        trim((string)($_POST['affiliation_en'] ?? '')),

    'email' =>
        trim((string)($_POST['email'] ?? '')),

    'image_path' =>
        $imagePath,

    'sort_order' =>
        (int)($_POST['sort_order'] ?? 0),

    'is_active' => 1,

    'created_by' =>
        (int)$_SESSION['user_id']

]);

        header("Location: /easychair/admin/committee-images");
        exit;
    }

public function updateCommitteeImage()
{
    $this->requireAccess();

    $conference = $this->conference();

    $imagePath = null;

    if (
        !empty($_FILES['image']['name'])
        &&
        is_uploaded_file($_FILES['image']['tmp_name'])
    ) {

        $dir =
            BASE_PATH .
            '/public/uploads/committee/' .
            (int)$conference['id'];

        if (!is_dir($dir)) {
            mkdir($dir,0775,true);
        }

        $ext =
            strtolower(
                pathinfo(
                    $_FILES['image']['name'],
                    PATHINFO_EXTENSION
                )
            );

        $name =
            'committee_' .
            time() .
            '_' .
            mt_rand(1000,9999) .
            '.' .
            $ext;

        move_uploaded_file(
            $_FILES['image']['tmp_name'],
            $dir . '/' . $name
        );

        $imagePath =
            'uploads/committee/' .
            (int)$conference['id'] .
            '/' .
            $name;
    }

    $sql = "
        UPDATE conference_committee_people
        SET
            committee_type=?,
            full_name_ar=?,
            full_name_en=?,
            email=?,
            affiliation_ar=?,
            affiliation_en=?,
            role_title_ar=?,
            role_title_en=?,
            sort_order=?
    ";

    $params = [

        trim($_POST['committee_type'] ?? ''),

        trim($_POST['full_name_ar'] ?? ''),

        trim($_POST['full_name_en'] ?? ''),

        trim($_POST['email'] ?? ''),

        trim($_POST['affiliation_ar'] ?? ''),

        trim($_POST['affiliation_en'] ?? ''),

        trim($_POST['role_title_ar'] ?? ''),

        trim($_POST['role_title_en'] ?? ''),

        (int)($_POST['sort_order'] ?? 0)
    ];

    if ($imagePath) {

        $sql .= ",
            image_path=?
        ";

        $params[] = $imagePath;
    }

    $sql .= "
        WHERE id=?
          AND conference_id=?
          AND org_id=?
    ";

    $params[] = (int)$_POST['id'];
    $params[] = (int)$conference['id'];
    $params[] = (int)$conference['org_id'];

    $stmt =
        $this->db()->prepare($sql);

    $stmt->execute($params);

    header(
        "Location: /easychair/admin/committee-images"
    );

    exit;
}

    public function editCommitteeImage()
{
    $this->requireAccess();

    $conference = $this->conference();

    $stmt = $this->db()->prepare("
        SELECT *
        FROM conference_committee_people
        WHERE id=?
          AND conference_id=?
          AND org_id=?
        LIMIT 1
    ");

    $stmt->execute([
        (int)($_GET['id'] ?? 0),
        (int)$conference['id'],
        (int)$conference['org_id']
    ]);

    $item =
        $stmt->fetch(\PDO::FETCH_ASSOC);

    if (!$item) {
        die('Committee member not found');
    }



    require BASE_PATH .
        '/app/views/admin/committee_image_edit.php';
 $content = ob_get_clean();

        require BASE_PATH .
        '/app/views/layouts/admin_layout.php';

}

    public function reviewerAssignments()
{
$db=\App\Core\Database::getInstance();

$conference=$this->conference();

$submissions=[];

$isTrackChair =
    (($_SESSION['conference_role'] ?? $_SESSION['role'] ?? '') === 'track_chair');

$trackIds =
    class_exists('\App\Services\TrackChairScope')
        ? \App\Services\TrackChairScope::trackIds()
        : [];

$submissionTrackSql='';

if(
    $isTrackChair
    &&
    !empty($trackIds)
){
    $submissionTrackSql=
        ' AND track_id IN ('.
        implode(',',array_map('intval',$trackIds)).
        ') ';
}
elseif($isTrackChair){
    $submissionTrackSql=' AND 1=0 ';
}

$stmt=$db->prepare("
SELECT
id,
submission_no,
title,
title_ar,
track_id
FROM submissions
WHERE conference_id=?
{$submissionTrackSql}
ORDER BY id DESC
");

$stmt->execute([
(int)$conference['id']
]);

$submissions=
$stmt->fetchAll(
\PDO::FETCH_ASSOC
);

error_log(
'PACK831C_SUBMISSIONS='.
json_encode(
array_column(
$submissions,
'id'
)
)
);

$reviewers=[];

$stmt=$db->prepare("
SELECT
u.id,
u.first_name,
u.last_name,
u.email

FROM conference_reviewers cr

JOIN users u
ON u.id=cr.user_id

WHERE
cr.conference_id=?
AND u.is_active=1

ORDER BY
u.first_name,
u.last_name
");

$stmt->execute([
(int)$conference['id']
]);

$reviewers=
$stmt->fetchAll(
\PDO::FETCH_ASSOC
);

/*
--------------------------------------------------
PACK840A
REVIEWER METRICS
--------------------------------------------------
*/

$activeMap=[];
$completedMap=[];
$performanceMap=[];

$riskMap=[];
$awardMap=[];


/*
---------------------------------------------------
PACK843B
REVIEWER PERFORMANCE MAP
---------------------------------------------------
*/

try{

    $rowsP=
    $db->query("
        SELECT
        reviewer_id,
        final_score,
        completion_rate,
        acceptance_rate,
        quality_score
        FROM reviewer_performance
        WHERE conference_id=".
        (int)$conference['id']
    )->fetchAll(\PDO::FETCH_ASSOC);

    foreach($rowsP as $r){

        $performanceMap[
            (int)$r['reviewer_id']
        ]=$r;
    }


}catch(\Throwable $e){}

/*
----------------------------------------------------
PACK848A
RISK MAP
----------------------------------------------------
*/

try{

    $riskRows=
    $db->query("
        SELECT
        reviewer_id,
        risk_level,
        risk_score
        FROM reviewer_risk_flags
        WHERE conference_id=".
        (int)$conference['id']."
        AND is_active=1
    ")->fetchAll(\PDO::FETCH_ASSOC);

    foreach($riskRows as $r){

        $riskMap[
            (int)$r['reviewer_id']
        ]=$r;
    }

}catch(\Throwable $e){}

/*
----------------------------------------------------
PACK848A
AWARD MAP
----------------------------------------------------
*/

try{

    $awardRows=
    $db->query("
        SELECT
        reviewer_id,
        award_type
        FROM reviewer_awards
        WHERE conference_id=".
        (int)$conference['id']."
    ")->fetchAll(\PDO::FETCH_ASSOC);

    foreach($awardRows as $r){

        $awardMap[
            (int)$r['reviewer_id']
        ]=$r['award_type'];
    }

}catch(\Throwable $e){}

try{

    $rowsA=
    $db->query("
        SELECT
        reviewer_id,
        COUNT(*) c
        FROM review_assignments
        WHERE status IN
        (
            'assigned',
            'accepted'
        )
        GROUP BY reviewer_id
    ")->fetchAll(\PDO::FETCH_ASSOC);

    foreach($rowsA as $r){

        $activeMap[
            (int)$r['reviewer_id']
        ]=(int)$r['c'];
    }

}catch(\Throwable $e){}

try{

    $rowsC=
    $db->query("
        SELECT
        reviewer_id,
        COUNT(*) c
        FROM review_assignments
        WHERE status='completed'
        GROUP BY reviewer_id
    ")->fetchAll(\PDO::FETCH_ASSOC);

    foreach($rowsC as $r){

        $completedMap[
            (int)$r['reviewer_id']
        ]=(int)$r['c'];
    }

}catch(\Throwable $e){}

$maxCapacity=5;

try{

    $cfg=
    $db->query("
        SELECT max_active_reviews
        FROM conference_review_settings
        WHERE conference_id=".
        (int)$conference['id']."
        LIMIT 1
    ")->fetchColumn();

    if($cfg){
        $maxCapacity=(int)$cfg;
    }

}catch(\Throwable $e){}

foreach($reviewers as &$rv){

    $rid=(int)$rv['id'];

    $active=
    (int)(
        $activeMap[$rid]
        ??
        0
    );

    $completed=
    (int)(
        $completedMap[$rid]
        ??
        0
    );

    $rv['active_assignments']=$active;

    $rv['completed_reviews']=$completed;

    $rv['capacity_limit']=$maxCapacity;

    $rv['capacity_percent']=
    $maxCapacity>0
    ?
    round(
        ($active/$maxCapacity)*100
    )
    :
    0;

    $perf=
    $performanceMap[$rid]
    ??
    [];

    $rv['final_score']=
    (float)(
        $perf['final_score']
        ??
        0
    );

    $rv['completion_rate']=
    (float)(
        $perf['completion_rate']
        ??
        0
    );

    $rv['acceptance_rate']=
    (float)(
        $perf['acceptance_rate']
        ??
        0
    );

    $rv['quality_score']=
    (float)(
        $perf['quality_score']
        ??
        0
    );


    $riskLevel=
    $riskMap[$rid]['risk_level']
    ??
    'low';

    $riskScore=
    (float)(
        $riskMap[$rid]['risk_score']
        ??
        0
    );

    $awardType=
    $awardMap[$rid]
    ??
    '';

    $awardBonus=0;

    if($awardType==='Gold Reviewer'){
        $awardBonus=15;
    }
    elseif($awardType==='Silver Reviewer'){
        $awardBonus=10;
    }
    elseif($awardType==='Bronze Reviewer'){
        $awardBonus=5;
    }

    $riskPenalty=0;

    if($riskLevel==='high'){
        $riskPenalty=20;
    }
    elseif($riskLevel==='medium'){
        $riskPenalty=10;
    }

    $rv['award_type']=$awardType;
    $rv['risk_level']=$riskLevel;
    $rv['risk_score']=$riskScore;

    $rv['intelligent_score']=round(

        (
            ((float)$rv['final_score'] * 0.35)
            +
            ((float)$rv['completion_rate'] * 0.15)
            +
            ((float)$rv['acceptance_rate'] * 0.10)
            +
            ((float)$rv['quality_score'] * 0.10)
            +
            ((float)(float)($rv['track_experience'] ?? 0) * 0.20)
            -
            ((float)$rv['capacity_percent'] * 0.10)
        )

        +

        $awardBonus

        -

        $riskPenalty

    ,2);

}
unset($rv);

$rows=[];

/*
--------------------------------------------------
PACK824 FIX
TRACK CHAIR SCOPE INIT
--------------------------------------------------
*/

$isTrackChair =
    (($_SESSION['conference_role'] ?? $_SESSION['role'] ?? '') === 'track_chair');

$trackIds =
    class_exists('\App\Services\TrackChairScope')
        ? \App\Services\TrackChairScope::trackIds()
        : [];

$trackSql = '';

if (
    $isTrackChair &&
    !empty($trackIds)
) {

    $trackSql =
        " AND s.track_id IN (" .
        implode(',', array_map('intval',$trackIds))
        . ") ";

} elseif ($isTrackChair) {

    $trackSql =
        " AND 1=0 ";
}

$stmt=$db->prepare("
SELECT
ra.*,

s.submission_no,
s.title,
s.title_ar,

u.first_name,
u.last_name,
u.email

FROM review_assignments ra

LEFT JOIN submissions s
ON s.id=ra.submission_id

LEFT JOIN users u
ON u.id=ra.reviewer_id

WHERE
ra.conference_id=?
{$trackSql}

ORDER BY
ra.id DESC
");

$stmt->execute([
(int)$conference['id']
]);

$rows=
$stmt->fetchAll(
\PDO::FETCH_ASSOC
);


/*
--------------------------------------------------
PACK839A
SLA METRICS - TRACK SCOPE SAFE
--------------------------------------------------
*/

$pendingReviews=0;
$overdueReviews=0;
$criticalReviews=0;

foreach($rows as &$r){

    $assignedTs=
    strtotime(
        $r['assigned_at']
        ??
        $r['created_at']
        ??
        'now'
    );

    $ageDays=
    max(
        0,
        (int)floor(
            (time()-$assignedTs)/86400
        )
    );

    $r['age_days']=$ageDays;

    $status=
    strtolower(
        (string)($r['status'] ?? '')
    );

    if(
        in_array(
            $status,
            ['assigned','accepted'],
            true
        )
    ){

        $pendingReviews++;

        if($ageDays>=14){
            $overdueReviews++;
        }

        if($ageDays>=21){
            $criticalReviews++;
        }
    }
}
unset($r);

try{

    $remindersSent=
    (int)$db->query("
        SELECT COUNT(*)
        FROM review_assignment_reminders
    ")->fetchColumn();

}catch(\Throwable $e){

    $remindersSent=0;

}

error_log(
'PACK839_SCOPED_PENDING='.
$pendingReviews
);



ob_start();

$pendingReviews=$pendingReviews ?? 0;
$overdueReviews=$overdueReviews ?? 0;
$criticalReviews=$criticalReviews ?? 0;
$remindersSent=$remindersSent ?? 0;

$overloadedReviewers=
$overloadedReviewers ?? 0;

require
BASE_PATH
.
'/app/views/admin/reviewer_assignments/index.php';

$content=
ob_get_clean();

require
BASE_PATH
.
'/app/views/layouts/admin_layout.php';

return;
}



/*
--------------------------------------------------
PACK845A
REVIEWER ANALYTICS
--------------------------------------------------
*/

public function reviewerAnalytics()
{
    $this->requireAccess();

    $conference=
    $this->conference();

    $db=
    \App\Core\Database::getInstance();

    $cid=
    (int)$conference['id'];

    $leaderboard=
    $db->query("
        SELECT
        rp.*,
        u.first_name,
        u.last_name,
        u.email
        FROM reviewer_performance rp
        JOIN users u
        ON u.id=rp.reviewer_id
        WHERE rp.conference_id=".$cid."
        ORDER BY rp.final_score DESC
        LIMIT 50
    ")->fetchAll(\PDO::FETCH_ASSOC);

    $overloaded=
    $db->query("
        SELECT
        reviewer_id,
        COUNT(*) active_reviews
        FROM review_assignments
        WHERE conference_id=".$cid."
        AND status IN
        (
            'assigned',
            'accepted'
        )
        GROUP BY reviewer_id
        HAVING COUNT(*)>=5
        ORDER BY active_reviews DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();

    require
    BASE_PATH.
    '/app/views/admin/reviewer_analytics/index.php';

    $content=
    ob_get_clean();

    require
    BASE_PATH.
    '/app/views/layouts/admin_layout.php';

    return;
}




/*
--------------------------------------------------
PACK847A
REVIEWER CERTIFICATES
--------------------------------------------------
*/

public function reviewerCertificates()
{
    $this->requireAccess();

    $conference=
    $this->conference();

    $db=
    \App\Core\Database::getInstance();

    $cid=
    (int)$conference['id'];

    $rows=
    $db->query("
        SELECT
        ra.*,
        u.first_name,
        u.last_name,
        u.email
        FROM reviewer_awards ra
        JOIN users u
        ON u.id=ra.reviewer_id
        WHERE ra.conference_id=".$cid."
        ORDER BY ra.score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();

    require
    BASE_PATH.
    '/app/views/admin/reviewer_certificates/index.php';

    $content=
    ob_get_clean();

    require
    BASE_PATH.
    '/app/views/layouts/admin_layout.php';

    return;
}




public function generateReviewerCertificate()
{
    $this->requireAccess();

    $conference=$this->conference();

    $db=\App\Core\Database::getInstance();

    $reviewerId=
    (int)($_GET['id'] ?? 0);

    if(!$reviewerId){
        die('Invalid reviewer');
    }

    $stmt=$db->prepare("
        SELECT *
        FROM reviewer_awards
        WHERE reviewer_id=?
        AND conference_id=?
        ORDER BY score DESC
        LIMIT 1
    ");

    $stmt->execute([
        $reviewerId,
        (int)$conference['id']
    ]);

    $award=
    $stmt->fetch(\PDO::FETCH_ASSOC);

    if(!$award){
        die('No reviewer award found');
    }

    $certificateNo=
    'RC-'
    .date('Y')
    .'-'
    .$reviewerId
    .'-'
    .time();

    $db->prepare("
        INSERT INTO reviewer_certificates
        (
            conference_id,
            reviewer_id,
            award_type,
            certificate_no,
            score,
            generated_by,
            generated_at
        )
        VALUES
        (
            ?,?,?,?,?,?,NOW()
        )
    ")->execute([
        $conference['id'],
        $reviewerId,
        $award['award_type'],
        $certificateNo,
        $award['score'],
        $_SESSION['user_id']
    ]);

    header(
    'Location:/easychair/admin/reviewer-certificates'
    );

    exit;
}




/*
--------------------------------------------------
PACK847B
REVIEWER RECOGNITION REPORTS
--------------------------------------------------
*/

public function reviewerRecognition()
{
    $this->requireAccess();

    $conference=
    $this->conference();

    $db=
    \App\Core\Database::getInstance();

    $cid=
    (int)$conference['id'];

    $topReviewers=
    $db->query("
        SELECT
        rp.*,
        u.first_name,
        u.last_name,
        u.email
        FROM reviewer_performance rp
        JOIN users u
        ON u.id=rp.reviewer_id
        WHERE rp.conference_id=".$cid."
        ORDER BY rp.final_score DESC
        LIMIT 20
    ")->fetchAll(\PDO::FETCH_ASSOC);

    $awards=
    $db->query("
        SELECT *
        FROM reviewer_awards
        WHERE conference_id=".$cid."
        ORDER BY score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    $riskReviewers=
    $db->query("
        SELECT *
        FROM reviewer_risk_flags
        WHERE conference_id=".$cid."
        AND is_active=1
        ORDER BY risk_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    $certificateCount=
    (int)$db->query("
        SELECT COUNT(*)
        FROM reviewer_certificates
        WHERE conference_id=".$cid."
    ")->fetchColumn();

    ob_start();

    require
    BASE_PATH.
    '/app/views/admin/reviewer_recognition/index.php';

    $content=
    ob_get_clean();

    require
    BASE_PATH.
    '/app/views/layouts/admin_layout.php';

    return;
}





/*
--------------------------------------------------
PACK851A
AUTO ASSIGN REVIEWERS
--------------------------------------------------
*/

public function autoAssignReviewers()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $conference=$this->conference();

    $submissionId=
    (int)($_GET['submission_id'] ?? 0);

    if(!$submissionId){
        die('Submission required');
    }

    $cid=(int)$conference['id'];

    $reviewers=
    $db->query("
        SELECT *
        FROM reviewer_performance
        WHERE conference_id=".$cid."
        ORDER BY final_score DESC
        LIMIT 3
    ")->fetchAll(\PDO::FETCH_ASSOC);

    $submissionRow=
    $db->prepare("
        SELECT
        s.*,
        u.email AS author_email
        FROM submissions s
        LEFT JOIN users u
        ON u.id=s.user_id
        WHERE s.id=?
        LIMIT 1
    ");

    $submissionRow->execute([
        $submissionId
    ]);

    $submission=
    $submissionRow->fetch(\PDO::FETCH_ASSOC);

    foreach($reviewers as $r){

        $reviewerRow=
        $db->prepare("
            SELECT *
            FROM users
            WHERE id=?
            LIMIT 1
        ");

        $reviewerRow->execute([
            $r['reviewer_id']
        ]);

        $reviewer=
        $reviewerRow->fetch(\PDO::FETCH_ASSOC);

        $conflicts=
        \App\Services\ReviewerConflictService::detect(
            $submission ?: [],
            $reviewer ?: []
        );

        if(!empty($conflicts)){

            foreach($conflicts as $c){

                $db->prepare("
                    INSERT INTO reviewer_conflicts
                    (
                        conference_id,
                        submission_id,
                        reviewer_id,
                        conflict_type,
                        conflict_reason,
                        risk_score
                    )
                    VALUES
                    (
                        ?,?,?,?,?,?
                    )
                ")->execute([
                    $cid,
                    $submissionId,
                    $r['reviewer_id'],
                    $c['type'],
                    $c['reason'],
                    $c['risk']
                ]);

            }

            continue;
        }

        $exists=
        $db->prepare("
            SELECT COUNT(*)
            FROM review_assignments
            WHERE submission_id=?
            AND reviewer_id=?
        ");

        $exists->execute([
            $submissionId,
            $r['reviewer_id']
        ]);

        if($exists->fetchColumn()){
            continue;
        }

        $db->prepare("
            INSERT INTO review_assignments
            (
                submission_id,
                reviewer_id,
                status,
                created_at
            )
            VALUES
            (
                ?,
                ?,
                'assigned',
                NOW()
            )
        ")->execute([
            $submissionId,
            $r['reviewer_id']
        ]);

        $db->prepare("
            INSERT INTO reviewer_auto_assignments
            (
                conference_id,
                submission_id,
                reviewer_id,
                assignment_score,
                assignment_reason,
                assigned_by
            )
            VALUES
            (
                ?,?,?,?,?,?
            )
        ")->execute([
            $cid,
            $submissionId,
            $r['reviewer_id'],
            $r['final_score'],
            'Auto selected by Pack851A',
            $_SESSION['user_id']
        ]);
    }

    $_SESSION['toast']=[
        'type'=>'success',
        'msg'=>'Top reviewers assigned automatically'
    ];

    header(
    'Location:/easychair/admin/reviewer-assignments'
    );

    exit;
}



/*
--------------------------------------------------
PACK870A
UNIFIED INTELLIGENCE HUB
--------------------------------------------------
*/

public function intelligenceHub()
{
    $this->requireAccess();

    ob_start();
?>

<div class="container-fluid">

<h2 class="mb-4">
Unified Intelligence Hub
</h2>

<div class="row">

<?php

$modules=[

['Executive Briefing',
'/easychair/admin/executive-briefing',
'bg-primary'],

['Executive Command Center',
'/easychair/admin/executive-command-center',
'bg-success'],

['Portfolio Intelligence',
'/easychair/admin/portfolio-intelligence',
'bg-dark'],

['Governance Intelligence',
'/easychair/admin/governance-intelligence',
'bg-info'],

['Strategic Optimization',
'/easychair/admin/strategic-optimization',
'bg-warning'],

['Self Healing',
'/easychair/admin/self-healing',
'bg-danger'],

['AI Operations Center',
'/easychair/admin/ai-operations-center',
'bg-secondary'],

['Predictive Intelligence',
'/easychair/admin/predictive-intelligence',
'bg-primary']

];

foreach($modules as $m):

?>

<div class="col-md-3 mb-4">

<div class="card shadow">

<div class="card-header <?= $m[2] ?> text-white">

<?= htmlspecialchars($m[0]) ?>

</div>

<div class="card-body text-center">

<a
class="btn btn-outline-dark"
href="<?= htmlspecialchars($m[1]) ?>"
>

Open

</a>

</div>

</div>

</div>

<?php endforeach; ?>

</div>

</div>

<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}



/*
--------------------------------------------------
PACK869A
EXECUTIVE BRIEFING
--------------------------------------------------
*/

public function executiveBriefing()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $brief=
    $db->query("
        SELECT *
        FROM executive_briefings
        ORDER BY id DESC
        LIMIT 1
    ")->fetch(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-lg border-primary">

<div class="card-header bg-primary text-white">

<h2 class="mb-0">
AI Executive Briefing
</h2>

</div>

<div class="card-body">

<div class="alert alert-info">

<h4>Executive Summary</h4>

<p>
<?= nl2br(htmlspecialchars($brief['summary_text'] ?? '')) ?>
</p>

</div>

<div class="row">

<div class="col-md-4">

<div class="card border-danger">

<div class="card-header">
Top Risks
</div>

<div class="card-body">
<?= nl2br(htmlspecialchars($brief['top_risks'] ?? '')) ?>
</div>

</div>

</div>

<div class="col-md-4">

<div class="card border-success">

<div class="card-header">
Opportunities
</div>

<div class="card-body">
<?= nl2br(htmlspecialchars($brief['top_opportunities'] ?? '')) ?>
</div>

</div>

</div>

<div class="col-md-4">

<div class="card border-warning">

<div class="card-header">
Recommended Actions
</div>

<div class="card-body">
<?= nl2br(htmlspecialchars($brief['recommended_actions'] ?? '')) ?>
</div>

</div>

</div>

</div>

</div>

</div>

</div>

<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}



/*
--------------------------------------------------
PACK868A
EXECUTIVE COMMAND CENTER
--------------------------------------------------
*/

public function executiveCommandCenter()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $ecc=
    $db->query("
        SELECT *
        FROM executive_command_center
        ORDER BY id DESC
        LIMIT 1
    ")->fetch(\PDO::FETCH_ASSOC);

    $portfolio=
    $db->query("
        SELECT *
        FROM conference_portfolio_intelligence
        ORDER BY portfolio_rank
        LIMIT 10
    ")->fetchAll(\PDO::FETCH_ASSOC);

    $governance=
    $db->query("
        SELECT *
        FROM organization_governance_intelligence
        ORDER BY governance_score DESC
        LIMIT 10
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<h2 class="mb-4">
Executive Command Center
</h2>

<div class="row">

<div class="col-md-3">
<div class="card shadow border-primary">
<div class="card-body">
<h6>Total Conferences</h6>
<h2><?= (int)($ecc['total_conferences'] ?? 0) ?></h2>
</div>
</div>
</div>

<div class="col-md-3">
<div class="card shadow border-success">
<div class="card-body">
<h6>Organizations</h6>
<h2><?= (int)($ecc['total_organizations'] ?? 0) ?></h2>
</div>
</div>
</div>

<div class="col-md-3">
<div class="card shadow border-warning">
<div class="card-body">
<h6>Average Health</h6>
<h2><?= htmlspecialchars($ecc['avg_health_score'] ?? 0) ?></h2>
</div>
</div>
</div>

<div class="col-md-3">
<div class="card shadow border-danger">
<div class="card-body">
<h6>High Risk Conferences</h6>
<h2><?= (int)($ecc['high_risk_conferences'] ?? 0) ?></h2>
</div>
</div>
</div>

</div>

<br>

<div class="row">

<div class="col-md-6">

<div class="card shadow">

<div class="card-header bg-dark text-white">
Portfolio Ranking
</div>

<div class="card-body">

<table class="table table-bordered table-sm">

<tr>
<th>Rank</th>
<th>Conference</th>
<th>Score</th>
<th>Risk</th>
</tr>

<?php foreach($portfolio as $r): ?>

<tr>

<td>#<?= (int)$r['portfolio_rank'] ?></td>

<td>
<?= (int)$r['conference_id'] ?>
</td>

<td>
<?= $r['overall_score'] ?>
</td>

<td>
<?= htmlspecialchars($r['risk_level']) ?>
</td>

</tr>

<?php endforeach; ?>

</table>

</div>

</div>

</div>

<div class="col-md-6">

<div class="card shadow">

<div class="card-header bg-primary text-white">
Governance Ranking
</div>

<div class="card-body">

<table class="table table-bordered table-sm">

<tr>
<th>Org</th>
<th>Health</th>
<th>Gap</th>
<th>Score</th>
</tr>

<?php foreach($governance as $r): ?>

<tr>

<td><?= (int)$r['org_id'] ?></td>

<td><?= $r['avg_health_score'] ?></td>

<td><?= $r['avg_kpi_gap'] ?></td>

<td><?= $r['governance_score'] ?></td>

</tr>

<?php endforeach; ?>

</table>

</div>

</div>

</div>

</div>

<br>

<div class="row">

<div class="col-md-4">

<div class="card shadow">

<div class="card-body">

<h5>Best Conference</h5>

<h2>
#<?= (int)($ecc['portfolio_best_conference'] ?? 0) ?>
</h2>

</div>

</div>

</div>

<div class="col-md-4">

<div class="card shadow">

<div class="card-body">

<h5>Best Organization</h5>

<h2>
#<?= (int)($ecc['governance_best_org'] ?? 0) ?>
</h2>

</div>

</div>

</div>

<div class="col-md-4">

<div class="card shadow">

<div class="card-body">

<h5>Pending Actions</h5>

<h2>
<?= (int)($ecc['pending_actions'] ?? 0) ?>
</h2>

<div>
Healing:
<?= (int)($ecc['pending_healing'] ?? 0) ?>
</div>

</div>

</div>

</div>

</div>

</div>

<?php

    $content=ob_get_clean();

    require BASE_PATH.'/app/views/layouts/admin_layout.php';

    return;
}



/*
--------------------------------------------------
PACK866A
PORTFOLIO INTELLIGENCE
--------------------------------------------------
*/

public function portfolioIntelligence()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT
        cpi.*,
        c.title_en,
        c.title_ar
        FROM conference_portfolio_intelligence cpi
        LEFT JOIN conferences c
        ON c.id=cpi.conference_id
        ORDER BY cpi.portfolio_rank
    ")->fetchAll(\PDO::FETCH_ASSOC);

    $best=$rows[0] ?? null;
    $worst=end($rows);

    ob_start();
?>

<div class="container-fluid">

<div class="row mb-4">

<div class="col-md-3">
<div class="card border-success shadow">
<div class="card-body">
<h6>Best Conference</h6>
<h4><?= htmlspecialchars($best['title_en'] ?? '-') ?></h4>
<div>Score: <?= $best['overall_score'] ?? 0 ?></div>
</div>
</div>
</div>

<div class="col-md-3">
<div class="card border-danger shadow">
<div class="card-body">
<h6>Needs Intervention</h6>
<h4><?= htmlspecialchars($worst['title_en'] ?? '-') ?></h4>
<div>Gap: <?= $worst['optimization_gap'] ?? 0 ?></div>
</div>
</div>
</div>

<div class="col-md-3">
<div class="card shadow">
<div class="card-body">
<h6>Total Conferences</h6>
<h3><?= count($rows) ?></h3>
</div>
</div>
</div>

<div class="col-md-3">
<div class="card shadow">
<div class="card-body">
<h6>Portfolio Intelligence</h6>
<h3>866A</h3>
</div>
</div>
</div>

</div>

<div class="card shadow-lg">

<div class="card-header bg-dark text-white">

<h3 class="mb-0">
Portfolio Intelligence Dashboard
</h3>

</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>

<tr>
<th>Rank</th>
<th>Conference</th>
<th>Score</th>
<th>Health</th>
<th>KPI Gap</th>
<th>Risk</th>
<th>Executive Summary</th>
</tr>

</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td>
<b>#<?= (int)$r['portfolio_rank'] ?></b>
</td>

<td>
<?= htmlspecialchars(
$r['title_en']
?? $r['title_ar']
?? ('Conference '.$r['conference_id'])
) ?>
</td>

<td>
<?= $r['overall_score'] ?>
</td>

<td>
<?= $r['health_score'] ?>
</td>

<td>
<?= $r['optimization_gap'] ?>
</td>

<td>

<?php

$cls='secondary';

if(($r['risk_level'] ?? '')==='High'){
    $cls='danger';
}elseif(($r['risk_level'] ?? '')==='Medium'){
    $cls='warning';
}else{
    $cls='success';
}

?>

<span class="badge bg-<?= $cls ?>">
<?= htmlspecialchars($r['risk_level']) ?>
</span>

</td>

<td>
<?= htmlspecialchars($r['executive_summary']) ?>
</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}



/*
--------------------------------------------------
PACK863A
STRATEGIC OPTIMIZATION ENGINE
--------------------------------------------------
*/

public function strategicOptimization()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT
        sco.*,
        c.title_en
        FROM strategic_conference_optimization sco
        LEFT JOIN conferences c
        ON c.id=sco.conference_id
        ORDER BY sco.optimization_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-lg">

<div class="card-header bg-info text-white">
<h3 class="mb-0">
Strategic Conference Optimization
</h3>
</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Conference</th>
<th>Priority</th>
<th>Type</th>
<th>Recommendation</th>
<th>Score</th>
<th>Status</th>
<th>Execute</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= htmlspecialchars($r['title_en'] ?? '') ?></td>

<td><?= htmlspecialchars($r['priority_level']) ?></td>

<td><?= htmlspecialchars($r['optimization_type']) ?></td>

<td><?= htmlspecialchars($r['recommendation_text']) ?></td>

<td><?= $r['optimization_score'] ?></td>

<td><?= htmlspecialchars($r['status']) ?></td>

<td>

<?php if($r['status']=='pending'): ?>

<a class="btn btn-primary btn-sm"
href="/easychair/admin/strategic-optimization/execute?id=<?= (int)$r['id'] ?>">
Execute
</a>

<?php endif; ?>

</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}

public function executeStrategicOptimization()
{
    $this->requireAccess();

    $id=(int)($_GET['id'] ?? 0);

    if($id>0){

        $db=\App\Core\Database::getInstance();

        $db->prepare("
        UPDATE strategic_conference_optimization
        SET status='executed'
        WHERE id=?
        ")->execute([$id]);

    }

    header(
    'Location:/easychair/admin/strategic-optimization'
    );
    exit;
}



/*
--------------------------------------------------
PACK862A
SELF HEALING ENGINE
--------------------------------------------------
*/

public function selfHealingDashboard()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT
        sha.*,
        c.title_en
        FROM self_healing_actions sha
        LEFT JOIN conferences c
        ON c.id=sha.conference_id
        ORDER BY sha.id DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-lg">

<div class="card-header bg-warning">

<h3 class="mb-0">
Self Healing Review Pipeline
</h3>

</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Conference</th>
<th>Severity</th>
<th>Type</th>
<th>Action</th>
<th>Status</th>
<th>Execute</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= htmlspecialchars($r['title_en'] ?? '') ?></td>

<td><?= htmlspecialchars($r['severity']) ?></td>

<td><?= htmlspecialchars($r['healing_type']) ?></td>

<td><?= htmlspecialchars($r['action_text']) ?></td>

<td><?= htmlspecialchars($r['healing_status']) ?></td>

<td>

<?php if($r['healing_status']=='pending'): ?>

<a class="btn btn-success btn-sm"
href="/easychair/admin/self-healing/execute?id=<?= (int)$r['id'] ?>">
Execute
</a>

<?php endif; ?>

</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}

public function executeHealingAction()
{
    $this->requireAccess();

    $id=(int)($_GET['id'] ?? 0);

    if($id>0){

        $db=\App\Core\Database::getInstance();

        $db->prepare("
        UPDATE self_healing_actions
        SET healing_status='executed'
        WHERE id=?
        ")->execute([$id]);

    }

    header(
    'Location:/easychair/admin/self-healing'
    );
    exit;
}



/*
--------------------------------------------------
PACK861A
EXECUTION ENGINE
--------------------------------------------------
*/

public function executionEngine()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT ea.*, c.title_en
        FROM execution_actions ea
        LEFT JOIN conferences c
        ON c.id=ea.conference_id
        ORDER BY ea.id DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-lg">

<div class="card-header bg-dark text-white">
<h3 class="mb-0">
Execution Engine
</h3>
</div>

<div class="card-body">

<table class="table table-bordered">

<thead>
<tr>
<th>Conference</th>
<th>Action</th>
<th>Status</th>
<th>Execute</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= htmlspecialchars($r['title_en'] ?? '') ?></td>

<td><?= htmlspecialchars($r['action_type']) ?></td>

<td><?= htmlspecialchars($r['execution_status']) ?></td>

<td>

<?php if($r['execution_status']=='pending'): ?>

<a class="btn btn-success btn-sm"
href="/easychair/admin/execution-engine/run?id=<?= (int)$r['id'] ?>">
Execute
</a>

<?php endif; ?>

</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}

public function runExecutionAction()
{
    $this->requireAccess();

    $id=(int)($_GET['id'] ?? 0);

    if($id>0){

        $db=\App\Core\Database::getInstance();

        $db->prepare("
        UPDATE execution_actions
        SET
        execution_status='completed',
        executed_by=?,
        executed_at=NOW(),
        execution_result='Executed successfully'
        WHERE id=?
        ")->execute([
            $_SESSION['user_id'] ?? 0,
            $id
        ]);

        $db->prepare("
        INSERT INTO execution_logs
        (
            execution_action_id,
            log_type,
            log_message
        )
        VALUES
        (
            ?,
            'execution',
            'Action executed successfully'
        )
        ")->execute([
            $id
        ]);
    }

    header(
    'Location:/easychair/admin/execution-engine'
    );
    exit;
}



/*
--------------------------------------------------
PACK860A
ACTION APPROVAL ENGINE
--------------------------------------------------
*/

public function actionApprovalEngine()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT
        oaa.*,
        aro.action_text,
        aro.priority_level,
        c.title_en
        FROM orchestration_action_approvals oaa
        LEFT JOIN autonomous_review_orchestration aro
        ON aro.id=oaa.orchestration_id
        LEFT JOIN conferences c
        ON c.id=oaa.conference_id
        ORDER BY oaa.id DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-lg">

<div class="card-header bg-success text-white">
<h3 class="mb-0">
Autonomous Action Approval Engine
</h3>
</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Conference</th>
<th>Priority</th>
<th>Action</th>
<th>Status</th>
<th>Approve</th>
<th>Reject</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= htmlspecialchars($r['title_en'] ?? '') ?></td>

<td><?= htmlspecialchars($r['priority_level'] ?? '') ?></td>

<td><?= htmlspecialchars($r['action_text'] ?? '') ?></td>

<td><?= htmlspecialchars($r['approval_status']) ?></td>

<td>
<a class="btn btn-success btn-sm"
href="/easychair/admin/action-approval-engine/approve?id=<?= (int)$r['id'] ?>">
Approve
</a>
</td>

<td>
<a class="btn btn-danger btn-sm"
href="/easychair/admin/action-approval-engine/reject?id=<?= (int)$r['id'] ?>">
Reject
</a>
</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

    $content=ob_get_clean();

    require BASE_PATH.'/app/views/layouts/admin_layout.php';

    return;
}

public function approveOrchestrationAction()
{
    $this->requireAccess();

    $id=(int)($_GET['id'] ?? 0);

    if($id>0){

        $db=\App\Core\Database::getInstance();

        $db->prepare("
        UPDATE orchestration_action_approvals
        SET
        approval_status='approved',
        approved_by=?,
        approved_at=NOW()
        WHERE id=?
        ")->execute([
            $_SESSION['user_id'] ?? 0,
            $id
        ]);

    }

    header(
    'Location:/easychair/admin/action-approval-engine'
    );
    exit;
}

public function rejectOrchestrationAction()
{
    $this->requireAccess();

    $id=(int)($_GET['id'] ?? 0);

    if($id>0){

        $db=\App\Core\Database::getInstance();

        $db->prepare("
        UPDATE orchestration_action_approvals
        SET
        approval_status='rejected',
        approved_by=?,
        approved_at=NOW()
        WHERE id=?
        ")->execute([
            $_SESSION['user_id'] ?? 0,
            $id
        ]);

    }

    header(
    'Location:/easychair/admin/action-approval-engine'
    );
    exit;
}



/*
--------------------------------------------------
PACK859A
REVIEW ORCHESTRATION
--------------------------------------------------
*/

public function reviewOrchestration()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT
        aro.*,
        c.title_en
        FROM autonomous_review_orchestration aro
        LEFT JOIN conferences c
        ON c.id=aro.conference_id
        ORDER BY aro.confidence_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-lg">

<div class="card-header bg-primary text-white">

<h3 class="mb-0">
Autonomous Review Orchestration
</h3>

</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Conference</th>
<th>Priority</th>
<th>Action Type</th>
<th>Action</th>
<th>Confidence</th>
<th>Status</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= htmlspecialchars($r['title_en'] ?? '') ?></td>

<td><b><?= htmlspecialchars($r['priority_level']) ?></b></td>

<td><?= htmlspecialchars($r['action_type']) ?></td>

<td><?= htmlspecialchars($r['action_text']) ?></td>

<td><?= $r['confidence_score'] ?></td>

<td><?= htmlspecialchars($r['status']) ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}



/*
--------------------------------------------------
PACK858B
AI DECISION BOARD
--------------------------------------------------
*/

public function aiDecisionBoard()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT
        adb.*,
        c.title_en
        FROM ai_decision_board adb
        LEFT JOIN conferences c
        ON c.id=adb.conference_id
        ORDER BY adb.decision_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-lg">

<div class="card-header bg-danger text-white">

<h3 class="mb-0">
AI Decision Board
</h3>

</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>

<tr>
<th>Conference</th>
<th>Priority</th>
<th>Decision Type</th>
<th>Recommendation</th>
<th>Score</th>
</tr>

</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td>
<?= htmlspecialchars($r['title_en']) ?>
</td>

<td>
<b><?= htmlspecialchars($r['priority_level']) ?></b>
</td>

<td>
<?= htmlspecialchars($r['decision_type']) ?>
</td>

<td>
<?= htmlspecialchars($r['decision_text']) ?>
</td>

<td>
<?= $r['decision_score'] ?>
</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}



/*
--------------------------------------------------
PACK858A
PREDICTIVE INTELLIGENCE
--------------------------------------------------
*/

public function predictiveIntelligence()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT
        pci.*,
        c.title_en
        FROM predictive_conference_intelligence pci
        LEFT JOIN conferences c
        ON c.id=pci.conference_id
        ORDER BY pci.prediction_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-lg">

<div class="card-header bg-warning">

<h3 class="mb-0">
Predictive Conference Intelligence
</h3>

</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>

<tr>
<th>Conference</th>
<th>Prediction</th>
<th>Score</th>
<th>Forecast</th>
<th>Date</th>
</tr>

</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td>
<?= htmlspecialchars($r['title_en'] ?? '') ?>
</td>

<td>
<?= htmlspecialchars($r['prediction_type']) ?>
</td>

<td>
<?= $r['prediction_score'] ?>
</td>

<td>
<?= htmlspecialchars($r['prediction_text']) ?>
</td>

<td>
<?= htmlspecialchars($r['predicted_date']) ?>
</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}



/*
--------------------------------------------------
PACK857A
AI OPERATIONS CENTER
--------------------------------------------------
*/

public function aiOperationsCenter()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT
        aoc.*,
        c.title_en
        FROM ai_operations_center aoc
        LEFT JOIN conferences c
        ON c.id=aoc.conference_id
        ORDER BY aoc.overall_ai_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-lg border-0">

<div class="card-header bg-dark text-white">

<h3 class="mb-0">
🤖 AI Review Operations Center
</h3>

</div>

<div class="card-body">

<div class="row mb-4">

<?php if(!empty($rows)): ?>

<?php
$top=$rows[0];
?>

<div class="col-md-3">
<div class="card border-success">
<div class="card-body text-center">
<h6>Top Conference</h6>
<h4><?= htmlspecialchars($top['title_en']) ?></h4>
</div>
</div>
</div>

<div class="col-md-3">
<div class="card border-primary">
<div class="card-body text-center">
<h6>AI Score</h6>
<h2><?= $top['overall_ai_score'] ?></h2>
</div>
</div>
</div>

<div class="col-md-3">
<div class="card border-warning">
<div class="card-body text-center">
<h6>Reviewer Health</h6>
<h2><?= $top['reviewer_health_score'] ?></h2>
</div>
</div>
</div>

<div class="col-md-3">
<div class="card border-danger">
<div class="card-body text-center">
<h6>Track Health</h6>
<h2><?= $top['track_health_score'] ?></h2>
</div>
</div>
</div>

<?php endif; ?>

</div>

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Conference</th>
<th>Conference Health</th>
<th>Reviewer Health</th>
<th>Track Health</th>
<th>Risk</th>
<th>Assignment</th>
<th>AI Score</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= htmlspecialchars($r['title_en']) ?></td>

<td><?= $r['conference_health_score'] ?></td>

<td><?= $r['reviewer_health_score'] ?></td>

<td><?= $r['track_health_score'] ?></td>

<td><?= $r['risk_score'] ?></td>

<td><?= $r['assignment_score'] ?></td>

<td>
<b><?= $r['overall_ai_score'] ?></b>
</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}



/*
--------------------------------------------------
PACK856A
CONFERENCE HEALTH DASHBOARD
--------------------------------------------------
*/

public function conferenceHealth()
{
    $this->requireAccess();

    $db=
    \App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT
        chm.*,
        c.id AS conference_name
        FROM conference_health_metrics chm
        LEFT JOIN conferences c
        ON c.id=chm.conference_id
        ORDER BY chm.overall_health_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-sm">

<div class="card-header bg-success text-white">

<h4 class="mb-0">
Conference Health Dashboard
</h4>

</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>

<tr>
<th>Conference</th>
<th>Reviewer Health</th>
<th>Track Health</th>
<th>Workflow</th>
<th>Deadline</th>
<th>Overall</th>
</tr>

</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= htmlspecialchars($r['conference_name'] ?? '') ?></td>

<td><?= $r['reviewer_health_score'] ?></td>

<td><?= $r['track_health_score'] ?></td>

<td><?= $r['workflow_health_score'] ?></td>

<td><?= $r['deadline_health_score'] ?></td>

<td>
<b><?= $r['overall_health_score'] ?></b>
</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

    $content=
    ob_get_clean();

    require
    BASE_PATH.
    '/app/views/layouts/admin_layout.php';

    return;
}



/*
--------------------------------------------------
PACK855B
TRACK INTELLIGENCE
--------------------------------------------------
*/

public function trackIntelligence()
{
    $this->requireAccess();

    $conference=
    $this->conference();

    $db=
    \App\Core\Database::getInstance();

    $cid=
    (int)$conference['id'];

    $tracks=
    $db->query("
        SELECT
        thm.*,
        t.name_en
        FROM track_health_metrics thm
        LEFT JOIN tracks t
        ON t.id=thm.track_id
        WHERE thm.conference_id=".$cid."
        ORDER BY thm.health_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    $riskCount=
    (int)$db->query("
        SELECT COUNT(*)
        FROM track_risk_alerts
        WHERE conference_id=".$cid."
    ")->fetchColumn();

    $bottleneckCount=
    (int)$db->query("
        SELECT COUNT(*)
        FROM track_bottlenecks
        WHERE conference_id=".$cid."
    ")->fetchColumn();

    ob_start();
?>

<div class="container-fluid">

<div class="row mb-3">

<div class="col-md-6">
<div class="card border-danger">
<div class="card-body text-center">
<h5>Track Risks</h5>
<h2><?= $riskCount ?></h2>
</div>
</div>
</div>

<div class="col-md-6">
<div class="card border-warning">
<div class="card-body text-center">
<h5>Bottlenecks</h5>
<h2><?= $bottleneckCount ?></h2>
</div>
</div>
</div>

</div>

<div class="card">

<div class="card-header">
Track Intelligence
</div>

<div class="card-body">

<table class="table table-bordered">

<thead>
<tr>
<th>Track</th>
<th>Submissions</th>
<th>Reviews</th>
<th>Completion</th>
<th>Diversity</th>
<th>Health</th>
</tr>
</thead>

<tbody>

<?php foreach($tracks as $t): ?>

<tr>

<td><?= htmlspecialchars($t['name_en'] ?? '') ?></td>

<td><?= $t['submission_count'] ?></td>

<td><?= $t['review_count'] ?></td>

<td><?= $t['completion_rate'] ?></td>

<td><?= $t['diversity_score'] ?></td>

<td>
<b><?= $t['health_score'] ?></b>
</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

    $content=ob_get_clean();

    require BASE_PATH.'/app/views/layouts/admin_layout.php';

    return;
}



/*
--------------------------------------------------
PACK855A
REVIEWER NETWORK INTELLIGENCE
--------------------------------------------------
*/

public function reviewerNetworkIntelligence()
{
    $this->requireAccess();

    $conference=$this->conference();

    $db=\App\Core\Database::getInstance();

    $cid=(int)$conference['id'];

    $metrics=
    $db->query("
        SELECT
        rnm.*,
        u.email
        FROM reviewer_network_metrics rnm
        LEFT JOIN users u
        ON u.id=rnm.reviewer_id
        WHERE rnm.conference_id=".$cid."
        ORDER BY rnm.influence_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    $clusters=
    (int)$db->query("
        SELECT COUNT(*)
        FROM reviewer_cluster_analysis
        WHERE conference_id=".$cid."
    ")->fetchColumn();

    $alerts=
    (int)$db->query("
        SELECT COUNT(*)
        FROM reviewer_bias_alerts
        WHERE conference_id=".$cid."
    ")->fetchColumn();

    ob_start();
?>

<div class="container-fluid">

<div class="row mb-3">

<div class="col-md-6">
<div class="card border-primary">
<div class="card-body text-center">
<h5>Clusters</h5>
<h2><?= $clusters ?></h2>
</div>
</div>
</div>

<div class="col-md-6">
<div class="card border-danger">
<div class="card-body text-center">
<h5>Bias Alerts</h5>
<h2><?= $alerts ?></h2>
</div>
</div>
</div>

</div>

<div class="card">

<div class="card-header">
Reviewer Network Intelligence
</div>

<div class="card-body">

<table class="table table-bordered">

<thead>
<tr>
<th>Reviewer</th>
<th>Reviews</th>
<th>Completion</th>
<th>Influence</th>
<th>Diversity</th>
</tr>
</thead>

<tbody>

<?php foreach($metrics as $m): ?>

<tr>

<td><?= htmlspecialchars($m['email'] ?? '') ?></td>

<td><?= $m['review_count'] ?></td>

<td><?= $m['completion_rate'] ?></td>

<td><b><?= $m['influence_score'] ?></b></td>

<td><?= $m['diversity_score'] ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

    $content=ob_get_clean();

    require BASE_PATH.'/app/views/layouts/admin_layout.php';

    return;
}



/*
--------------------------------------------------
PACK854B
RECOMMENDATION EXPLANATIONS
--------------------------------------------------
*/

public function reviewerRecommendations()
{
    $this->requireAccess();

    $conference=
    $this->conference();

    $db=
    \App\Core\Database::getInstance();

    $cid=
    (int)$conference['id'];

    $rows=
    $db->query("
        SELECT
        rre.*,
        u.email
        FROM reviewer_recommendation_explanations rre
        LEFT JOIN users u
        ON u.id=rre.reviewer_id
        WHERE rre.conference_id=".$cid."
        ORDER BY rre.final_assignment_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-sm">

<div class="card-header bg-success text-white">

<h4 class="mb-0">
Reviewer Recommendation Explanations
</h4>

</div>

<div class="card-body">

<table class="table table-bordered">

<thead>

<tr>
<th>Reviewer</th>
<th>Assignment Score</th>
<th>Explanation</th>
</tr>

</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= htmlspecialchars($r['email']) ?></td>

<td>
<b><?= $r['final_assignment_score'] ?></b>
</td>

<td>
<?= htmlspecialchars($r['explanation_text']) ?>
</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

    $content=
    ob_get_clean();

    require
    BASE_PATH.
    '/app/views/layouts/admin_layout.php';

    return;
}



/*
--------------------------------------------------
PACK854A
ASSIGNMENT INTELLIGENCE
--------------------------------------------------
*/

public function reviewerAssignmentIntelligence()
{
    $this->requireAccess();

    $conference=
    $this->conference();

    $db=
    \App\Core\Database::getInstance();

    $cid=
    (int)$conference['id'];

    $rows=
    $db->query("
        SELECT
        ras.*,
        u.email
        FROM reviewer_assignment_scores ras
        LEFT JOIN users u
        ON u.id=ras.reviewer_id
        WHERE ras.conference_id=".$cid."
        ORDER BY ras.final_assignment_score DESC
        LIMIT 200
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-sm">

<div class="card-header bg-primary text-white">

<h4 class="mb-0">
Reviewer Assignment Intelligence
</h4>

</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>

<tr>
<th>Reviewer</th>
<th>Expertise</th>
<th>Performance</th>
<th>Capacity</th>
<th>Deadline</th>
<th>Final Score</th>
</tr>

</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= htmlspecialchars($r['email'] ?? '') ?></td>

<td><?= $r['expertise_score'] ?></td>

<td><?= $r['performance_score'] ?></td>

<td><?= $r['capacity_score'] ?></td>

<td><?= $r['deadline_score'] ?></td>

<td>
<b><?= $r['final_assignment_score'] ?></b>
</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

    $content=
    ob_get_clean();

    require
    BASE_PATH.
    '/app/views/layouts/admin_layout.php';

    return;
}



/*
--------------------------------------------------
PACK852B
REVIEW ESCALATIONS
--------------------------------------------------
*/

public function reviewEscalations()
{
    $this->requireAccess();

    $conference=
    $this->conference();

    $db=
    \App\Core\Database::getInstance();

    $cid=
    (int)$conference['id'];

    $rows=
    $db->query("
        SELECT
        re.*,
        u.email reviewer_email,
        ur.email replacement_email
        FROM review_escalations re

        LEFT JOIN users u
        ON u.id=re.reviewer_id

        LEFT JOIN users ur
        ON ur.id=re.replacement_reviewer_id

        WHERE re.conference_id=".$cid."

        ORDER BY re.id DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-sm">

<div class="card-header bg-danger text-white">

<h4 class="mb-0">
Review Escalations
</h4>

</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>

<tr>
<th>ID</th>
<th>Assignment</th>
<th>Reviewer</th>
<th>Replacement</th>
<th>Reason</th>
<th>Status</th>
</tr>

</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= (int)$r['id'] ?></td>

<td><?= (int)$r['assignment_id'] ?></td>

<td><?= htmlspecialchars($r['reviewer_email'] ?? '') ?></td>

<td><?= htmlspecialchars($r['replacement_email'] ?? '') ?></td>

<td><?= htmlspecialchars($r['escalation_reason'] ?? '') ?></td>

<td><?= htmlspecialchars($r['status'] ?? '') ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

    $content=
    ob_get_clean();

    require
    BASE_PATH.
    '/app/views/layouts/admin_layout.php';

    return;
}



/*
--------------------------------------------------
PACK852A
REVIEW DEADLINE INTELLIGENCE
--------------------------------------------------
*/

public function reviewDeadlineIntelligence()
{
    $this->requireAccess();

    $conference=
    $this->conference();

    $db=
    \App\Core\Database::getInstance();

    $cid=
    (int)$conference['id'];

    $safe=
    (int)$db->query("
        SELECT COUNT(*)
        FROM review_deadline_predictions
        WHERE conference_id=".$cid."
        AND prediction_status='safe'
    ")->fetchColumn();

    $risk=
    (int)$db->query("
        SELECT COUNT(*)
        FROM review_deadline_predictions
        WHERE conference_id=".$cid."
        AND prediction_status='at_risk'
    ")->fetchColumn();

    $critical=
    (int)$db->query("
        SELECT COUNT(*)
        FROM review_deadline_predictions
        WHERE conference_id=".$cid."
        AND prediction_status='critical'
    ")->fetchColumn();

    $rows=
    $db->query("
        SELECT *
        FROM review_deadline_predictions
        WHERE conference_id=".$cid."
        ORDER BY prediction_score DESC
        LIMIT 200
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>
<div class="container-fluid">

<div class="row mb-4">

<div class="col-md-4">
<div class="card border-success">
<div class="card-body text-center">
<h5>Safe</h5>
<h2><?= $safe ?></h2>
</div>
</div>
</div>

<div class="col-md-4">
<div class="card border-warning">
<div class="card-body text-center">
<h5>At Risk</h5>
<h2><?= $risk ?></h2>
</div>
</div>
</div>

<div class="col-md-4">
<div class="card border-danger">
<div class="card-body text-center">
<h5>Critical</h5>
<h2><?= $critical ?></h2>
</div>
</div>
</div>

</div>

<div class="card">

<div class="card-header">
Review Deadline Intelligence
</div>

<div class="card-body">

<table class="table table-bordered">

<thead>
<tr>
<th>Assignment</th>
<th>Reviewer</th>
<th>Status</th>
<th>Score</th>
<th>Days Left</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= (int)$r['assignment_id'] ?></td>

<td><?= (int)$r['reviewer_id'] ?></td>

<td><?= htmlspecialchars($r['prediction_status']) ?></td>

<td><?= htmlspecialchars($r['prediction_score']) ?></td>

<td><?= (int)$r['days_remaining'] ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>
<?php

    $content=ob_get_clean();

    require
    BASE_PATH.
    '/app/views/layouts/admin_layout.php';

    return;
}



/*
--------------------------------------------------
PACK851B
REVIEWER CONFLICTS DASHBOARD
--------------------------------------------------
*/

public function reviewerConflicts()
{
    $this->requireAccess();

    $conference=
    $this->conference();

    $db=
    \App\Core\Database::getInstance();

    $cid=
    (int)$conference['id'];

    $rows=
    $db->query("
        SELECT
        rc.*,
        u.email
        FROM reviewer_conflicts rc
        LEFT JOIN users u
        ON u.id=rc.reviewer_id
        WHERE
        (
            rc.conference_id=".$cid."
            OR rc.conference_id IS NULL
        )
        ORDER BY
        rc.id DESC
        LIMIT 500
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();

    ?>
    <div class="container-fluid">

    <div class="card shadow-sm">

    <div class="card-header bg-danger text-white">

    <h4 class="mb-0">
    Reviewer Conflict Log
    </h4>

    </div>

    <div class="card-body">

    <table class="table table-bordered table-striped">

    <thead>
    <tr>
    <th>ID</th>
    <th>Reviewer</th>
    <th>Submission</th>
    <th>Type</th>
    <th>Risk</th>
    <th>Reason</th>
    </tr>
    </thead>

    <tbody>

    <?php foreach($rows as $r): ?>

    <tr>

    <td><?= (int)$r['id'] ?></td>

    <td><?= htmlspecialchars($r['email'] ?? '') ?></td>

    <td><?= (int)($r['submission_id'] ?? 0) ?></td>

    <td><?= htmlspecialchars($r['conflict_type'] ?? '') ?></td>

    <td><?= htmlspecialchars($r['risk_score'] ?? '') ?></td>

    <td><?= htmlspecialchars($r['conflict_reason'] ?? '') ?></td>

    </tr>

    <?php endforeach; ?>

    </tbody>

    </table>

    </div>

    </div>

    </div>
    <?php

    $content=
    ob_get_clean();

    require
    BASE_PATH.
    '/app/views/layouts/admin_layout.php';

    return;
}



/*
--------------------------------------------------
PACK849B
REVIEWER CAPACITY DASHBOARD
--------------------------------------------------
*/

public function reviewerCapacity()
{
    $this->requireAccess();

    $conference=
    $this->conference();

    $db=
    \App\Core\Database::getInstance();

    $cid=
    (int)$conference['id'];

    $rows=
    $db->query("
        SELECT
        rcf.*,
        u.first_name,
        u.last_name,
        u.email
        FROM reviewer_capacity_forecasts rcf
        JOIN users u
        ON u.id=rcf.reviewer_id
        WHERE rcf.conference_id=".$cid."
        ORDER BY rcf.forecast_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    $healthy=0;
    $busy=0;
    $high=0;
    $overloaded=0;

    foreach($rows as $r){

        switch($r['forecast_status']){

            case 'healthy':
                $healthy++;
                break;

            case 'busy':
                $busy++;
                break;

            case 'high_load':
                $high++;
                break;

            case 'overloaded':
                $overloaded++;
                break;
        }
    }

    ob_start();

    require
    BASE_PATH.
    '/app/views/admin/reviewer_capacity/index.php';

    $content=
    ob_get_clean();

    require
    BASE_PATH.
    '/app/views/layouts/admin_layout.php';

    return;
}



/*
--------------------------------------------------
PACK842B
APPROVE SUGGESTION
--------------------------------------------------
*/

public function approveSuggestion()
{
    $this->requireAccess();

    $id=(int)($_GET['id'] ?? 0);

    if(!$id){
        header('Location:/easychair/admin/reviewer-assignments');
        exit;
    }

    $db=\App\Core\Database::getInstance();

    $stmt=$db->prepare("
        SELECT *
        FROM reviewer_reassignment_suggestions
        WHERE id=?
        LIMIT 1
    ");

    $stmt->execute([$id]);

    $sug=$stmt->fetch(\PDO::FETCH_ASSOC);

    if(!$sug){
        die('Suggestion not found');
    }

    $db->prepare("
        UPDATE reviewer_reassignment_suggestions
        SET status='approved'
        WHERE id=?
    ")->execute([$id]);

    $db->prepare("
        INSERT INTO review_assignment_events
        (
            assignment_id,
            event_type,
            created_by
        )
        VALUES
        (
            ?,
            'replacement_assigned',
            ?
        )
    ")->execute([
        $sug['assignment_id'],
        $_SESSION['user_id'] ?? null
    ]);

    $_SESSION['toast']=[
        'type'=>'success',
        'msg'=>'Suggestion approved'
    ];

    header(
    'Location:/easychair/admin/reviewer-assignments'
    );

    exit;
}

/*
--------------------------------------------------
PACK842B
REJECT SUGGESTION
--------------------------------------------------
*/

public function rejectSuggestion()
{
    $this->requireAccess();

    $id=(int)($_GET['id'] ?? 0);

    if($id){

        $db=\App\Core\Database::getInstance();

        $db->prepare("
            UPDATE reviewer_reassignment_suggestions
            SET status='rejected'
            WHERE id=?
        ")->execute([$id]);
    }

    header(
    'Location:/easychair/admin/reviewer-assignments'
    );

    exit;
}



public function saveReviewerAssignment()
{
    $this->requireAccess();

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {

header(
'Location: /easychair/admin/reviewer-assignments'
);

exit;

}

ob_start();

    $conference =
        $this->conference();

    
$db =
        $this->db();

$isTrackChair =
    (($_SESSION['conference_role'] ?? $_SESSION['role'] ?? '') === 'track_chair');

$trackIds =
    TrackChairScope::trackIds();


    $submissionId =
        (int)($_POST['submission_id'] ?? 0);

    $reviewerId =
        (int)($_POST['reviewer_id'] ?? 0);

    if (!$submissionId || !$reviewerId) {

        die("Invalid assignment.");

    }

    /*
    STEP 1 — Conflict check
    */

    $conflict =
        \App\Services\ReviewConflictService::check(

            $submissionId,

            $reviewerId

        );

    if ($conflict) {

        /*
        Log conflict
        */

        $db->prepare("
            INSERT INTO submission_status_history
            (
                submission_id,
                new_status,
                changed_by,
                created_at
            )
            VALUES
            (?, 'assignment_conflict_blocked', ?, NOW())
        ")
        ->execute([
            $submissionId,
            (int)$_SESSION['user_id']
        ]);

        error_log(
            "ASSIGNMENT BLOCKED: "
            . $conflict
        );

        die($conflict);

    }

    /*
    STEP 2 — Prevent duplicate assignment
    */

    $dup = $db->prepare("
    SELECT COUNT(*)
    FROM review_assignments
    WHERE submission_id = ?
      AND reviewer_id = ?
");

$dup->execute([
    $submissionId,
    $reviewerId
]);


if ((int)$dup->fetchColumn() > 0) {

    $_SESSION['warning'] = 'Reviewer already assigned.';


ob_end_clean();

header(
'Location: /easychair/admin/reviewer-assignments'
);

    exit;
}

    /*
    STEP 3 — Check workload limit
    */

    if (
        !\App\Services\ReviewerLoadService::canAssign(

            $reviewerId,

            (int)$conference['id']

        )
    ) {

        die(
            "Reviewer workload limit reached."
        );

    }

    /*
    STEP 4 — Insert assignment
    */

    $this->insertDynamic(

        'review_assignments',

        [

            'org_id' =>
                (int)$conference['org_id'],

            'conference_id' =>
                (int)$conference['id'],

            'submission_id' =>
                $submissionId,

            'reviewer_id' =>
                $reviewerId,

            'status' =>
                'assigned',

            'due_date' =>
(
trim(
(string)(
$_POST['due_date']
?? ''
)
)
!== ''

?

trim(
(string)(
$_POST['due_date']
?? ''
)
)

:

null
),

            'assigned_by' =>
                (int)$_SESSION['user_id'],

            'created_by' =>
                (int)$_SESSION['user_id'],

            'created_at' =>
                date('Y-m-d H:i:s')

        ]

    );

/*
STEP 5 — Queue reviewer email
*/

try {

$submission=
$db
->prepare("
SELECT *
FROM submissions
WHERE id=?
LIMIT 1
");

$submission->execute([
$submissionId
]);

$submission=
$submission->fetch(
\PDO::FETCH_ASSOC
);

$reviewer=
$db
->prepare("
SELECT *
FROM users
WHERE id=?
LIMIT 1
");

$reviewer->execute([
$reviewerId
]);

$reviewer=
$reviewer->fetch(
\PDO::FETCH_ASSOC
);

if(
$submission
&&
$reviewer
&&
!empty($reviewer['email'])
){

\App\Services\SubmissionWorkflowService::queueEmail(

(int)$conference['id'],

'reviewer_assigned',

$reviewer['email'],

trim(
($reviewer['first_name'] ?? '')
.' '.
($reviewer['last_name'] ?? '')
),

\App\Services\SubmissionWorkflowService::submissionVars(
$submission,
$conference,
$reviewer
),

$submissionId,

$reviewerId,

$reviewer['preferred_lang']
?? 'en'

);

error_log(
'EMAIL_QUEUED reviewer='
.
$reviewer['email']
);

}

}catch(
\Exception $e
){

error_log(
'EMAIL_ASSIGN_FAIL='
.
$e->getMessage()
);

}

    error_log(
        "REVIEWER ASSIGNED: submission="
        . $submissionId
        . " reviewer="
        . $reviewerId
    );

    header(
        "Location: /easychair/admin/reviewer-assignments"
    );

    exit;
}

    public function deleteReviewerAssignment()
    {
        $this->requireAccess();
        $conference = $this->conference();
        $this->deleteById('review_assignments', (int)($_GET['id'] ?? 0), $conference);
        header("Location: /easychair/admin/reviewer-assignments");
        exit;
    }

    public function submissionStageRules()
    {
        $this->requireAccess();
        $conference = $this->conference();

        $stmt = $this->db()->prepare("
            SELECT *
            FROM submission_stage_rules
            WHERE conference_id=? AND org_id=?
            ORDER BY sort_order, id
        ");
        $stmt->execute([(int)$conference['id'], (int)$conference['org_id']]);
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $this->view('submission_stage_rules', compact('conference','rows'));
    }

    public function saveSubmissionStageRule()
    {
        $this->requireAccess();
        $conference = $this->conference();

        $stmt = $this->db()->prepare("
            INSERT INTO submission_stage_rules
            (org_id, conference_id, stage_key, stage_title_en, stage_title_ar, sort_order, allow_author_upload, notify_author, require_review_complete, is_active, created_by)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ON DUPLICATE KEY UPDATE
                stage_title_en=VALUES(stage_title_en),
                stage_title_ar=VALUES(stage_title_ar),
                sort_order=VALUES(sort_order),
                allow_author_upload=VALUES(allow_author_upload),
                notify_author=VALUES(notify_author),
                require_review_complete=VALUES(require_review_complete),
                is_active=VALUES(is_active),
                updated_at=NOW()
        ");
        $stmt->execute([
            (int)$conference['org_id'],
            (int)$conference['id'],
            trim((string)($_POST['stage_key'] ?? '')),
            trim((string)($_POST['stage_title_en'] ?? '')),
            trim((string)($_POST['stage_title_ar'] ?? '')),
            (int)($_POST['sort_order'] ?? 0),
            !empty($_POST['allow_author_upload']) ? 1 : 0,
            !empty($_POST['notify_author']) ? 1 : 0,
            !empty($_POST['require_review_complete']) ? 1 : 0,
            !empty($_POST['is_active']) ? 1 : 0,
            (int)$_SESSION['user_id'],
        ]);

        header("Location: /easychair/admin/submission-stage-rules");
        exit;
    }

    public function deleteSubmissionStageRule()
    {
        $this->requireAccess();
        $conference = $this->conference();
        $this->deleteById('submission_stage_rules', (int)($_GET['id'] ?? 0), $conference);
        header("Location: /easychair/admin/submission-stage-rules");
        exit;
    }

    public function testEmail()
    {
        $this->requireAccess();
        if (function_exists('ec_require_action')) { ec_require_action('/easychair/admin/test-email', 'view'); }
        $conference = $this->conference();

       $stmt = $this->db()->prepare("

SELECT

l.*,

COALESCE(
o.status,
l.status
) final_status,

o.sent_at,

o.error_message

FROM conference_test_email_logs l

LEFT JOIN conference_mail_outbox o

ON
o.conference_id=l.conference_id

AND
o.recipient_email=l.recipient_email

AND
o.subject=l.subject

WHERE

l.conference_id=?

AND

l.org_id=?

ORDER BY l.id DESC

LIMIT 100

");
        $stmt->execute([(int)$conference['id'], (int)$conference['org_id']]);
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $this->view('test_email', compact('conference','rows'));
    }

    public function sendTestEmail()
    {
        $this->requireAccess();
        if (function_exists('ec_require_action')) { ec_require_action('/easychair/admin/test-email', 'create'); }
        $conference = $this->conference();

        $to = trim((string)($_POST['recipient_email'] ?? ''));
        $subject = trim((string)($_POST['subject'] ?? 'EasyChair test email'));
        $body = trim((string)($_POST['body'] ?? 'This is a test email.'));

        $status = 'queued';
        $error = null;

        try {
            $this->insertDynamic('conference_mail_outbox', [
                'org_id' => (int)$conference['org_id'],
                'conference_id' => (int)$conference['id'],
                'template_key' => 'manual_test',
                'event_key' => 'manual_test',
                'recipient_email' => $to,
                'subject' => $subject,
                'body' => $body,
                'status' => 'queued',
                'created_by' => (int)$_SESSION['user_id'],
                'created_at' => date('Y-m-d H:i:s'),
            ]);
        } catch (\Throwable $e) {
            $status = 'failed';
            $error = $e->getMessage();
        }

       /*
WRITE LOG
*/

$this->insertDynamic(

'conference_test_email_logs',

[

'org_id'=>
(int)$conference['org_id'],

'conference_id'=>
(int)$conference['id'],

'recipient_email'=>$to,

'subject'=>$subject,

'body'=>$body,

'status'=>'queued',

'created_by'=>
(int)$_SESSION['user_id'],

]

);

/*
AUTO SEND
*/

try{

if(

file_exists(
BASE_PATH.
'/tools/mail_queue_worker.php'
)

){

exec(

'cd '
.
escapeshellarg(BASE_PATH)
.
' && php tools/mail_queue_worker.php'

);

/*
SYNC UI LOG
*/

$this->db()
->prepare("

UPDATE
conference_test_email_logs

SET

status='sent'

WHERE

conference_id=?

AND

recipient_email=?

AND

subject=?

AND

status='queued'

")

->execute([

(int)$conference['id'],

$to,

$subject

]);

}

}
catch(
\Throwable $e
){

$this->db()
->prepare("

UPDATE
conference_test_email_logs

SET

status='failed',

error_message=?

WHERE

conference_id=?

AND

recipient_email=?

AND

subject=?

")

->execute([

$e->getMessage(),

(int)$conference['id'],

$to,

$subject

]);

}

header(
"Location: /easychair/admin/test-email"
);

exit;
    }

    public function conferenceRolePermissions()
    {
        $this->requireAccess();
        $conference = $this->conference();

        $roleCode = $this->role();

        if ($roleCode === 'superadmin') {
            $roles = $this->db()->query("SELECT id, code, name FROM roles WHERE code <> 'superadmin' ORDER BY code")->fetchAll(\PDO::FETCH_ASSOC);
            $menus = $this->db()->query("SELECT id, menu_key, label, label_ar, url, is_active FROM rbac_menu_items ORDER BY sort_order, id")->fetchAll(\PDO::FETCH_ASSOC);
        } else {
            $rolesStmt = $this->db()->prepare("
                SELECT id, code, name
                FROM roles
                WHERE code IN ('org_admin','admin','organizer','conference_chair','track_chair','section_editor','reviewer','author')
                ORDER BY code
            ");
            $rolesStmt->execute();
            $roles = $rolesStmt->fetchAll(\PDO::FETCH_ASSOC);

            $menusStmt = $this->db()->prepare("
                SELECT id, menu_key, label, label_ar, url, is_active
                FROM rbac_menu_items
                WHERE url <> '/easychair/admin/rbac-matrix'
                ORDER BY sort_order, id
            ");
            $menusStmt->execute();
            $menus = $menusStmt->fetchAll(\PDO::FETCH_ASSOC);
        }

        $stmt = $this->db()->prepare("
            SELECT *
            FROM rbac_role_menu_permissions
            WHERE conference_id=? AND org_id=?
        ");
        $stmt->execute([(int)$conference['id'], (int)$conference['org_id']]);
        $permissions = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $permissionMap = [];
        foreach ($permissions as $p) {
            $permissionMap[(int)$p['role_id']][(int)$p['menu_item_id']] = $p;
        }

        $this->view('conference_role_permissions', compact('conference','roles','menus','permissions','permissionMap'));
    }

    

    

    

    

    public function sidebarDiscovery()
    {
        $this->requireAccess();

        $db = $this->db();

        $sidebarFile =
            BASE_PATH .
            '/app/views/partials/unified_role_layout_links.php';

        $txt =
            file_get_contents(
                $sidebarFile
            );

        preg_match_all(
            "/'url'\s*=>\s*'([^']+)'/",
            $txt,
            $m
        );

        $sidebarUrls =
            array_unique(
                $m[1] ?? []
            );

        $rbacUrls =
            $db->query("
                SELECT url
                FROM rbac_menu_items
                WHERE url IS NOT NULL
                AND url<>''
            ")
            ->fetchAll(
                \PDO::FETCH_COLUMN
            );

        $rbacUrls =
            array_unique($rbacUrls);

        $missingInSidebar =
            array_values(
                array_diff(
                    $rbacUrls,
                    $sidebarUrls
                )
            );

        $missingInRbac =
            array_values(
                array_diff(
                    $sidebarUrls,
                    $rbacUrls
                )
            );

        ob_start();
?>

<div class="container-fluid">

<div class="card shadow-sm mb-3">
<div class="card-header">
<h3>Sidebar Discovery Report</h3>
</div>

<div class="card-body">

<div class="row">

<div class="col-md-3">
<div class="alert alert-primary">
Sidebar URLs:
<?= count($sidebarUrls) ?>
</div>
</div>

<div class="col-md-3">
<div class="alert alert-success">
RBAC URLs:
<?= count($rbacUrls) ?>
</div>
</div>

<div class="col-md-3">
<div class="alert alert-warning">
Missing In Sidebar:
<?= count($missingInSidebar) ?>
</div>
</div>

<div class="col-md-3">
<div class="alert alert-danger">
Missing In RBAC:
<?= count($missingInRbac) ?>
</div>
</div>

</div>

<h4>Missing In Sidebar</h4>

<table class="table table-bordered table-sm">
<thead>
<tr>
<th>URL</th>
</tr>
</thead>
<tbody>

<?php foreach(array_slice($missingInSidebar,0,200) as $u): ?>

<tr>
<td><?= htmlspecialchars($u) ?></td>
</tr>

<?php endforeach; ?>

</tbody>
</table>

</div>
</div>

</div>

<?php

        $content = ob_get_clean();

        require BASE_PATH .
        '/app/views/layouts/admin_layout.php';
    }



public function permissionSnapshots()
{
    $this->requireAccess();

    $rows =
        $this->db()
        ->query("
            SELECT *
            FROM permission_snapshots
            ORDER BY id DESC
        ")
        ->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>
<div class="container-fluid">

<div class="card shadow-sm">

<div class="card-header">
<h3>
Permission Snapshots
</h3>
</div>

<div class="card-body">

<table class="table table-bordered">

<thead>
<tr>
<th>ID</th>
<th>Conference</th>
<th>Name</th>
<th>Date</th>
<th>Action</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= (int)$r['id'] ?></td>

<td><?= (int)$r['conference_id'] ?></td>

<td><?= htmlspecialchars($r['snapshot_name']) ?></td>

<td><?= htmlspecialchars($r['created_at']) ?></td>

<td>

<a
class="btn btn-danger btn-sm"
href="/easychair/admin/permission-snapshot-restore?id=<?= (int)$r['id'] ?>"
onclick="return confirm('Restore Snapshot?');">

Restore

</a>

</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>
<?php

    $content = ob_get_clean();

    require BASE_PATH .
    '/app/views/layouts/admin_layout.php';
}

public function restorePermissionSnapshot()
{
    $this->requireAccess();

    $snapshotId =
        (int)($_GET['id'] ?? 0);

    if ($snapshotId <= 0) {
        die('Invalid Snapshot');
    }

    $db = $this->db();

    $rowsStmt =
        $db->prepare("
            SELECT *
            FROM permission_snapshot_rows
            WHERE snapshot_id=?
        ");

    $rowsStmt->execute([
        $snapshotId
    ]);

    $rows =
        $rowsStmt->fetchAll(
            \PDO::FETCH_ASSOC
        );

    $db->beginTransaction();

    try {

        foreach ($rows as $row) {

            $payload =
                json_decode(
                    $row['payload'],
                    true
                );

            if (
                $row['source_table']
                ===
                'rbac_role_menu_permissions'
            ) {

                unset($payload['id']);

                // build restore later
            }

            if (
                $row['source_table']
                ===
                'conference_business_permissions'
            ) {

                unset($payload['id']);

                // build restore later
            }
        }

        $db->commit();

    } catch (\Throwable $e) {

        $db->rollBack();

        die(
            $e->getMessage()
        );
    }

    header(
        'Location: /easychair/admin/permission-snapshots'
    );
    exit;
}

    public function permissionDiff()
    {
        $this->requireAccess();

        $db = $this->db();

        $source =
            (int)($_GET['source'] ?? 1);

        $target =
            (int)($_GET['target'] ?? 4);

        $sql = "
        SELECT
            role_id,
            menu_item_id,
            can_view,
            can_create,
            can_update,
            can_delete
        FROM rbac_role_menu_permissions
        WHERE conference_id=?
        ";

        $st1 = $db->prepare($sql);
        $st1->execute([$source]);

        $st2 = $db->prepare($sql);
        $st2->execute([$target]);

        $sourceRows = [];
        foreach($st1->fetchAll(\PDO::FETCH_ASSOC) as $r){
            $sourceRows[
                $r['role_id'] . ':' .
                $r['menu_item_id']
            ] = $r;
        }

        $targetRows = [];
        foreach($st2->fetchAll(\PDO::FETCH_ASSOC) as $r){
            $targetRows[
                $r['role_id'] . ':' .
                $r['menu_item_id']
            ] = $r;
        }

        $added = [];
        $removed = [];
        $changed = [];

        foreach($sourceRows as $k=>$v){

            if(!isset($targetRows[$k])){
                $removed[$k] = $v;
                continue;
            }

            if(
                json_encode($v)
                !==
                json_encode($targetRows[$k])
            ){
                $changed[$k] = [
                    'source'=>$v,
                    'target'=>$targetRows[$k]
                ];
            }
        }

        foreach($targetRows as $k=>$v){
            if(!isset($sourceRows[$k])){
                $added[$k] = $v;
            }
        }

        ob_start();
?>

<div class="container-fluid">

<div class="card shadow-sm mb-4">

<div class="card-header">
<h3>
Permission Diff Viewer
</h3>
</div>

<div class="card-body">

<form method="get">

<div class="row g-3">

<div class="col-md-4">
<label>Source Conference</label>
<input
type="number"
name="source"
class="form-control"
value="<?= $source ?>">
</div>

<div class="col-md-4">
<label>Target Conference</label>
<input
type="number"
name="target"
class="form-control"
value="<?= $target ?>">
</div>

<div class="col-md-4">
<label>&nbsp;</label>
<button class="btn btn-primary w-100">
Compare
</button>
</div>

</div>

</form>

<hr>

<div class="row">

<div class="col-md-4">
<div class="alert alert-success">
Added:
<?= count($added) ?>
</div>
</div>

<div class="col-md-4">
<div class="alert alert-danger">
Removed:
<?= count($removed) ?>
</div>
</div>

<div class="col-md-4">
<div class="alert alert-warning">
Changed:
<?= count($changed) ?>
</div>
</div>

</div>

</div>

</div>

</div>

<?php

$content = ob_get_clean();

require BASE_PATH .
'/app/views/layouts/admin_layout.php';
    }


public function rbacHealth()
    {
        $this->requireAccess();

        $db = $this->db();

        $routesFile =
            BASE_PATH . '/config/routes.php';

        $routesText =
            file_get_contents($routesFile);

        preg_match_all(
            "/'([^']+)'\s*=>/",
            $routesText,
            $m
        );

        $routes =
            array_unique($m[1] ?? []);

        $routeCount =
            count($routes);

        $rbacCount =
            (int)$db->query("
                SELECT COUNT(*)
                FROM rbac_menu_items
            ")->fetchColumn();

        $sidebarFile =
            BASE_PATH .
            '/app/views/partials/unified_role_layout_links.php';

        $sidebarText =
            file_get_contents($sidebarFile);

        preg_match_all(
            "/'url'\s*=>\s*'([^']+)'/",
            $sidebarText,
            $sMatches
        );

        $sidebarUrls =
            array_unique(
                $sMatches[1] ?? []
            );

        $sidebarCount =
            count($sidebarUrls);

        $duplicates =
            $db->query("
                SELECT url,
                       COUNT(*) c
                FROM rbac_menu_items
                GROUP BY url
                HAVING COUNT(*)>1
            ")
            ->fetchAll(\PDO::FETCH_ASSOC);

        $stats = [
            'routes' => $routeCount,
            'rbac' => $rbacCount,
            'sidebar' => $sidebarCount,
            'duplicates' => count($duplicates)
        ];

        ob_start();

        ?>
        <div class="container-fluid">

            <div class="card shadow-sm">

                <div class="card-header">
                    <h3>
                        RBAC Health Checker
                    </h3>
                </div>

                <div class="card-body">

                    <div class="row">

                        <div class="col-md-3">
                            <div class="alert alert-primary">
                                Routes:
                                <?= (int)$stats['routes'] ?>
                            </div>
                        </div>

                        <div class="col-md-3">
                            <div class="alert alert-success">
                                RBAC Menus:
                                <?= (int)$stats['rbac'] ?>
                            </div>
                        </div>

                        <div class="col-md-3">
                            <div class="alert alert-warning">
                                Sidebar:
                                <?= (int)$stats['sidebar'] ?>
                            </div>
                        </div>

                        <div class="col-md-3">
                            <div class="alert alert-danger">
                                Duplicates:
                                <?= (int)$stats['duplicates'] ?>
                            </div>
                        </div>

                    </div>

                    <table class="table table-bordered">

                        <thead>
                        <tr>
                            <th>Duplicate URL</th>
                            <th>Count</th>
                        </tr>
                        </thead>

                        <tbody>

                        <?php foreach($duplicates as $d): ?>

                        <tr>
                            <td><?= htmlspecialchars($d['url']) ?></td>
                            <td><?= (int)$d['c'] ?></td>
                        </tr>

                        <?php endforeach; ?>

                        </tbody>

                    </table>

                </div>

            </div>

        </div>
        <?php

        $content = ob_get_clean();

        require BASE_PATH .
        '/app/views/layouts/admin_layout.php';
    }


public function syncRbacMenus()
{
error_log("RBAC_SYNC_REACHED user=" . ($_SESSION["user_id"] ?? "NULL"));
 
        $this->requireAccess();

        $routesFile =
            BASE_PATH .
            '/config/routes.php';

        $txt =
            file_get_contents(
                $routesFile
            );

        preg_match_all(
            "/'([^']+)'\s*=>/",
            $txt,
            $matches
        );

        $routes =
            $matches[1] ?? [];

        $db =
            $this->db();

        $inserted = 0;

        foreach ($routes as $route) {

            if (
                strpos($route,'/admin/') !== 0
                &&
                strpos($route,'/reviewer/') !== 0
                &&
                strpos($route,'/author/') !== 0
            ) {
                continue;
            }

            $st =
                $db->prepare("
                    SELECT COUNT(*)
                    FROM rbac_menu_items
                    WHERE url=?
                ");

            $st->execute([
                '/easychair' . $route
            ]);

            if (
                (int)$st->fetchColumn() > 0
            ) {
                continue;
            }

            $menuKey =
                trim(
                    str_replace(
                        '/',
                        '.',
                        trim($route,'/')
                    )
                );

            $label =
                ucwords(
                    str_replace(
                        ['.','-'],
                        ' ',
                        basename($route)
                    )
                );

            $ins =
                $db->prepare("
                    INSERT INTO
                    rbac_menu_items
                    (
                        menu_key,
                        label,
                        url
                    )
                    VALUES
                    (
                        ?,
                        ?,
                        ?
                    )
                ");

            $ins->execute([
                $menuKey,
                $label,
                '/easychair' . $route
            ]);

            $inserted++;
        }

        echo
            '<h2>RBAC Sync Completed</h2>' .
            '<p>Inserted: ' .
            $inserted .
            '</p>';

 // require BASE_PATH .
   //     '/app/views/layouts/admin_layout.php';
         exit;
    }


public function cloneConferencePermissions()
    {
        $this->requireAccess();

        $sourceConference =
            (int)($_POST['source_conference_id'] ?? 0);

        $targetConference =
            (int)($_POST['target_conference_id'] ?? 0);

        if (
            $sourceConference <= 0 ||
            $targetConference <= 0 ||
            $sourceConference === $targetConference
        ) {
            header("Location: /easychair/admin/conference-role-permissions");
            exit;
        }

        $db = $this->db();

        try {

            $db->beginTransaction();

            $db->prepare("
                DELETE
                FROM rbac_role_menu_permissions
                WHERE conference_id=?
            ")
            ->execute([
                $targetConference
            ]);

            $db->prepare("
                INSERT INTO
                rbac_role_menu_permissions
                (
                    org_id,
                    conference_id,
                    role_id,
                    menu_item_id,
                    is_allowed,
                    can_view,
                    can_create,
                    can_update,
                    can_delete,
                    updated_by
                )
                SELECT
                    org_id,
                    ?,
                    role_id,
                    menu_item_id,
                    is_allowed,
                    can_view,
                    can_create,
                    can_update,
                    can_delete,
                    ?
                FROM rbac_role_menu_permissions
                WHERE conference_id=?
            ")
            ->execute([
                $targetConference,
                (int)($_SESSION['user_id'] ?? 0),
                $sourceConference
            ]);

            $db->prepare("
                DELETE
                FROM conference_business_permissions
                WHERE conference_id=?
            ")
            ->execute([
                $targetConference
            ]);

            $db->prepare("
                INSERT INTO
                conference_business_permissions
                (
                    org_id,
                    conference_id,
                    role_code,
                    business_key,
                    can_view,
                    can_create,
                    can_update,
                    can_delete,
                    created_by
                )
                SELECT
                    org_id,
                    ?,
                    role_code,
                    business_key,
                    can_view,
                    can_create,
                    can_update,
                    can_delete,
                    ?
                FROM conference_business_permissions
                WHERE conference_id=?
            ")
            ->execute([
                $targetConference,
                (int)($_SESSION['user_id'] ?? 0),
                $sourceConference
            ]);

            $db->commit();

        } catch (\Throwable $e) {

            $db->rollBack();

            die(
                'Clone Failed: '
                . $e->getMessage()
            );
        }

        header(
            "Location: /easychair/admin/conference-role-permissions"
        );
        exit;
    }




    public function createPermissionSnapshot()
    {
        $this->requireAccess();

        $conferenceId =
            (int)($_POST['conference_id'] ?? 0);

        if ($conferenceId <= 0) {
            die('Invalid conference');
        }

        $db = $this->db();

        $db->beginTransaction();

        try {

            $stmt = $db->prepare("
                INSERT INTO permission_snapshots
                (
                    org_id,
                    conference_id,
                    snapshot_name,
                    created_by
                )
                VALUES
                (
                    ?,
                    ?,
                    ?,
                    ?
                )
            ");

            $stmt->execute([
                (int)($_SESSION['org_id'] ?? 0),
                $conferenceId,
                'Snapshot ' . date('Y-m-d H:i:s'),
                (int)($_SESSION['user_id'] ?? 0)
            ]);

            $snapshotId =
                (int)$db->lastInsertId();

            foreach (
                ['rbac_role_menu_permissions',
                 'conference_business_permissions']
                as $table
            ) {

                $rows =
                    $db->query(
                        "SELECT * FROM {$table}
                         WHERE conference_id={$conferenceId}"
                    )
                    ->fetchAll(\PDO::FETCH_ASSOC);

                $ins =
                    $db->prepare("
                        INSERT INTO
                        permission_snapshot_rows
                        (
                            snapshot_id,
                            source_table,
                            payload
                        )
                        VALUES
                        (
                            ?,
                            ?,
                            ?
                        )
                    ");

                foreach ($rows as $row) {

                    $ins->execute([
                        $snapshotId,
                        $table,
                        json_encode($row)
                    ]);
                }
            }

            $db->commit();

        } catch (\Throwable $e) {

            $db->rollBack();

            die(
                'Snapshot Failed: '
                . $e->getMessage()
            );
        }

        header(
            "Location: /easychair/admin/conference-role-permissions"
        );
        exit;
    }


public function saveConferenceRolePermissions()
    {
        $this->requireAccess();
        $conference = $this->conference();

        $roleId = (int)($_POST['role_id'] ?? 0);
        
        // Mega519C: never edit superadmin from business permission editor.
        if (!empty($roleId)) {
            $checkRoleStmt = $this->db()->prepare("SELECT code FROM roles WHERE id=? LIMIT 1");
            $checkRoleStmt->execute([(int)$roleId]);
            if ((string)$checkRoleStmt->fetchColumn() === 'superadmin') {
                $_SESSION['flash_warning'] = 'Superadmin permissions are protected.';
                header("Location: /easychair/admin/conference-business-permissions");
                exit;
            }
        }

$items = $_POST['items'] ?? [];

        if ($roleId <= 0) {
            header("Location: /easychair/admin/conference-role-permissions");
            exit;
        }

        $roleStmt = $this->db()->prepare("SELECT code FROM roles WHERE id=? LIMIT 1");
        $roleStmt->execute([$roleId]);
        $targetRoleCode = (string)$roleStmt->fetchColumn();

        if (!ec_is_superadmin() && $targetRoleCode === 'superadmin') {
            http_response_code(403);
            exit('Only super admin can manage super admin permissions.');
        }

        $menuRows = $this->db()->query("SELECT id, url FROM rbac_menu_items")->fetchAll(\PDO::FETCH_ASSOC);

        $upsert = $this->db()->prepare("
            INSERT INTO rbac_role_menu_permissions
            (org_id, conference_id, role_id, menu_item_id, is_allowed, can_view, can_create, can_update, can_delete, updated_by)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ON DUPLICATE KEY UPDATE
                is_allowed=VALUES(is_allowed),
                can_view=VALUES(can_view),
                can_create=VALUES(can_create),
                can_update=VALUES(can_update),
                can_delete=VALUES(can_delete),
                updated_by=VALUES(updated_by),
                updated_at=NOW()
        ");

        foreach ($menuRows as $m) {
            $menuItemId = (int)$m['id'];
            $url = (string)($m['url'] ?? '');

            if ($url === '/easychair/admin/rbac-matrix' && $targetRoleCode !== 'superadmin') {
                $isAllowed = 0;
                $canView = 0;
                $canCreate = 0;
                $canUpdate = 0;
                $canDelete = 0;
            } else {
                $row = $items[$menuItemId] ?? [];
                $isAllowed = !empty($row['is_allowed']) ? 1 : 0;
                $canView = !empty($row['can_view']) ? 1 : 0;
                $canCreate = !empty($row['can_create']) ? 1 : 0;
                $canUpdate = !empty($row['can_update']) ? 1 : 0;
                $canDelete = !empty($row['can_delete']) ? 1 : 0;

                if (!$isAllowed) {
                    $canView = 0;
                    $canCreate = 0;
                    $canUpdate = 0;
                    $canDelete = 0;
                }
            }

            $upsert->execute([
                (int)$conference['org_id'],
                (int)$conference['id'],
                $roleId,
                $menuItemId,
                $isAllowed,
                $canView,
                $canCreate,
                $canUpdate,
                $canDelete,
                (int)$_SESSION['user_id'],
            ]);
        }

        header("Location: /easychair/admin/conference-role-permissions?role_id=" . $roleId);
        exit;
    }

    public function conferenceBusinessPermissions()
    {
        
        // Mega519A conferenceBusinessPermissions superadmin bypass
        if (session_status() !== PHP_SESSION_ACTIVE) { session_start(); }
        $role = (string)($_SESSION['conference_role'] ?? $_SESSION['role'] ?? $_SESSION['user_role'] ?? '');
        if ($role === 'superadmin') {
            // continue unrestricted
        } else {
            if (function_exists('ec_admin_require_url_action')) {
                ec_admin_require_url_action('/easychair/admin/conference-business-permissions', 'view');
            }
        }

$this->requireAccess();
        $conference = $this->conference();

        $stmt = $this->db()->prepare("
            SELECT *
            FROM conference_business_permissions
            WHERE conference_id=? AND org_id=?
            ORDER BY role_code, business_key
        ");
        $stmt->execute([(int)$conference['id'], (int)$conference['org_id']]);
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $this->view('conference_business_permissions', compact('conference','rows'));
    }

    public function saveConferenceBusinessPermission()
    {
        
        // Mega519A saveConferenceBusinessPermission superadmin bypass
        if (session_status() !== PHP_SESSION_ACTIVE) { session_start(); }
        $role = (string)($_SESSION['conference_role'] ?? $_SESSION['role'] ?? $_SESSION['user_role'] ?? '');
        if ($role === 'superadmin') {
            // continue unrestricted
        } else {
            if (function_exists('ec_admin_require_url_action')) {
                ec_admin_require_url_action('/easychair/admin/conference-business-permissions', 'view');
            }
        }

$this->requireAccess();
        $conference = $this->conference();

        $stmt = $this->db()->prepare("
            INSERT INTO conference_business_permissions
            (org_id, conference_id, role_code, business_key, can_view, can_create, can_update, can_delete, created_by)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
            ON DUPLICATE KEY UPDATE
                can_view=VALUES(can_view),
                can_create=VALUES(can_create),
                can_update=VALUES(can_update),
                can_delete=VALUES(can_delete),
                updated_at=NOW()
        ");
        $stmt->execute([
            (int)$conference['org_id'],
            (int)$conference['id'],
            trim((string)($_POST['role_code'] ?? '')),
            trim((string)($_POST['business_key'] ?? '')),
            !empty($_POST['can_view']) ? 1 : 0,
            !empty($_POST['can_create']) ? 1 : 0,
            !empty($_POST['can_update']) ? 1 : 0,
            !empty($_POST['can_delete']) ? 1 : 0,
            (int)$_SESSION['user_id'],
        ]);

        header("Location: /easychair/admin/conference-business-permissions");
        exit;
    }

    public function deleteConferenceBusinessPermission()
    {
        
        // Mega519A deleteConferenceBusinessPermission superadmin bypass
        if (session_status() !== PHP_SESSION_ACTIVE) { session_start(); }
        $role = (string)($_SESSION['conference_role'] ?? $_SESSION['role'] ?? $_SESSION['user_role'] ?? '');
        if ($role === 'superadmin') {
            // continue unrestricted
        } else {
            if (function_exists('ec_admin_require_url_action')) {
                ec_admin_require_url_action('/easychair/admin/conference-business-permissions', 'view');
            }
        }

$this->requireAccess();
        $conference = $this->conference();
        $this->deleteById('conference_business_permissions', (int)($_GET['id'] ?? 0), $conference);
        header("Location: /easychair/admin/conference-business-permissions");
        exit;
    }

    public function customRights()
    {
        $this->requireAccess();
        $conference = $this->conference();

        $stmt = $this->db()->prepare("
            SELECT *
            FROM conference_custom_rights
            WHERE conference_id=? AND org_id=?
            ORDER BY role_code, right_key
        ");
        $stmt->execute([(int)$conference['id'], (int)$conference['org_id']]);
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $this->view('custom_rights', compact('conference','rows'));
    }

    public function saveCustomRight()
    {
        $this->requireAccess();
        $conference = $this->conference();

        $stmt = $this->db()->prepare("
            INSERT INTO conference_custom_rights
            (org_id, conference_id, role_code, right_key, right_label_en, right_label_ar, is_allowed, notes, created_by)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
            ON DUPLICATE KEY UPDATE
                right_label_en=VALUES(right_label_en),
                right_label_ar=VALUES(right_label_ar),
                is_allowed=VALUES(is_allowed),
                notes=VALUES(notes),
                updated_at=NOW()
        ");
        $stmt->execute([
            (int)$conference['org_id'],
            (int)$conference['id'],
            trim((string)($_POST['role_code'] ?? '')),
            trim((string)($_POST['right_key'] ?? '')),
            trim((string)($_POST['right_label_en'] ?? '')),
            trim((string)($_POST['right_label_ar'] ?? '')),
            !empty($_POST['is_allowed']) ? 1 : 0,
            trim((string)($_POST['notes'] ?? '')),
            (int)$_SESSION['user_id'],
        ]);

        header("Location: /easychair/admin/custom-rights");
        exit;
    }

    public function deleteCustomRight()
    {
        $this->requireAccess();
        $conference = $this->conference();
        $this->deleteById('conference_custom_rights', (int)($_GET['id'] ?? 0), $conference);
        header("Location: /easychair/admin/custom-rights");
        exit;
    }

public function suggestReviewers()
{
    $this->requireAccess();

    $submissionId =
        (int)($_GET['submission_id'] ?? 0);

    if (!$submissionId) {

        die("Submission ID missing.");

    }

    $conference =
        $this->conference();

    $suggestions =
        \App\Services\ReviewerAutoAssignService::suggestReviewers(

            $submissionId,

            (int)$conference['id'],

            3

        );

    header(
        'Content-Type: application/json'
    );

    echo json_encode(

        $suggestions

    );

    exit;
}

public function cloneConferenceEmailTemplates()
{
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        die('Invalid request');
    }

    $db=$this->db();

    $source=(int)(
        $_POST['source_conference_id']
        ??0
    );

    $target=(int)(
        $_POST['target_conference_id']
        ??0
    );

    $overwrite=
    !empty(
        $_POST['overwrite']
    );

    $activate=
    !empty(
        $_POST['activate']
    );

    if(
        !$source
        ||
        !$target
    ){
        die('Conference required');
    }

    $src=
    $db
    ->prepare("

SELECT
org_id,
template_key,
event_key,
subject_en,
subject_ar,
body_en,
body_ar,
is_active

FROM conference_email_templates

WHERE conference_id=?

");

    $src
    ->execute([
        $source
    ]);

    $rows=
    $src
    ->fetchAll();

    foreach(
        $rows
        as $r
    ){

        if(
            $overwrite
        ){

            $db
            ->prepare("

DELETE

FROM conference_email_templates

WHERE

conference_id=?

AND

event_key=?

")

            ->execute([

                $target,

                $r['event_key']

            ]);

        }

        $db
        ->prepare("

INSERT IGNORE
INTO
conference_email_templates

(

org_id,
conference_id,
template_key,
event_key,
subject_en,
subject_ar,
body_en,
body_ar,
is_active,
created_by

)

VALUES

(

?,
?,
?,
?,
?,
?,
?,
?,
?,
?

)

")

        ->execute([

            $r['org_id'],

            $target,

            $r['template_key'],

            $r['event_key'],

            $r['subject_en'],

            $r['subject_ar'],

            $r['body_en'],

            $r['body_ar'],

            $activate
            ?1
            :$r['is_active'],

            $_SESSION['user_id']
            ??null

        ]);

    }

    $_SESSION[
    'flash_success'
    ]=
    'Templates cloned successfully';

    header(
        'Location:/easychair/admin/email-templates'
    );

    exit;
}




/*
--------------------------------------------------
PACK871A
CROSS CONFERENCE RESOURCE OPTIMIZER
--------------------------------------------------
*/

public function resourceOptimizer()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT *
        FROM cross_conference_resource_optimizer
        ORDER BY optimization_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-lg">

<div class="card-header bg-primary text-white">
<h3 class="mb-0">
Cross Conference Resource Optimizer
</h3>
</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Source Conference</th>
<th>Target Conference</th>
<th>Resource</th>
<th>Score</th>
<th>Status</th>
<th>Recommendation</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td>#<?= (int)$r['source_conference_id'] ?></td>

<td>#<?= (int)$r['target_conference_id'] ?></td>

<td><?= htmlspecialchars($r['resource_type']) ?></td>

<td><?= htmlspecialchars($r['optimization_score']) ?></td>

<td><?= htmlspecialchars($r['status']) ?></td>

<td><?= htmlspecialchars($r['recommendation_text']) ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

    $content=ob_get_clean();

    require BASE_PATH.'/app/views/layouts/admin_layout.php';

    return;
}





/*
--------------------------------------------------
PACK875A
REVIEWER CERTIFICATION & PROMOTIONS
--------------------------------------------------
*/

public function reviewerCertificationPromotions()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT *
        FROM reviewer_certification_promotions
        ORDER BY eligibility_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-lg">

<div class="card-header bg-success text-white">
<h3 class="mb-0">
Reviewer Certification & Promotions
</h3>
</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Reviewer</th>
<th>Conference</th>
<th>Certification</th>
<th>Promotion Path</th>
<th>Score</th>
<th>Status</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td>#<?= (int)$r['reviewer_id'] ?></td>

<td>#<?= (int)$r['conference_id'] ?></td>

<td><?= htmlspecialchars($r['certification_level']) ?></td>

<td><?= htmlspecialchars($r['promotion_path']) ?></td>

<td><?= htmlspecialchars($r['eligibility_score']) ?></td>

<td><?= htmlspecialchars($r['status']) ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

    $content=ob_get_clean();

    require BASE_PATH.'/app/views/layouts/admin_layout.php';

    return;
}





/*
--------------------------------------------------
PACK877A
REVIEWER REWARDS
--------------------------------------------------
*/

public function reviewerRewards()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=$db->query("
        SELECT *
        FROM reviewer_reward_intelligence
        ORDER BY award_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>
<div class="container-fluid">

<div class="card shadow-lg">

<div class="card-header bg-warning">
<h3 class="mb-0">
🏆 Reviewer Reward Intelligence
</h3>
</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Reviewer</th>
<th>Conference</th>
<th>Award</th>
<th>Score</th>
<th>Status</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td>#<?= (int)$r['reviewer_id'] ?></td>

<td>#<?= (int)$r['conference_id'] ?></td>

<td><?= htmlspecialchars($r['award_category']) ?></td>

<td><?= htmlspecialchars($r['award_score']) ?></td>

<td><?= htmlspecialchars($r['status']) ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>
<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}





public function reviewerAcademy()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=$db->query("
        SELECT *
        FROM reviewer_academy_programs
        ORDER BY academy_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>
<div class="container-fluid">
<div class="card">
<div class="card-header bg-primary text-white">
<h3>Reviewer Academy</h3>
</div>
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Reviewer</th>
<th>Conference</th>
<th>Program</th>
<th>Level</th>
<th>Score</th>
</tr>
</thead>
<tbody>
<?php foreach($rows as $r): ?>
<tr>
<td>#<?= (int)$r['reviewer_id'] ?></td>
<td>#<?= (int)$r['conference_id'] ?></td>
<td><?= htmlspecialchars($r['academy_program']) ?></td>
<td><?= htmlspecialchars($r['academy_level']) ?></td>
<td><?= htmlspecialchars($r['academy_score']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php

    $content=ob_get_clean();
    require BASE_PATH.'/app/views/layouts/admin_layout.php';
    return;
}



public function reviewerRetentionIntelligence()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=$db->query("
        SELECT *
        FROM reviewer_retention_intelligence
        ORDER BY retention_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>
<div class="container-fluid">
<div class="card">
<div class="card-header bg-danger text-white">
<h3>Reviewer Retention Intelligence</h3>
</div>
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Reviewer</th>
<th>Conference</th>
<th>Engagement</th>
<th>Retention</th>
<th>Burnout</th>
<th>Risk</th>
</tr>
</thead>
<tbody>
<?php foreach($rows as $r): ?>
<tr>
<td>#<?= (int)$r['reviewer_id'] ?></td>
<td>#<?= (int)$r['conference_id'] ?></td>
<td><?= htmlspecialchars($r['engagement_score']) ?></td>
<td><?= htmlspecialchars($r['retention_score']) ?></td>
<td><?= htmlspecialchars($r['burnout_risk']) ?></td>
<td><?= htmlspecialchars($r['retention_risk']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<?php

    $content=ob_get_clean();
    require BASE_PATH.'/app/views/layouts/admin_layout.php';
    return;
}





public function reviewerMarketplace()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT *
        FROM reviewer_marketplace
        ORDER BY marketplace_rank
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>
<div class="container-fluid">

<div class="card shadow">

<div class="card-header bg-info text-white">
<h3>Global Reviewer Marketplace</h3>
</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Rank</th>
<th>Reviewer</th>
<th>Conference</th>
<th>Score</th>
<th>Level</th>
<th>Status</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= (int)$r['marketplace_rank'] ?></td>

<td>#<?= (int)$r['reviewer_id'] ?></td>

<td>#<?= (int)$r['home_conference_id'] ?></td>

<td><?= htmlspecialchars($r['marketplace_score']) ?></td>

<td><?= htmlspecialchars($r['marketplace_level']) ?></td>

<td><?= htmlspecialchars($r['availability_status']) ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>
<?php

    $content=ob_get_clean();

    require BASE_PATH.'/app/views/layouts/admin_layout.php';

    return;
}





public function reviewerExchange()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT *
        FROM reviewer_exchange_recommendations
        ORDER BY exchange_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>
<div class="container-fluid">

<div class="card shadow">

<div class="card-header bg-success text-white">
<h3>Cross-Conference Reviewer Exchange</h3>
</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Reviewer</th>
<th>Source</th>
<th>Target</th>
<th>Score</th>
<th>Exchange Type</th>
<th>Status</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td>#<?= (int)$r['reviewer_id'] ?></td>

<td>#<?= (int)$r['source_conference_id'] ?></td>

<td>#<?= (int)$r['target_conference_id'] ?></td>

<td><?= htmlspecialchars($r['exchange_score']) ?></td>

<td><?= htmlspecialchars($r['exchange_type']) ?></td>

<td><?= htmlspecialchars($r['status']) ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>
<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}





public function reviewerLifetimeAchievement()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT *
        FROM reviewer_lifetime_achievement
        ORDER BY hall_of_fame_rank
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>
<div class="container-fluid">

<div class="card shadow">

<div class="card-header bg-dark text-white">
<h3>Reviewer Lifetime Achievement</h3>
</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Rank</th>
<th>Reviewer</th>
<th>Impact Score</th>
<th>Achievement Level</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= (int)$r['hall_of_fame_rank'] ?></td>

<td>#<?= (int)$r['reviewer_id'] ?></td>

<td><?= htmlspecialchars($r['lifetime_impact_score']) ?></td>

<td><?= htmlspecialchars($r['achievement_level']) ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>
<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}





public function reviewerEcosystem()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT *
        FROM reviewer_ecosystem_actions
        ORDER BY confidence_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>
<div class="container-fluid">

<div class="card shadow">

<div class="card-header bg-primary text-white">
<h3>Autonomous Reviewer Ecosystem</h3>
</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Reviewer</th>
<th>Conference</th>
<th>Action</th>
<th>Priority</th>
<th>Confidence</th>
<th>Status</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td>#<?= (int)$r['reviewer_id'] ?></td>

<td>#<?= (int)$r['conference_id'] ?></td>

<td><?= htmlspecialchars($r['action_type']) ?></td>

<td><?= htmlspecialchars($r['priority_level']) ?></td>

<td><?= htmlspecialchars($r['confidence_score']) ?></td>

<td><?= htmlspecialchars($r['action_status']) ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>
<?php

    $content=ob_get_clean();

    require BASE_PATH.'/app/views/layouts/admin_layout.php';

    return;
}





public function reviewerReputationNetwork()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT *
        FROM reviewer_reputation_network
        ORDER BY global_rank
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>
<div class="container-fluid">

<div class="card shadow">

<div class="card-header bg-success text-white">
<h3>Reviewer Reputation Network</h3>
</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Rank</th>
<th>Reviewer</th>
<th>Conference</th>
<th>Reputation Score</th>
<th>Trust Index</th>
<th>Tier</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= (int)$r['global_rank'] ?></td>

<td>#<?= (int)$r['reviewer_id'] ?></td>

<td>#<?= (int)$r['conference_id'] ?></td>

<td><?= htmlspecialchars($r['reputation_score']) ?></td>

<td><?= htmlspecialchars($r['trust_index']) ?></td>

<td><?= htmlspecialchars($r['reputation_tier']) ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>
<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}





public function reviewerLeadershipSuccession()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT *
        FROM reviewer_leadership_succession_ai
        ORDER BY readiness_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>
<div class="container-fluid">

<div class="card shadow">

<div class="card-header bg-primary text-white">
<h3>Autonomous Leadership Succession AI</h3>
</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Reviewer</th>
<th>Conference</th>
<th>Succession Role</th>
<th>Readiness</th>
<th>Confidence</th>
<th>Tier</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td>#<?= (int)$r['reviewer_id'] ?></td>

<td>#<?= (int)$r['conference_id'] ?></td>

<td><?= htmlspecialchars($r['succession_role']) ?></td>

<td><?= htmlspecialchars($r['readiness_score']) ?></td>

<td><?= htmlspecialchars($r['succession_confidence']) ?></td>

<td><?= htmlspecialchars($r['leadership_tier']) ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>
<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}





public function globalExpertDiscovery()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT *
        FROM reviewer_global_experts
        ORDER BY expert_rank
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>
<div class="container-fluid">

<div class="card shadow">

<div class="card-header bg-warning">
<h3>Global Expert Discovery Engine</h3>
</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Rank</th>
<th>Reviewer</th>
<th>Conference</th>
<th>Expert Score</th>
<th>Expert Level</th>
<th>Confidence</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= (int)$r['expert_rank'] ?></td>

<td>#<?= (int)$r['reviewer_id'] ?></td>

<td>#<?= (int)$r['conference_id'] ?></td>

<td><?= htmlspecialchars($r['expert_score']) ?></td>

<td><?= htmlspecialchars($r['expert_level']) ?></td>

<td><?= htmlspecialchars($r['discovery_confidence']) ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>
<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}





public function reviewerDigitalTwins()
{
    $this->requireAccess();

    $db=\App\Core\Database::getInstance();

    $rows=
    $db->query("
        SELECT *
        FROM reviewer_digital_twins
        ORDER BY digital_twin_score DESC
    ")->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>
<div class="container-fluid">

<div class="card shadow">

<div class="card-header bg-info text-white">
<h3>Reviewer Digital Twin Intelligence</h3>
</div>

<div class="card-body">

<table class="table table-bordered table-striped">

<thead>
<tr>
<th>Reviewer</th>
<th>Conference</th>
<th>Twin Score</th>
<th>Growth</th>
<th>Leadership</th>
<th>Promotion</th>
<th>Future Role</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td>#<?= (int)$r['reviewer_id'] ?></td>
<td>#<?= (int)$r['conference_id'] ?></td>
<td><?= htmlspecialchars($r['digital_twin_score']) ?></td>
<td><?= htmlspecialchars($r['growth_potential']) ?></td>
<td><?= htmlspecialchars($r['leadership_probability']) ?></td>
<td><?= htmlspecialchars($r['promotion_probability']) ?></td>
<td><?= htmlspecialchars($r['future_role']) ?></td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>
<?php

$content=ob_get_clean();

require BASE_PATH.'/app/views/layouts/admin_layout.php';

return;
}

public function permissionTemplates()
{
    $this->requireAccess();

    $rows =
        $this->db()
        ->query("
            SELECT *
            FROM permission_templates
            ORDER BY id DESC
        ")
        ->fetchAll(\PDO::FETCH_ASSOC);

    ob_start();
?>

<div class="container-fluid">

<div class="card shadow-sm">

<div class="card-header">
<h3>
Permission Templates
</h3>
</div>

<div class="card-body">

<div class="alert alert-info mb-3">
Permission Template creation is reserved for the next complete template-engine pack.
</div>

<table class="table table-bordered">

<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Role</th>
<th>Action</th>
</tr>
</thead>

<tbody>

<?php foreach($rows as $r): ?>

<tr>

<td><?= (int)$r['id'] ?></td>

<td><?= htmlspecialchars($r['template_name']) ?></td>

<td><?= htmlspecialchars($r['role_code']) ?></td>

<td>

<a
class="btn btn-primary btn-sm"
href="/easychair/admin/permission-template-apply?id=<?= (int)$r['id'] ?>">

Apply

</a>

</td>

</tr>

<?php endforeach; ?>

</tbody>

</table>

</div>

</div>

</div>

<?php

$content = ob_get_clean();

require BASE_PATH .
'/app/views/layouts/admin_layout.php';
}




public function addFavorite()
{
    if(session_status()!==PHP_SESSION_ACTIVE){
        session_start();
    }

    $userId=(int)($_SESSION['user_id']??0);

    if($userId<=0){
        die('Login required');
    }

    $url=trim((string)($_GET['url']??''));
    $label=trim((string)($_GET['label']??''));

    if($url===''){
        die('Missing URL');
    }

    $st=$this->db()->prepare("
        INSERT IGNORE INTO user_sidebar_favorites
        (
            user_id,
            url,
            label
        )
        VALUES
        (
            ?,
            ?,
            ?
        )
    ");

    $st->execute([
        $userId,
        $url,
        $label
    ]);

    header(
        'Location: ' .
        ($_SERVER['HTTP_REFERER']
        ??
        '/easychair')
    );

    exit;
}

public function removeFavorite()
{
    if(session_status()!==PHP_SESSION_ACTIVE){
        session_start();
    }

    $userId=(int)($_SESSION['user_id']??0);

    $url=trim((string)($_GET['url']??''));

    $st=$this->db()->prepare("
        DELETE
        FROM user_sidebar_favorites
        WHERE user_id=?
        AND url=?
    ");

    $st->execute([
        $userId,
        $url
    ]);

    header(
        'Location: ' .
        ($_SERVER['HTTP_REFERER']
        ??
        '/easychair')
    );

    exit;
}

public function updateCommitteeOrder()
{
    $this->requireAccess();

    $conference = $this->conference();

    $stmt = $this->db()->prepare("
        UPDATE conference_committee_people
        SET sort_order=?
        WHERE id=?
          AND conference_id=?
          AND org_id=?
    ");

    $stmt->execute([
        (int)($_POST['sort_order'] ?? 0),
        (int)($_POST['id'] ?? 0),
        (int)$conference['id'],
        (int)$conference['org_id']
    ]);

    header(
        'Location: /easychair/admin/committee-images'
    );

    exit;
}

}
