<?php

namespace App\Controllers;

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

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

class AuthorSubmissionController extends Controller
{
    private function db()
    {
        return Database::getInstance();
    }

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

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

    private function requireSubmissionOwner(array $submission): void
    {
        if ((int)($submission['author_id'] ?? 0) !== (int)($_SESSION['user_id'] ?? 0)) {
            die("Access denied.");
        }
    }

    private function resolveConferenceId(): int
{
    $db = $this->db();

    /*
    ---------------------------------------------------------
    Resolve incoming id OR slug
    ---------------------------------------------------------
    */

    $idOrSlug = trim((string)(
        $_GET['id']
        ?? $_POST['conference_id']
        ?? $_SESSION['submit_conference_id']
        ?? $_SESSION['conference_short_name']
        ?? $_SESSION['conference_id']
        ?? ''
    ));

    $conferenceId = 0;

    /*
    ---------------------------------------------------------
    Numeric conference ID
    ---------------------------------------------------------
    */

    if (
        $idOrSlug !== ''
        &&
        ctype_digit($idOrSlug)
    ) {

        $conferenceId = (int)$idOrSlug;

    }

    /*
    ---------------------------------------------------------
    Conference slug
    ---------------------------------------------------------
    */

    elseif ($idOrSlug !== '') {

        $stmt = $db->prepare("
            SELECT id
            FROM conferences
            WHERE
                slug = ?
                OR short_name = ?
            LIMIT 1
        ");

        $stmt->execute([
            $idOrSlug,
            $idOrSlug
        ]);

        $conferenceId =
            (int)$stmt->fetchColumn();
    }

    /*
    ---------------------------------------------------------
    Fallback from user organization
    ---------------------------------------------------------
    */

    if (
        !$conferenceId
        &&
        !empty($_SESSION['user_id'])
    ) {

        $stmt = $db->prepare("
            SELECT c.id
            FROM conferences c
            JOIN users u
                ON u.org_id = c.org_id
            WHERE u.id = ?
            ORDER BY c.id DESC
            LIMIT 1
        ");

        $stmt->execute([
            (int)$_SESSION['user_id']
        ]);

        $conferenceId =
            (int)$stmt->fetchColumn();
    }

    /*
    ---------------------------------------------------------
    Final fallback
    ---------------------------------------------------------
    */

    if (!$conferenceId) {

        $stmt = $db->query("
            SELECT id
            FROM conferences
            WHERE is_active = 1
            ORDER BY id DESC
            LIMIT 1
        ");

        $conferenceId =
            (int)$stmt->fetchColumn();
    }

    /*
    ---------------------------------------------------------
    Persist session safely
    ---------------------------------------------------------
    */

    if ($conferenceId > 0) {

        $_SESSION['conference_id'] =
            $conferenceId;

    }

    return $conferenceId;
}

    private function columns(string $table): array
    {
        static $cache = [];

        if (isset($cache[$table])) {
            return $cache[$table];
        }

        try {
            $stmt = $this->db()->query("DESCRIBE `$table`");
            $cache[$table] = array_column($stmt->fetchAll(PDO::FETCH_ASSOC), 'Field');
        } catch (\Throwable $e) {
            $cache[$table] = [];
        }

        return $cache[$table];
    }

    private function hasColumn(string $table, string $column): bool
    {
        return in_array($column, $this->columns($table), true);
    }

    private function insertDynamic(string $table, array $data): void
    {
        $cols = $this->columns($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));
    }


public function index()
{
    return $this->create();
}



    public function create()
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }

        if (empty($_SESSION['user_id'])) {
            if (!empty($_GET['id'])) {

    $_SESSION['submit_conference_id'] =
        trim((string)$_GET['id']);

}

            header("Location: /easychair/register");
            exit;
        }

        $conferenceId = $this->resolveConferenceId();

        if (!$conferenceId) {
            die("Conference ID missing.");
        }

        $stmt = $this->db()->prepare("
            SELECT id, name_ar, name_en
            FROM tracks
            WHERE conference_id = ?
            AND is_active = 1
            ORDER BY id
        ");
        $stmt->execute([$conferenceId]);
        $tracks = $stmt->fetchAll(PDO::FETCH_ASSOC);

        error_log("SUBMIT CREATE: conf={$conferenceId} tracks=" . count($tracks));

        $this->render('author/submissions/submit', [
            'tracks' => $tracks,
            'conference_id' => $conferenceId
        ]);
    }

    public function store()
{
    $this->requireLogin();

    $db = $this->db();
    $conferenceId = $this->resolveConferenceId();

    if (!$conferenceId) {
        die("Conference ID missing.");
    }

    /*
    Resolve organization
    */

    $confStmt = $db->prepare("
        SELECT *
        FROM conferences
        WHERE id = ?
        LIMIT 1
    ");
    $confStmt->execute([$conferenceId]);

    $conference =
        $confStmt->fetch(PDO::FETCH_ASSOC)
        ?: [];

    $orgId =
        (int)(
            $conference['org_id']
            ?? $_SESSION['org_id']
            ?? 0
        );

    $_SESSION['org_id'] =
        $orgId;

    /*
    Track
    */

    $trackId =
        !empty($_POST['track_id'])
        ? (int)$_POST['track_id']
        : null;

    /*
    Titles
    */

    $titleEn =
        trim(
            $_POST['title']
            ?? $_POST['title_en']
            ?? ''
        );

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

    /*
    Abstract
    */

    $abstractEn =
        trim(
            $_POST['abstract']
            ?? $_POST['abstract_en']
            ?? ''
        );

    $abstractAr =
        trim(
            $_POST['abstract_ar']
            ?? ''
        );

    /*
    KEYWORDS — FIXED
    Always populate all keyword fields
    */

    /*
KEYWORDS — robust normalization
*/

/*
KEYWORDS — bulletproof normalization
*/

/*
FINAL — correct multilingual keyword handling
*/

$keywordsEn = '';
$keywordsAr = '';

/* English keywords */

if (isset($_POST['keywords_en'])) {

    $keywordsEn =
        trim($_POST['keywords_en']);

}

/* Arabic keywords */

if (isset($_POST['keywords_ar'])) {

    $keywordsAr =
        trim($_POST['keywords_ar']);

}

/*
Safety — enforce string
*/

if (!is_string($keywordsEn)) {
    $keywordsEn = '';
}

if (!is_string($keywordsAr)) {
    $keywordsAr = '';
}

/*
System rule:
keywords column stores English index
*/

$keywords =
    $keywordsEn;

    /*
    Normalize
    */

    $title =
        $titleEn
        ?: $titleAr
        ?: 'Submission '
           . date('YmdHis');

    $abstract =
        $abstractEn
        ?: $abstractAr;

    /*
    Submission number
    */

    $submissionNo =
        'SUB-'
        . date('Y')
        . '-'
        . uniqid();

    /*
    INSERT submission
    */

    $stmt =
        $db->prepare("
            INSERT INTO submissions
            (
                org_id,
                conference_id,
                track_id,
                author_id,
                submission_no,

                title,
                title_en,
                title_ar,

                abstract,
                abstract_en,
                abstract_ar,

                keywords,
                keywords_en,
                keywords_ar,

                status,
                stage,
                submitted_at
            )
            VALUES
            (
                ?, ?, ?, ?, ?,
                ?, ?, ?,
                ?, ?, ?,
                ?, ?, ?,
                'submitted',
                'submission',
                NOW()
            )
        ");

    $stmt->execute([

        $orgId,
        $conferenceId,
        $trackId,
        (int)$_SESSION['user_id'],
        $submissionNo,

        $title,
        $titleEn,
        $titleAr,

        $abstract,
        $abstractEn,
        $abstractAr,

        $keywords,
        $keywordsEn,
        $keywordsAr

    ]);

    $submissionId =
        (int)$db->lastInsertId();

    /*
    ------------------------------------------------
    SAVE AUTHORS
    ------------------------------------------------
    */

    try{

    $stmtAuthor=
    $db->prepare("

        INSERT INTO submission_authors
        (
            submission_id,
            full_name,
            email,
            affiliation,
            country,
            is_corresponding,
            author_order
        )
        VALUES
        (
            ?,?,?,?,?,?,?
        )

    ");

    $stmtAuthor->execute([

        $submissionId,

        trim(
            ($_SESSION['full_name']??'Author')
        ),

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

        '',

        '',

        1,

        1

    ]);

    $names=
        $_POST['coauthor_name']
        ??[];

    $emails=
        $_POST['coauthor_email']
        ??[];

    $aff=
        $_POST['coauthor_affiliation']
        ??[];

    $country=
        $_POST['coauthor_country']
        ??[];

    $corr=
        (int)(
            $_POST[
                'corresponding_author'
            ]
            ?? 0
        );

    foreach(
        $names
        as $i=>$n
    ){

        if(
            trim($n)===''
        ){
            continue;
        }

        $stmtAuthor->execute([

            $submissionId,

            trim($n),

            trim(
                $emails[$i]
                ?? ''
            ),

            trim(
                $aff[$i]
                ?? ''
            ),

            trim(
                $country[$i]
                ?? ''
            ),

            $corr===($i+1)
            ?1
            :0,

            $i+2

        ]);

    }

    }catch(Throwable $e){

        error_log(
            'AUTHOR SAVE: '
            .$e->getMessage()
        );

    }

    /*
    FILE UPLOAD
    */

    $file =
        $_FILES['file']
        ?? $_FILES['paper']
        ?? null;

    if (
        $file
        && is_uploaded_file(
            $file['tmp_name']
        )
    ) {

        $uploadDir =
            BASE_PATH
            . '/public/uploads/submissions/';

        if (!is_dir($uploadDir)) {

            mkdir(
                $uploadDir,
                0775,
                true
            );
        }

        @chmod(
            $uploadDir,
            0775
        );

        $originalName =
            $file['name'];

        $ext =
            strtolower(
                pathinfo(
                    $originalName,
                    PATHINFO_EXTENSION
                )
            );

        $ext =
            $ext ?: 'dat';

        $filename =
            'submission_'
            . $submissionId
            . '_'
            . time()
            . '.'
            . $ext;

        /*
        CRITICAL FIX — leading slash
        */

        $relativePath =
            '/uploads/submissions/'
            . $filename;

        $absolutePath =
            $uploadDir
            . $filename;

        if (
            move_uploaded_file(
                $file['tmp_name'],
                $absolutePath
            )
        ) {

            /*
            Update main submission
            */

            $db->prepare("
                UPDATE submissions
                SET
                    file_path = ?,
                    original_filename = ?,
                    current_version = 1
                WHERE id = ?
            ")
            ->execute([

                $relativePath,
                $originalName,
                $submissionId

            ]);

            /*
            Version record
            */

            $this->insertDynamic(
                'submission_versions',
                [

                    'submission_id' =>
                        $submissionId,

                    'version_no' =>
                        1,

                    'file_path' =>
                        $relativePath,

                    'original_filename' =>
                        $originalName,

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

                    'upload_type' =>
                        'manuscript',

                    'notes' =>
                        'Initial submission',

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

                ]
            );

            /*
            Files record
            */

            $this->insertDynamic(
                'submission_files',
                [

                    'submission_id' =>
                        $submissionId,

                    'file_category' =>
                        'full_article',

                    'original_name' =>
                        $originalName,

                    'original_filename' =>
                        $originalName,

                    'file_path' =>
                        $relativePath,

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

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

                ]
            );

            error_log(
                "FILE UPLOADED: submission="
                . $submissionId
                . " path="
                . $relativePath
            );

        }
        else {

            error_log(
                "FILE UPLOAD FAILED: submission="
                . $submissionId
            );

        }

    }

    error_log(
        "SUBMISSION CREATED: id="
        . $submissionId
        . " title="
        . $title
        . " keywords="
        . $keywords
    );

    header(
        "Location: /easychair/author/submission?id="
        . $submissionId
    );

    exit;
}

    

public function show()
{
    $this->requireLogin();

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

    if (!$id) {
        die("Submission ID missing.");
    }

    $stmt = $this->db()->prepare("
        SELECT s.*,
               t.name_en AS track_name_en,
               t.name_ar AS track_name_ar
        FROM submissions s
        LEFT JOIN tracks t ON t.id = s.track_id
        WHERE s.id = ?
        LIMIT 1
    ");

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

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

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

    $this->requireSubmissionOwner($submission);

    /*
    ============================================================
    AUTHORS
    ============================================================
    */

    $authors = [];

    $stmtAuthors = $this->db()->prepare("
        SELECT
            id,
            submission_id,
            full_name,
            email,
            affiliation,
            country,
            is_corresponding,
            author_order
        FROM submission_authors
        WHERE submission_id = ?
        ORDER BY author_order ASC
    ");

    $stmtAuthors->execute([
        (int)$submission['id']
    ]);

    $authors =
        $stmtAuthors->fetchAll(PDO::FETCH_ASSOC);

    /*
    ============================================================
    FILES / VERSIONS
    ============================================================
    */

    $files = [];

    if ($this->columns('submission_versions')) {

        $stmt = $this->db()->prepare("
            SELECT *
            FROM submission_versions
            WHERE submission_id = ?
            ORDER BY version_no DESC, id DESC
        ");

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

        $files =
            $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    if (
        !$files &&
        $this->columns('submission_files')
    ) {

        $stmt = $this->db()->prepare("
            SELECT *
            FROM submission_files
            WHERE submission_id = ?
            ORDER BY id DESC
        ");

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

        $files =
            $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    /*
    ============================================================
    REVIEWS + SCORES
    ============================================================
    */

    $reviews = [];

    try {

        $stmtReviews = $this->db()->prepare("
    SELECT
        r.*,

        ra.round_no,
        ra.status AS assignment_status,

        CONCAT(
            COALESCE(u.first_name,''),
            ' ',
            COALESCE(u.last_name,'')
        ) AS reviewer_name

    FROM reviews r

    LEFT JOIN review_assignments ra
        ON ra.id = r.review_assignment_id

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

    WHERE r.submission_id = ?

    ORDER BY r.id DESC
");
        $stmtReviews->execute([$id]);

        $reviews =
            $stmtReviews->fetchAll(PDO::FETCH_ASSOC);

/*
------------------------------------------------
LOAD VERSION HISTORY
------------------------------------------------
*/

$stmtVersions = $this->db()->prepare("
    SELECT
        sv.*,

        CONCAT(
            COALESCE(u.first_name,''),
            ' ',
            COALESCE(u.last_name,'')
        ) AS uploader_name

    FROM submission_versions sv

    LEFT JOIN users u
        ON u.id = sv.uploaded_by

    WHERE sv.submission_id = ?

    ORDER BY
        sv.round_no ASC,
        sv.version_no ASC,
        sv.id ASC
");

$stmtVersions->execute([
    (int)$submission['id']
]);

$versions =
    $stmtVersions->fetchAll(
        \PDO::FETCH_ASSOC
    );

        foreach ($reviews as &$review) {

            $stmtScores =
                $this->db()->prepare("
                    SELECT
                        rcs.score,
                        rc.title_en,
                        rc.title_ar,
                        rc.weight,
                        rc.max_score

                    FROM review_criterion_scores rcs

                    INNER JOIN review_criteria rc
                        ON rc.id = rcs.criterion_id

                    WHERE rcs.review_id = ?

                    ORDER BY rc.sort_order ASC,
                             rc.id ASC
                ");

            $stmtScores->execute([
                (int)$review['id']
            ]);

            $review['criteria_scores'] =
                $stmtScores->fetchAll(
                    PDO::FETCH_ASSOC
                );
        }

        unset($review);

    } catch (\Throwable $e) {

        error_log(
            'AUTHOR REVIEW LOAD ERROR: '
            . $e->getMessage()
        );
    }

    /*
    ============================================================
    WORKFLOW TIMELINE
    ============================================================
    */

    $workflowTimeline = [

        [
            'key' => 'submitted',
            'label' => 'Submitted'
        ],

        [
            'key' => 'under_review',
            'label' => 'Under Review'
        ],

        [
            'key' => 'revision_required',
            'label' => 'Revision Required'
        ],

        [
            'key' => 'accepted',
            'label' => 'Accepted'
        ],

        [
            'key' => 'camera_ready',
            'label' => 'Camera Ready'
        ],

        [
            'key' => 'published',
            'label' => 'Published'
        ]

    ];

    /*
    ============================================================
    RENDER
    ============================================================
    */

    ob_start();

require BASE_PATH .
    '/app/views/author/submissions/show.php';

$content =
    ob_get_clean();

require BASE_PATH .
    '/app/views/layouts/author_layout.php';
}
    public function edit()
    {
        $this->requireLogin();

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

        if (!$id) {
            die("Submission ID missing.");
        }

        $stmt = $this->db()->prepare("
            SELECT *
            FROM submissions
            WHERE id = ?
            LIMIT 1
        ");
        $stmt->execute([$id]);

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

        if (!$row) {
            die("Submission not found.");
        }

        $this->requireSubmissionOwner($row);

        $row['title'] = trim($row['title'] ?? $row['title_en'] ?? $row['title_ar'] ?? '');
        $row['title_ar'] = trim($row['title_ar'] ?? '');
        $row['abstract'] = trim($row['abstract'] ?? $row['abstract_en'] ?? $row['abstract_ar'] ?? '');
        $row['abstract_ar'] = trim($row['abstract_ar'] ?? '');
        $row['keywords'] = trim($row['keywords'] ?? $row['keywords_en'] ?? '');
        $row['keywords_ar'] = trim($row['keywords_ar'] ?? '');

        $this->render('author/submissions/edit', [
            'row' => $row
        ]);
    }

    
public function update()
{
    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }

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

    $id = (int)($_POST['id'] ?? $_GET['id'] ?? 0);
    $userId = (int)($_SESSION['user_id'] ?? 0);

    if (!$id || !$userId) {
        die('Invalid submission.');
    }

    $stmt = $db->prepare("
        SELECT *
        FROM submissions
        WHERE id=?
        AND author_id=?
        LIMIT 1
    ");
    $stmt->execute([$id,$userId]);
    $submission = $stmt->fetch(\PDO::FETCH_ASSOC);

    if (!$submission) {
        die('Submission not found or access denied.');
    }

    $colsStmt = $db->query("SHOW COLUMNS FROM submissions");
    $cols = [];
    foreach ($colsStmt->fetchAll(\PDO::FETCH_ASSOC) as $c) {
        $cols[$c['Field']] = true;
    }

    $data = [];

    foreach ([
        'title',
        'title_en',
        'title_ar',
        'abstract',
        'abstract_en',
        'abstract_ar',
        'keywords',
        'keywords_en',
        'keywords_ar',
        'track_id',
        'submission_type_id',
        'submission_language'
    ] as $field) {
        if (isset($cols[$field]) && array_key_exists($field,$_POST)) {
            $data[$field] = is_string($_POST[$field]) ? trim($_POST[$field]) : $_POST[$field];
        }
    }

    if (!empty($_FILES['manuscript_file']['name'])) {
        $dir = BASE_PATH . '/public/uploads/submissions';
        if (!is_dir($dir)) {
            mkdir($dir,0775,true);
        }

        $name = basename($_FILES['manuscript_file']['name']);
        $ext = strtolower(pathinfo($name,PATHINFO_EXTENSION));
        $safe = 'submission_'.$id.'_'.time().'.'.$ext;
        $target = $dir.'/'.$safe;

        if (move_uploaded_file($_FILES['manuscript_file']['tmp_name'],$target)) {
            if (isset($cols['file_path'])) {
                $data['file_path'] = 'uploads/submissions/'.$safe;
            }
            if (isset($cols['original_filename'])) {
                $data['original_filename'] = $name;
            }
        }
    }

    if ($data) {
        $set = [];
        $vals = [];

        foreach ($data as $k=>$v) {
            $set[] = "$k=?";
            $vals[] = $v;
        }

        $vals[] = $id;

        $sql = "
            UPDATE submissions
            SET ".implode(',',$set)."
            WHERE id=?
        ";

        $db->prepare($sql)->execute($vals);
    }

    /*
    |--------------------------------------------------------------------------
    | AUTHORS / CO-AUTHORS
    |--------------------------------------------------------------------------
    */

    $authorNames = $_POST['author_name'] ?? [];
    $authorEmails = $_POST['author_email'] ?? [];
    $authorAffiliations = $_POST['author_affiliation'] ?? [];
    $authorCountries = $_POST['author_country'] ?? [];
    $correspondingIndex = (int)($_POST['corresponding_author'] ?? 0);

    $cleanAuthors = [];

    foreach ($authorNames as $i=>$name) {
        $name = trim((string)$name);

        if ($name === '') {
            continue;
        }

        $cleanAuthors[] = [
            'name' => $name,
            'email' => trim((string)($authorEmails[$i] ?? '')),
            'affiliation' => trim((string)($authorAffiliations[$i] ?? '')),
            'country' => trim((string)($authorCountries[$i] ?? 'Jordan')),
        ];
    }

    if (!$cleanAuthors) {
        $cleanAuthors[] = [
            'name' => $_SESSION['name'] ?? $_SESSION['full_name'] ?? 'Author',
            'email' => $_SESSION['email'] ?? '',
            'affiliation' => '',
            'country' => 'Jordan',
        ];
        $correspondingIndex = 0;
    }

    if (!isset($cleanAuthors[$correspondingIndex])) {
        $correspondingIndex = 0;
    }

    $db->prepare("
        DELETE FROM submission_authors
        WHERE submission_id=?
    ")->execute([$id]);

    $ins = $db->prepare("
        INSERT INTO submission_authors
        (
            submission_id,
            full_name,
            email,
            affiliation,
            country,
            is_corresponding,
            author_order
        )
        VALUES
        (?,?,?,?,?,?,?)
    ");

    foreach ($cleanAuthors as $i=>$a) {
        $ins->execute([
            $id,
            $a['name'],
            $a['email'],
            $a['affiliation'],
            $a['country'],
            $i === $correspondingIndex ? 1 : 0,
            $i + 1
        ]);
    }

    $_SESSION['flash_success'] = 'Submission updated successfully.';

    header("Location: /easychair/author/submission/show?id=".$id);
    exit;
}



public function authors()
{
    $this->requireLogin();

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

    $stmt = $this->db()->prepare("
        SELECT *
        FROM submission_authors
        WHERE submission_id = ?
        ORDER BY author_order ASC
    ");

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

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

    require BASE_PATH .
        '/app/views/author/submissions/authors.php';
}

/* ============================================================
   AUTHORS WORKFLOW — aligned to submission_authors schema
============================================================ */

public function addAuthor()
{
    $this->requireLogin();

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

    if (!$submissionId) {
        die("Submission ID missing.");
    }

    $name =
        trim($_POST['full_name'] ?? '');

    if ($name === '') {
        die("Author name required.");
    }

    $db = $this->db();

    /* get next order */

    $stmt = $db->prepare("
        SELECT COALESCE(MAX(author_order),0) + 1
        FROM submission_authors
        WHERE submission_id = ?
    ");

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

    $order =
        (int)$stmt->fetchColumn();

    /* insert author */

    $stmt = $db->prepare("
        INSERT INTO submission_authors
        (
            submission_id,
            full_name,
            email,
            affiliation,
            country,
            is_corresponding,
            author_order
        )
        VALUES
        (?, ?, ?, ?, ?, 0, ?)
    ");

    $stmt->execute([

        $submissionId,

        $name,

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

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

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

        $order

    ]);

    error_log(
        "AUTHOR ADDED: submission={$submissionId} name={$name}"
    );

    header(
        "Location: /easychair/author/submission?id=" .
        $submissionId
    );

    exit;
}

public function deleteAuthor()
{
    $this->requireLogin();

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

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

    if (!$id) {
        die("Author ID missing.");
    }

    $stmt = $this->db()->prepare("
        DELETE FROM submission_authors
        WHERE id = ?
    ");

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

    header(
        "Location: /easychair/author/submission?id=" .
        $submissionId
    );

    exit;
}



public function setCorrespondingAuthor()
{
    $this->requireLogin();

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

    $authorId =
        (int)($_POST['author_id'] ?? 0);

    if (!$submissionId || !$authorId) {
        die("Invalid request.");
    }

    $db = $this->db();

    /* reset all */

    $db->prepare("
        UPDATE submission_authors
        SET is_corresponding = 0
        WHERE submission_id = ?
    ")->execute([
        $submissionId
    ]);

    /* set selected */

    $db->prepare("
        UPDATE submission_authors
        SET is_corresponding = 1
        WHERE id = ?
    ")->execute([
        $authorId
    ]);

    header(
        "Location: /easychair/author/submission?id=" .
        $submissionId
    );

    exit;
}


public function viewReviews()
{
    $this->requireLogin();

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

    if (!$submissionId) {
        die("Submission ID missing.");
    }

    $db = $this->db();

    /*
    Verify submission ownership
    */

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

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

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

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

    $this->requireSubmissionOwner($submission);

    /*
    Force correct conference context from submission
    */

    $_SESSION['conference_id'] =
        (int)($submission['conference_id'] ?? 0);

    $_SESSION['org_id'] =
        (int)($submission['org_id'] ?? 0);

    /*
    Blind author reviews
    DO NOT expose reviewer name/id
    */

    $stmt = $db->prepare("
        SELECT
            r.id,
            r.round_no,
            r.overall_score,
            r.score,
            r.recommendation,
            r.comments_to_author,
            r.review_file_path,
            r.file_path,
            r.submitted_at
        FROM reviews r
        WHERE r.submission_id = ?
        AND r.submitted_at IS NOT NULL
        ORDER BY r.round_no ASC, r.id ASC
    ");

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

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

    /*
    Load criteria scores per review
    */

    $criteriaScores = [];

    if (!empty($reviews)) {

        $reviewIds =
            array_map(
                'intval',
                array_column($reviews, 'id')
            );

        $placeholders =
            implode(
                ',',
                array_fill(0, count($reviewIds), '?')
            );

        $stmt = $db->prepare("
            SELECT
                rcs.review_id,
                rcs.score,
                rc.title_en,
                rc.title_ar,
                rc.max_score,
                rc.weight
            FROM review_criterion_scores rcs
            JOIN review_criteria rc
                ON rc.id = rcs.criterion_id
            WHERE rcs.review_id IN ($placeholders)
            ORDER BY rc.sort_order ASC, rc.id ASC
        ");

        $stmt->execute($reviewIds);

        foreach (
            $stmt->fetchAll(\PDO::FETCH_ASSOC)
            as $row
        ) {

            $criteriaScores[
                (int)$row['review_id']
            ][] = $row;

        }

    }

    error_log(
        "AUTHOR BLIND REVIEWS LOADED: submission="
        . $submissionId
        . " count="
        . count($reviews)
    );

    $this->render(
        'author/submissions/reviews',
        [
            'submission' => $submission,
            'reviews' => $reviews,
            'criteriaScores' => $criteriaScores
        ]
    );
}


public function cameraReady()
{
    $this->requireLogin();

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

    if (!$id) {
        die("Submission ID missing.");
    }

    $stmt = $this->db()->prepare("
        SELECT *
        FROM submissions
        WHERE id = ?
        LIMIT 1
    ");
    $stmt->execute([$id]);

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

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

    $this->requireSubmissionOwner($submission);

    $stmt = $this->db()->prepare("
        SELECT *
        FROM submission_files
        WHERE submission_id = ?
        AND file_category IN (
            'camera_ready',
            'copyright',
            'payment_receipt',
            'final_source',
            'other_required'
        )
        ORDER BY id DESC
    ");
    $stmt->execute([$id]);

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

    $this->render(
        'author/submissions/camera_ready',
        [
            'submission' => $submission,
            'files' => $files
        ]
    );
}

public function uploadCameraReady()
{
    $this->requireLogin();

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

    $allowed = [
        'camera_ready',
        'copyright',
        'payment_receipt',
        'final_source',
        'other_required'
    ];

    if (!$submissionId || !in_array($category, $allowed, true)) {
        die("Invalid upload request.");
    }

    $stmt = $this->db()->prepare("
        SELECT *
        FROM submissions
        WHERE id = ?
        LIMIT 1
    ");
    $stmt->execute([$submissionId]);

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

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

    $this->requireSubmissionOwner($submission);

    if (!in_array(($submission['status'] ?? ''), ['accepted', 'production', 'galley', 'published'], true)) {
        die("Camera-ready upload is available only after acceptance.");
    }

    $file = $_FILES['file'] ?? null;

    if (!$file || !is_uploaded_file($file['tmp_name'])) {
        die("File missing.");
    }

    $uploadDir = BASE_PATH . '/public/uploads/camera_ready/';

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

    $originalName = $file['name'];
    $ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION)) ?: 'dat';

    $filename =
        'submission_' .
        $submissionId .
        '_' .
        $category .
        '_' .
        time() .
        '.' .
        $ext;

    $relativePath =
        'uploads/camera_ready/' .
        $filename;

    if (!move_uploaded_file($file['tmp_name'], $uploadDir . $filename)) {
        die("Upload failed.");
    }

    $this->insertDynamic(
        'submission_files',
        [
            'submission_id' => $submissionId,
            'file_category' => $category,
            'original_name' => $originalName,
            'original_filename' => $originalName,
            'file_path' => $relativePath,
            'uploaded_by' => (int)$_SESSION['user_id'],
            'created_at' => date('Y-m-d H:i:s')
        ]
    );

    $this->db()->prepare("
        UPDATE submissions
        SET
            production_status = 'camera_ready_uploaded',
            stage = 'production',
            updated_by = ?,
            updated_at = NOW()
        WHERE id = ?
    ")->execute([
        (int)$_SESSION['user_id'],
        $submissionId
    ]);

    header(
        "Location: /easychair/author/submission/camera-ready?id=" .
        $submissionId
    );
    exit;
}

public function revisionForm()
{
    $this->requireLogin();

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

    if (!$submissionId) {
        die("Submission ID missing.");
    }

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

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

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

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

    $this->requireSubmissionOwner($submission);

    if (
        ($submission['status'] ?? '') !==
        'revision_required'
    ) {

        die(
            "Revision not allowed."
        );

    }

    /*
    Deadline check
    */

    if (
        !empty(
            $submission['revision_open_until']
        )
        &&
        strtotime(
            $submission['revision_open_until']
        ) < time()
    ) {

        die(
            "Revision deadline expired."
        );

    }

    $this->render(
        'author/submissions/revision',
        [
            'submission' => $submission
        ]
    );
}

public function uploadRevision()
{
    $this->requireLogin();

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

    if (!$submissionId) {
        die("Submission ID missing.");
    }

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

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

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

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

    $this->requireSubmissionOwner($submission);

    if (
        ($submission['status'] ?? '') !==
        'revision_required'
    ) {
        
$_SESSION["flash_error"]=
"Revision upload is available only after Revision Required.";

header(
"Location: /easychair/author/submission?id="
.$submissionId
);

exit;

    }

    /*
    Upload file
    */

    if (
        empty($_FILES['file'])
        ||
        !is_uploaded_file(
            $_FILES['file']['tmp_name']
        )
    ) {

        die("File missing.");
    }

    $uploadDir =
        BASE_PATH .
        '/public/uploads/revisions/';

    if (!is_dir($uploadDir)) {

        mkdir(
            $uploadDir,
            0775,
            true
        );

    }

    $filename =
        'revision_' .
        $submissionId .
        '_r' .
        (
            (int)$submission[
                'current_round_no'
            ] + 1
        ) .
        '_' .
        time() .
        '.pdf';

    $relative =
        'uploads/revisions/' .
        $filename;

    move_uploaded_file(
        $_FILES['file']['tmp_name'],
        $uploadDir . $filename
    );

    /*
    Save file version
    */

    $this->insertDynamic(
        'submission_versions',
        [
            'submission_id' => $submissionId,
            'version_no' =>
                (int)$submission[
                    'current_round_no'
                ] + 1,
            'file_path' => $relative,
            'original_filename' =>
                $_FILES['file']['name'],
            'upload_type' =>
                'revision',
            'uploaded_by' =>
                (int)$_SESSION['user_id'],
            'created_at' =>
                date('Y-m-d H:i:s')
        ]
    );

    /*
    Update submission
    */

    /*
Update submission
*/

$this->db()->prepare("
    UPDATE submissions
    SET
        status = 'revised',
        stage  = 'review',
        revision_file = ?,
        current_round_no =
            current_round_no + 1,
        updated_at = NOW()
    WHERE id = ?
")
->execute([

    $relative,

    $submissionId

]);

/*
Start next review round
*/

\App\Services\ReviewRoundService::startNextRound(

    $submissionId,

    (int)$_SESSION['user_id']

);
    /*
    Log history
    */

    $this->insertDynamic(
        'submission_status_history',
        [
            'submission_id' => $submissionId,
            'new_status' => 'revised',
            'changed_by' =>
                (int)$_SESSION['user_id'],
            'created_at' =>
                date('Y-m-d H:i:s')
        ]
    );

    error_log(
        "REVISION SUBMITTED: submission="
        . $submissionId
    );

    header(
        "Location: /easychair/author/dashboard"
    );

    exit;
}




}
