<?php
namespace App\Controllers;

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

class AuthorSubmissionController extends Controller
{
    private function requireConference()
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }

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

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


    private function requireAuthorPhone(): void
    {
        $db = Database::getInstance();

        $stmt = $db->prepare("
            SELECT COALESCE(NULLIF(phone,''), NULLIF(mobile,'')) AS phone_value
            FROM users
            WHERE id = ?
            LIMIT 1
        ");
        $stmt->execute([(int)$_SESSION['user_id']]);
        $phone = trim((string)$stmt->fetchColumn());

        if ($phone === '') {
            header("Location: /easychair/author/profile/complete");
            exit;
        }
    }

    public function create()
    {
        
        if (!empty($_SESSION['user_id']) && !empty($_SESSION['conference_id'])) {
            $profileGuard = new ProfileGuard();
            $profileGuard->ensureCompleteOrRedirect(
                (int)$_SESSION['user_id'],
                (int)$_SESSION['conference_id'],
                $_SERVER['REQUEST_URI'] ?? ''
            );
        }

$this->requireConference();
        $this->requireAuthorPhone();

        $db = Database::getInstance();

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

        $stmt = $db->prepare("
            SELECT stage, is_enabled
            FROM conference_workflow
            WHERE conference_id = ?
            ORDER BY FIELD(stage,'submission','screening','review','revision','decision','galley','production','issue','published'), id
        ");
        $stmt->execute([(int)$_SESSION['conference_id']]);
        $workflow = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $submissionOpen = true;

        if (!empty($conference['submission_start']) && strtotime($conference['submission_start']) > time()) {
            $submissionOpen = false;
        }

        if (!empty($conference['submission_end']) && strtotime($conference['submission_end']) < time()) {
            $submissionOpen = false;
        }

        if (($conference['cfp_status'] ?? 'open') === 'closed') {
            $submissionOpen = false;
        }

        $fileCategories = [
            'abstract' => 'Abstract',
            'manuscript' => 'Manuscript',
            'revised_version' => 'Revised Version',
            'payment_invoice' => 'Payment Invoice',
            'figures' => 'Figures',
            'tables' => 'Tables',
            'comments' => 'Comments',
            'other' => 'Other',
        ];

        ob_start();
        require BASE_PATH . '/app/views/author/submit.php';
        $content = ob_get_clean();

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

    public function store()
    {
        $this->requireConference();
        $this->requireAuthorPhone();

        $db = Database::getInstance();

        $conferenceId = (int)$_SESSION['conference_id'];
        $orgId = (int)($_SESSION['org_id'] ?? 0);
        $userId = (int)$_SESSION['user_id'];

        $title = trim($_POST['title'] ?? '');
        $titleAr = trim($_POST['title_ar'] ?? '');
        $abstract = trim($_POST['abstract'] ?? '');
        $abstractAr = trim($_POST['abstract_ar'] ?? '');
        $keywords = trim($_POST['keywords'] ?? '');
        $keywordsAr = trim($_POST['keywords_ar'] ?? '');

        if (!$title && !$titleAr) {
            die("Title is required.");
        }

        $submissionNo = 'SUB-' . $conferenceId . '-' . date('YmdHis') . '-' . $userId;

        $mainFilePath = null;
        $mainOriginal = null;

        $db->beginTransaction();

        try {
            $stmt = $db->prepare("
                INSERT INTO submissions
                (conference_id, author_id, submission_no, title, title_ar, abstract, abstract_ar,
                 keywords, keywords_ar, status, stage, current_round_no, current_version,
                 submitted_at, org_id, author_name, created_at)
                VALUES
                (?, ?, ?, ?, ?, ?, ?, ?, ?, 'submitted', 'submitted', 1, 1, NOW(), ?, ?, NOW())
            ");

            $stmt->execute([
                $conferenceId,
                $userId,
                $submissionNo,
                $title,
                $titleAr,
                $abstract,
                $abstractAr,
                $keywords,
                $keywordsAr,
                $orgId,
                $_SESSION['user_name'] ?? ''
            ]);

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

            $coNames = $_POST['coauthor_name'] ?? [];
            $coEmails = $_POST['coauthor_email'] ?? [];
            $coAffiliations = $_POST['coauthor_affiliation'] ?? [];
            $coCountries = $_POST['coauthor_country'] ?? [];

            foreach ($coNames as $i => $name) {
                $name = trim((string)$name);
                if ($name === '') {
                    continue;
                }

                $stmt = $db->prepare("
                    INSERT INTO submission_coauthors
                    (org_id, conference_id, submission_id, full_name, email, affiliation, country, is_corresponding, sort_order)
                    VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?)
                ");

                $stmt->execute([
                    $orgId,
                    $conferenceId,
                    $submissionId,
                    $name,
                    trim((string)($coEmails[$i] ?? '')),
                    trim((string)($coAffiliations[$i] ?? '')),
                    trim((string)($coCountries[$i] ?? '')),
                    $i + 1
                ]);
            }

            $dir = BASE_PATH . '/public/storage/submissions/' . $conferenceId;

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

            $allowedCategories = [
                'abstract',
                'manuscript',
                'revised_version',
                'payment_invoice',
                'figures',
                'tables',
                'comments',
                'other'
            ];

            $categories = $_POST['file_category'] ?? [];

            if (!empty($_FILES['submission_files']['name']) && is_array($_FILES['submission_files']['name'])) {
                foreach ($_FILES['submission_files']['name'] as $i => $originalName) {
                    if (!$originalName || !is_uploaded_file($_FILES['submission_files']['tmp_name'][$i])) {
                        continue;
                    }

                    $category = $categories[$i] ?? 'manuscript';
                    if (!in_array($category, $allowedCategories, true)) {
                        $category = 'other';
                    }

                    $ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
                    $safeExt = preg_replace('/[^a-z0-9]/', '', $ext);
                    $fileName = 'sub_' . $submissionId . '_' . $category . '_' . time() . '_' . $i . '.' . $safeExt;
                    $target = $dir . '/' . $fileName;

                    if (move_uploaded_file($_FILES['submission_files']['tmp_name'][$i], $target)) {
                        $relative = 'submissions/' . $conferenceId . '/' . $fileName;

                        $stmt = $db->prepare("
                            INSERT INTO submission_files
                            (org_id, conference_id, submission_id, category, file_path, original_filename, mime_type, file_size, uploaded_by, version_no)
                            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 1)
                        ");
                        $stmt->execute([
                            $orgId,
                            $conferenceId,
                            $submissionId,
                            $category,
                            $relative,
                            $originalName,
                            $_FILES['submission_files']['type'][$i] ?? null,
                            (int)($_FILES['submission_files']['size'][$i] ?? 0),
                            $userId
                        ]);

                        if ($mainFilePath === null || $category === 'manuscript') {
                            $mainFilePath = $relative;
                            $mainOriginal = $originalName;
                        }
                    }
                }
            }

            if ($mainFilePath) {
                $stmt = $db->prepare("
                    UPDATE submissions
                    SET file_path = ?,
                        original_filename = ?
                    WHERE id = ?
                ");
                $stmt->execute([$mainFilePath, $mainOriginal, $submissionId]);

                $stmt = $db->prepare("
                    INSERT INTO submission_versions
                    (org_id, conference_id, submission_id, version_no, file_path, original_filename, uploaded_by, upload_type, note)
                    VALUES (?, ?, ?, 1, ?, ?, ?, 'submission', 'Initial submission')
                ");
                $stmt->execute([
                    $orgId,
                    $conferenceId,
                    $submissionId,
                    $mainFilePath,
                    $mainOriginal,
                    $userId
                ]);
            }

            $db->commit();

            try {
                SubmissionWorkflowService::log(
                    $submissionId,
                    'submission_created',
                    'Submission created',
                    'Author submitted a new paper.',
                    $userId,
                    'author'
                );
            } catch (\Throwable $e) {
                // keep submission working
            }

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

        } catch (\Throwable $e) {
            $db->rollBack();
            throw $e;
        }
    }

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

        $db = Database::getInstance();

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

        $stmt = $db->prepare("
            SELECT s.*, COALESCE(c.title_ar, c.title_en) AS conference_title, c.short_name
            FROM submissions s
            LEFT JOIN conferences c ON c.id = s.conference_id
            WHERE s.id = ?
              AND s.author_id = ?
              AND s.conference_id = ?
            LIMIT 1
        ");
        $stmt->execute([
            $submissionId,
            (int)$_SESSION['user_id'],
            (int)$_SESSION['conference_id']
        ]);
        $submission = $stmt->fetch(\PDO::FETCH_ASSOC);

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

        $stmt = $db->prepare("SELECT * FROM submission_versions WHERE submission_id = ? ORDER BY version_no DESC, id DESC");
        $stmt->execute([$submissionId]);
        $versions = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $stmt = $db->prepare("SELECT * FROM submission_files WHERE submission_id = ? ORDER BY category, id");
        $stmt->execute([$submissionId]);
        $files = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $stmt = $db->prepare("SELECT * FROM submission_coauthors WHERE submission_id = ? ORDER BY sort_order, id");
        $stmt->execute([$submissionId]);
        $coauthors = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $stmt = $db->prepare("SELECT event_key, event_title, event_body, created_at FROM submission_activity_log WHERE submission_id = ? ORDER BY id DESC");
        $stmt->execute([$submissionId]);
        $activity = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $stmt = $db->prepare("
            SELECT
                ra.status,
                ra.round_no,
                ra.completed_at,
                rv.recommendation,
                rv.comments_to_author,
                rv.overall_score,
                rv.score,
                rv.submitted_at
            FROM review_assignments ra
            LEFT JOIN reviews rv ON rv.review_assignment_id = ra.id
            WHERE ra.submission_id = ?
              AND ra.status = 'completed'
            ORDER BY ra.round_no ASC, ra.id ASC
        ");
        $stmt->execute([$submissionId]);
        $authorReviews = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        ob_start();
        require BASE_PATH . '/app/views/author/submission_show.php';
        $content = ob_get_clean();

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

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

        $db = Database::getInstance();
        $submissionId = (int)($_POST['submission_id'] ?? 0);

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

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

        if (empty($_FILES['revision_file']['name']) || !is_uploaded_file($_FILES['revision_file']['tmp_name'])) {
            exit("Revision file is required.");
        }

        $dir = BASE_PATH . '/public/storage/revisions/' . (int)$submission['conference_id'];

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

        $ext = strtolower(pathinfo($_FILES['revision_file']['name'], PATHINFO_EXTENSION));
        $safeExt = preg_replace('/[^a-z0-9]/', '', $ext);
        $fileName = 'revision_' . $submissionId . '_' . time() . '.' . $safeExt;
        $target = $dir . '/' . $fileName;

        if (!move_uploaded_file($_FILES['revision_file']['tmp_name'], $target)) {
            exit("Could not upload revision file.");
        }

        $path = 'revisions/' . (int)$submission['conference_id'] . '/' . $fileName;

        SubmissionWorkflowService::addVersion(
            $submissionId,
            $path,
            $_FILES['revision_file']['name'],
            (int)$_SESSION['user_id'],
            'revision',
            trim($_POST['revision_note'] ?? '')
        );

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