<?php
namespace App\Controllers;

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

class AdminDecisionController extends Controller
{
    private function requireContext(): void
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }

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

        $role = $_SESSION['role'] ?? $_SESSION['user_role'] ?? '';

        if (!in_array($role, ['super_admin', 'conference_chair', 'track_chair', 'org_admin', 'admin'], true)) {
            http_response_code(403);
            exit("Access denied.");
        }

        if ($role !== 'super_admin') {
            if (empty($_SESSION['org_id']) || empty($_SESSION['conference_id'])) {
                header("Location: /easychair/select-conference");
                exit;
            }
        }
    }

    private function filters(array &$params): string
    {
        $role = $_SESSION['role'] ?? $_SESSION['user_role'] ?? '';

        $where = " WHERE 1=1 ";

        if ($role !== 'super_admin') {
            $where .= " AND s.org_id = ? AND s.conference_id = ? ";
            $params[] = (int)$_SESSION['org_id'];
            $params[] = (int)$_SESSION['conference_id'];
        } elseif (!empty($_SESSION['conference_id'])) {
            $where .= " AND s.conference_id = ? ";
            $params[] = (int)$_SESSION['conference_id'];
        }

        return $where;
    }

    public function index()
    {
        $this->requireContext();

        $db = Database::getInstance();

        $params = [];
        $where = $this->filters($params);

        $stmt = $db->prepare("
            SELECT
                s.id,
                COALESCE(s.title, s.title_en, s.title_ar, CONCAT('Submission #', s.id)) AS title,
                COALESCE(s.stage, s.status, 'submitted') AS stage,
                s.status,
                s.decision,
                s.recommended_decision,
                s.avg_score AS submission_avg_score,
                COUNT(DISTINCT r.id) AS reviews_count,
                ROUND(AVG(COALESCE(r.overall_score, r.score)), 2) AS review_avg_score
            FROM submissions s
            LEFT JOIN reviews r ON r.submission_id = s.id
            {$where}
            GROUP BY
                s.id,
                s.title,
                s.title_en,
                s.title_ar,
                s.stage,
                s.status,
                s.decision,
                s.recommended_decision,
                s.avg_score
            ORDER BY s.id DESC
        ");

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

        foreach ($rows as &$row) {
            $row['avg_score'] = $row['submission_avg_score'] ?? $row['review_avg_score'] ?? null;
        }
        unset($row);

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

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

    public function make()
    {
        $this->requireContext();

        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            header("Location: /easychair/admin/decisions");
            exit;
        }

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

        $allowed = ['accepted', 'revision_required', 'rejected'];

        if ($submissionId <= 0 || !in_array($decision, $allowed, true)) {
            http_response_code(400);
            exit("Invalid decision.");
        }

        $db = Database::getInstance();

        $status = $decision;
        $stage = 'decision';

        if ($decision === 'revision_required') {
            $stage = 'revision_required';
        }

        $params = [
            $decision,
            $status,
            $stage,
            $submissionId,
        ];

        $where = " id = ? ";

        $role = $_SESSION['role'] ?? $_SESSION['user_role'] ?? '';

        if ($role !== 'super_admin') {
            $where .= " AND org_id = ? AND conference_id = ? ";
            $params[] = (int)$_SESSION['org_id'];
            $params[] = (int)$_SESSION['conference_id'];
        }

        $stmt = $db->prepare("
            UPDATE submissions
            SET decision = ?,
                status = ?,
                stage = ?,
                updated_at = NOW()
            WHERE {$where}
        ");

        $stmt->execute($params);

        
        try {
            $stmt = $db->prepare("
                SELECT s.*, c.short_name, c.title_ar, c.title_en, u.email, u.first_name, u.last_name, u.preferred_lang
                FROM submissions s
                LEFT JOIN conferences c ON c.id = s.conference_id
                LEFT JOIN users u ON u.id = s.author_id
                WHERE s.id = ?
                LIMIT 1
            ");
            $stmt->execute([$submissionId]);
            $sub = $stmt->fetch(\PDO::FETCH_ASSOC);

            if ($sub) {
                SubmissionWorkflowService::log(
                    $submissionId,
                    'decision_made',
                    'Decision made',
                    'Decision: ' . $decision,
                    (int)$_SESSION['user_id'],
                    $_SESSION['role'] ?? null
                );

                if (!empty($sub['email'])) {
                    SubmissionWorkflowService::queueEmail(
                        (int)$sub['conference_id'],
                        $decision === 'revision_required' ? 'revision_required' : 'decision_notification',
                        $sub['email'],
                        trim(($sub['first_name'] ?? '') . ' ' . ($sub['last_name'] ?? '')),
                        SubmissionWorkflowService::submissionVars($sub, $sub, $sub),
                        $submissionId,
                        (int)$sub['author_id'],
                        $sub['preferred_lang'] ?? 'en'
                    );
                }
            }
        } catch (\Throwable $e) {
            // keep decision workflow working even if logging/mail queue fails
        }

        header("Location: /easychair/admin/decisions?msg=updated");
        exit;
    }

    public function setDecision()
    {
        return $this->make();
    }
}
