<?php
declare(strict_types=1);

namespace App\Controllers;

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

use App\Core\Controller;
use App\Core\Database;

final class AdminAutoAssignController extends Controller
{
    public function run(): void
    {
        require_permission('admin.access');
        if (!$this->isPost()) {
            redirect('admin/review-assignments/bulk');
        }
        csrf_check();

        $db = Database::getInstance();

        $conferenceId = (int)($_POST['conference_id'] ?? 0);
        $roundNo      = (int)($_POST['round_no'] ?? 1);
        $perPaper     = max(1, (int)($_POST['per_paper'] ?? 2));

        if ($conferenceId <= 0) {
            flash('danger', trans('required_fields'));
            redirect('admin/review-assignments/bulk');
        }

        // Submissions
        $st = $db->prepare("SELECT id FROM submissions WHERE conference_id=:cid ORDER BY id DESC LIMIT 200");
        $st->execute([':cid' => $conferenceId]);
        $subIds = array_map('intval', $st->fetchAll(\PDO::FETCH_COLUMN));

        // Reviewers (default reviewer role_id=4)
        $reviewers = $db->query("
            SELECT u.id, COALESCE(rp.admin_rating,0) AS rating
            FROM users u
            LEFT JOIN reviewer_profiles rp ON rp.user_id=u.id
            WHERE u.role_id=4 AND u.is_active=1
            ORDER BY rating DESC, u.id DESC
            LIMIT 500
        ")->fetchAll();

        // Current load map in this conference+round
        $st = $db->prepare("
            SELECT ra.reviewer_id, COUNT(*) AS cnt
            FROM review_assignments ra
            INNER JOIN submissions s ON s.id=ra.submission_id
            WHERE s.conference_id=:cid AND ra.round_no=:rn
            GROUP BY ra.reviewer_id
        ");
        $st->execute([':cid' => $conferenceId, ':rn' => $roundNo]);
        $loadMap = [];
        foreach ($st->fetchAll() as $r) {
            $loadMap[(int)$r['reviewer_id']] = (int)$r['cnt'];
        }

        // Insert assignment (ignore duplicates)
        $ins = $db->prepare("
            INSERT IGNORE INTO review_assignments (submission_id, reviewer_id, assigned_by, round_no, due_date, status)
            VALUES (:sid,:rid,:by,:rn,NULL,'assigned')
        ");

        $assigned = 0;

        foreach ($subIds as $sid) {
            // already assigned reviewers for this submission+round
            $st = $db->prepare("SELECT reviewer_id FROM review_assignments WHERE submission_id=:sid AND round_no=:rn");
            $st->execute([':sid' => $sid, ':rn' => $roundNo]);
            $already = array_map('intval', $st->fetchAll(\PDO::FETCH_COLUMN));
            $picked = 0;

            // pick reviewers one by one: lowest load, then highest rating
            $used = $already;

            while ($picked < $perPaper) {
                $bestId = 0;
                $bestLoad = 999999;
                $bestRating = -1;

                foreach ($reviewers as $rv) {
                    $rid = (int)$rv['id'];
                    if (in_array($rid, $used, true)) {
                        continue;
                    }
                    $load = $loadMap[$rid] ?? 0;
                    $rating = (int)($rv['rating'] ?? 0);

                    if ($load < $bestLoad || ($load === $bestLoad && $rating > $bestRating)) {
                        $bestId = $rid;
                        $bestLoad = $load;
                        $bestRating = $rating;
                    }
                }

                if ($bestId <= 0) {
                    // no more reviewers available
                    break;
                }

                $ins->execute([
                    ':sid' => $sid,
                    ':rid' => $bestId,
                    ':by'  => (int)auth_id(),
                    ':rn'  => $roundNo,
                ]);

                $loadMap[$bestId] = ($loadMap[$bestId] ?? 0) + 1;
                $used[] = $bestId;
                $assigned++;
                $picked++;
            }
        }

        flash('success', "Auto-assigned: {$assigned}");
        redirect('admin/review-assignments?conference_id=' . $conferenceId . '&round_no=' . $roundNo);
    }
}
