<?php
declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Models\PublishingModel;
use App\Models\Submission;
use App\Models\Conference;
use App\Models\User;
use App\Services\NotificationService;

final class PublishingController extends Controller
{
    public function uploadCameraReady(): void
    {
        require_permission('submissions.upload_camera_ready_own');

        $id = (int) ($_GET['id'] ?? 0);
        if ($id <= 0) {
            redirect('submissions');
        }

        $submissionModel = new Submission();
        $publishingModel = new PublishingModel();

        $submission = $submissionModel->findByIdForAuthor($id, (int) auth_id());
        if (!$submission) {
            redirect('submissions');
        }

        if (!$submissionModel->canUploadCameraReady($submission)) {
            flash('danger', trans('cannot_upload_camera_ready'));
            redirect('submissions/show?id=' . $id);
        }

        if ($this->isPost()) {
            csrf_check();

            try {
                $upload = handle_uploaded_camera_ready($_FILES['camera_ready_file'] ?? [], 'submissions/camera_ready');
            } catch (\Throwable $e) {
                flash('danger', $e->getMessage());
                redirect('submissions/camera-ready?id=' . $id);
            }

            $doi = trim((string) ($_POST['doi'] ?? ''));

            $publishingModel->upsertCameraReady(
                (int) $submission['conference_id'],
                $id,
                $upload['relative_path'],
                $doi !== '' ? $doi : null
            );

            audit_log('upload_camera_ready', 'proceedings', $id, ['doi' => $doi]);

            flash('success', trans('camera_ready_uploaded_success'));
            redirect('submissions/show?id=' . $id);
        }

        $this->view('publishing/camera_ready', [
            'submission' => $submission,
            'proceeding' => $publishingModel->getBySubmission($id),
        ]);
    }

    public function manageSubmission(): void
    {
        require_permission('proceedings.manage');

        $submissionId = (int) ($_GET['submission_id'] ?? 0);
        if ($submissionId <= 0) {
            redirect('submissions');
        }

        $submissionModel = new Submission();
        $publishingModel = new PublishingModel();

        $submission = $submissionModel->findById($submissionId);
        if (!$submission) {
            redirect('submissions');
        }

        $this->view('publishing/manage', [
            'submission' => $submission,
            'proceeding' => $publishingModel->getBySubmission($submissionId),
        ]);
    }

    public function publishSubmission(): void
    {
        require_permission('proceedings.manage');

        if (!$this->isPost()) {
            redirect('submissions');
        }

        csrf_check();

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

        if ($submissionId <= 0) {
            redirect('submissions');
        }

        $publishingModel = new PublishingModel();
        $submissionModel = new Submission();

        $publishingModel->publish($submissionId, $doi !== '' ? $doi : null);
        $submissionModel->setStatus($submissionId, 'published', (int) auth_id());

        audit_log('publish_paper', 'proceedings', $submissionId, ['doi' => $doi]);

        flash('success', trans('paper_published_success'));
        redirect('publishing/manage?submission_id=' . $submissionId);
    }

    public function unpublishSubmission(): void
    {
        require_permission('proceedings.manage');

        if (!$this->isPost()) {
            redirect('submissions');
        }

        csrf_check();

        $submissionId = (int) ($_POST['submission_id'] ?? 0);
        if ($submissionId <= 0) {
            redirect('submissions');
        }

        $publishingModel = new PublishingModel();
        $submissionModel = new Submission();

        $publishingModel->unpublish($submissionId);
        $submissionModel->setStatus($submissionId, 'accepted', (int) auth_id());

        audit_log('unpublish_paper', 'proceedings', $submissionId, []);

        flash('success', trans('paper_unpublished_success'));
        redirect('publishing/manage?submission_id=' . $submissionId);
    }

    public function conferenceProceedings(): void
    {
        $slug = trim((string) ($_GET['slug'] ?? ''));
        if ($slug === '') {
            redirect('');
        }

        $conferenceModel = new Conference();
        $publishingModel = new PublishingModel();

        $conference = $conferenceModel->findBySlug($slug);
        if (!$conference) {
            http_response_code(404);
            echo 'Conference not found';
            return;
        }

        $this->view('publishing/conference_proceedings', [
            'conference' => $conference,
            'papers' => $publishingModel->publishedByConference((int) $conference['id']),
        ]);
    }

    public function paperPage(): void
    {
        $id = (int) ($_GET['id'] ?? 0);
        if ($id <= 0) {
            redirect('');
        }

        $publishingModel = new PublishingModel();
        $submissionModel = new Submission();

        $paper = $publishingModel->publishedPaper($id);
        if (!$paper) {
            http_response_code(404);
            echo 'Paper not found';
            return;
        }

        $this->view('publishing/paper_page', [
            'paper' => $paper,
            'authors' => $submissionModel->authors($id),
        ]);
    }
}
