<?php
namespace App\Controllers;

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

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

use App\Core\Database;
use App\Core\RoleMatrix;
use App\Services\SubmissionWorkflowService;

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

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

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

        if (!RoleMatrix::can('manage_reviewers') && !RoleMatrix::can('manage_reviews')) {
            http_response_code(403);
            exit("Access denied.");
        }

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

    private function conference(): array
    {
        $db = Database::getInstance();

        $stmt = $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("Invalid conference access.");
        }

        return $c;
    }

    public function index()
    {

        // Pack512: non-superadmin bypasses selector safely.
        if (function_exists('ec_scope_role') && ec_scope_role() !== 'superadmin') {
            if (function_exists('ec_scope_auto_select_conference')) {
                // ec_scope_auto_select_conference(true);
            }
            $landing = function_exists('ec_scope_landing_url') ? ec_scope_landing_url() : '/easychair/admin/dashboard';
            header("Location: " . $landing);
            exit;
        }

$this->requireAccess();

        $db = Database::getInstance();
        $conference = $this->conference();

        $stmt = $db->prepare("
            SELECT
                s.id,
                s.submission_no,
                COALESCE(s.title, s.title_en, s.title_ar, CONCAT('Submission #', s.id)) AS title,
                s.status,
                s.stage,
                s.current_round_no,
                COUNT(DISTINCT ra.id) AS assignments_count,
                COUNT(DISTINCT CASE WHEN ra.status='completed' THEN ra.id END) AS completed_count
            FROM submissions s
            LEFT JOIN review_assignments ra ON ra.submission_id = s.id
            WHERE s.conference_id = ?
              AND s.org_id = ?
            GROUP BY s.id
            ORDER BY s.id DESC
        ");
        $stmt->execute([(int)$conference['id'], (int)$conference['org_id']]);
        $submissions = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $stmt = $db->prepare("
            SELECT
                u.id,
                u.first_name,
                u.last_name,
                u.email,
                u.expertise,
                u.reviewer_score,
                COUNT(ra.id) AS load_count
            FROM user_conferences uc
            JOIN roles r ON r.id = uc.role_id
            JOIN users u ON u.id = uc.user_id
            LEFT JOIN review_assignments ra ON ra.reviewer_id = u.id AND ra.conference_id = uc.conference_id
            WHERE uc.conference_id = ?
              AND r.code = 'reviewer'
              AND u.is_active = 1
            GROUP BY u.id
            ORDER BY load_count ASC, u.reviewer_score DESC, u.last_name ASC
        ");
        $stmt->execute([(int)$conference['id']]);
        $reviewers = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $stmt = $db->prepare("
            SELECT
                ra.*,
                COALESCE(s.title, s.title_en, s.title_ar, CONCAT('Submission #', s.id)) AS submission_title,
                CONCAT(COALESCE(u.first_name,''),' ',COALESCE(u.last_name,'')) AS reviewer_name,
                u.email AS reviewer_email
            FROM review_assignments ra
            JOIN submissions s ON s.id = ra.submission_id
            JOIN users u ON u.id = ra.reviewer_id
            WHERE ra.conference_id = ?
              AND ra.org_id = ?
            ORDER BY ra.id DESC
            LIMIT 100
        ");
        $stmt->execute([(int)$conference['id'], (int)$conference['org_id']]);
        $assignments = $stmt->fetchAll(\PDO::FETCH_ASSOC);

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

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

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

        $db = Database::getInstance();
        $conference = $this->conference();

        $submissionId = (int)($_POST['submission_id'] ?? 0);
        $reviewerId = (int)($_POST['reviewer_id'] ?? 0);
        $dueDate = trim($_POST['due_date'] ?? '');
        $roundNo = (int)($_POST['round_no'] ?? 1);

        if (!$submissionId || !$reviewerId) {
            exit("Missing submission or reviewer.");
        }

        $stmt = $db->prepare("
            SELECT *
            FROM submissions
            WHERE id = ?
              AND conference_id = ?
              AND org_id = ?
            LIMIT 1
        ");
        $stmt->execute([$submissionId, (int)$conference['id'], (int)$conference['org_id']]);
        $submission = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$submission) {
            exit("Submission not found.");
        }

        $stmt = $db->prepare("
            SELECT u.*
            FROM users u
            JOIN user_conferences uc ON uc.user_id = u.id
            JOIN roles r ON r.id = uc.role_id
            WHERE u.id = ?
              AND uc.conference_id = ?
              AND r.code = 'reviewer'
            LIMIT 1
        ");
        $stmt->execute([$reviewerId, (int)$conference['id']]);
        $reviewer = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$reviewer) {
            exit("Reviewer not valid for this conference.");
        }

        $stmt = $db->prepare("
            SELECT id
            FROM review_assignments
            WHERE submission_id = ?
              AND reviewer_id = ?
              AND conference_id = ?
            LIMIT 1
        ");
        $stmt->execute([$submissionId, $reviewerId, (int)$conference['id']]);

        if ($stmt->fetchColumn()) {
            header("Location: /easychair/admin/assignments?msg=exists");
            exit;
        }

        $stmt = $db->prepare("
            INSERT INTO review_assignments
            (submission_id, conference_id, reviewer_id, assigned_by, due_date, status, assigned_at, round_no, org_id)
            VALUES (?, ?, ?, ?, ?, 'assigned', NOW(), ?, ?)
        ");

        $stmt->execute([
            $submissionId,
            (int)$conference['id'],
            $reviewerId,
            (int)$_SESSION['user_id'],
            $dueDate ?: null,
            $roundNo,
            (int)$conference['org_id']
        ]);

        $db->prepare("
            UPDATE submissions
            SET status = 'under_review',
                stage = 'review',
                updated_at = NOW()
            WHERE id = ?
        ")->execute([$submissionId]);

        SubmissionWorkflowService::log(
            $submissionId,
            'reviewer_assigned',
            'Reviewer assigned',
            'Reviewer ' . ($reviewer['email'] ?? '') . ' assigned.',
            (int)$_SESSION['user_id'],
            $_SESSION['role'] ?? null
        );

        SubmissionWorkflowService::queueEmail(
            (int)$conference['id'],
            'reviewer_assigned',
            $reviewer['email'],
            trim(($reviewer['first_name'] ?? '') . ' ' . ($reviewer['last_name'] ?? '')),
            SubmissionWorkflowService::submissionVars($submission, $conference, $reviewer),
            $submissionId,
            (int)$reviewer['id'],
            $reviewer['preferred_lang'] ?? 'en'
        );

        header("Location: /easychair/admin/assignments?msg=assigned");
        exit;
    }
}
