<?php
namespace App\Controllers;

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

use App\Core\Database;

class AdminProductionController
{
    protected function db()
    {
        return Database::getInstance();
    }

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

    private function role(): string
    {
        return (string)($_SESSION['conference_role'] ?? $_SESSION['role'] ?? $_SESSION['user_role'] ?? '');
    }

    private function requireAccess(): void
    {
        $this->startSession();

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

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

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

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

        if (!$c) {
            exit("Conference not found.");
        }

        if ($this->role() !== 'super_admin' && (int)$c['org_id'] !== (int)($_SESSION['org_id'] ?? 0)) {
            http_response_code(403);
            exit("Invalid organization access.");
        }

        return $c;
    }

    private function setSubmissionStatus(int $submissionId, string $status, string $stage, string $productionStatus): void
    {
        $stmt = $this->db()->prepare("
            UPDATE submissions
            SET status=?,
                stage=?,
                production_status=?,
                updated_at=NOW()
            WHERE id=?
        ");
        $stmt->execute([$status, $stage, $productionStatus, $submissionId]);
    }

    public function index()
    {

        // Pack512: non-superadmin bypasses selector safely.
        if (function_exists('ec_scope_role') && ec_scope_role() !== 'super_admin') {
            if (function_exists('ec_scope_auto_select_conference')) {
                // ec_scope_auto_select_conference(true);
            }
            $landing = function_exists('ec_scope_landing_url') ? ec_scope_landing_url() : '/easychair/admin/dashboard';
            header("Location: " . $landing);
            exit;
        }

$this->requireAccess();
        $conference = $this->conference();

        $stmt = $this->db()->prepare("
            SELECT 
                s.id,
                s.submission_no,
                COALESCE(s.title,s.title_en,s.title_ar,CONCAT('Submission #',s.id)) AS display_title,
                s.status,
                s.stage,
                s.production_status,
                s.doi,
                g.id AS latest_galley_id,
                g.galley_label_en,
                g.galley_label_ar,
                g.galley_type,
                g.file_path,
                g.original_filename,
                g.status AS galley_status,
                g.is_public,
                g.sort_order,
                g.approved_at
            FROM submissions s
            LEFT JOIN production_galleys g
                   ON g.id = (
                        SELECT MAX(g2.id)
                        FROM production_galleys g2
                        WHERE g2.submission_id = s.id
                   )
            WHERE s.conference_id=?
              AND s.org_id=?
              AND s.status IN ('accepted','galley','production','assigned_to_issue','published')
            ORDER BY s.id DESC
        ");
        $stmt->execute([(int)$conference['id'], (int)$conference['org_id']]);
        $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        $stmt = $this->db()->prepare("
            SELECT 
                g.*,
                s.submission_no,
                COALESCE(s.title,s.title_en,s.title_ar) AS submission_title
            FROM production_galleys g
            JOIN submissions s ON s.id=g.submission_id
            WHERE g.conference_id=?
              AND g.org_id=?
            ORDER BY g.submission_id DESC, g.sort_order ASC, g.id DESC
        ");
        $stmt->execute([(int)$conference['id'], (int)$conference['org_id']]);
        $galleys = $stmt->fetchAll(\PDO::FETCH_ASSOC);

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

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

    public function upload()
    {
        $this->requireAccess();
        $conference = $this->conference();

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

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

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

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

        $galleyType = $_POST['galley_type'] ?? 'pdf';
        $allowedTypes = ['pdf','html','xml','epub','docx','other'];
        if (!in_array($galleyType, $allowedTypes, true)) {
            $galleyType = 'other';
        }

        $dir = BASE_PATH . '/public/storage/galleys/' . (int)$conference['id'];
        if (!is_dir($dir)) {
            mkdir($dir, 0775, true);
        }

        $ext = strtolower(pathinfo($_FILES['galley_file']['name'], PATHINFO_EXTENSION));
        $ext = preg_replace('/[^a-z0-9]/', '', $ext);

        $allowedExt = ['pdf','doc','docx','html','htm','xml','epub','zip'];
        if (!in_array($ext, $allowedExt, true)) {
            exit("Invalid file type.");
        }

        $file = 'galley_' . $submissionId . '_' . date('YmdHis') . '_' . rand(1000,9999) . '.' . $ext;

        if (!move_uploaded_file($_FILES['galley_file']['tmp_name'], $dir . '/' . $file)) {
            exit("Could not upload file.");
        }

        $path = 'galleys/' . (int)$conference['id'] . '/' . $file;

        $stmt = $this->db()->prepare("
            INSERT INTO production_galleys
            (org_id, conference_id, submission_id, galley_label_en, galley_label_ar, galley_type,
             file_path, original_filename, status, notes, is_public, sort_order, uploaded_by)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?, ?, ?)
        ");
        $stmt->execute([
            (int)$conference['org_id'],
            (int)$conference['id'],
            $submissionId,
            trim($_POST['galley_label_en'] ?? ''),
            trim($_POST['galley_label_ar'] ?? ''),
            $galleyType,
            $path,
            $_FILES['galley_file']['name'],
            trim($_POST['notes'] ?? ''),
            !empty($_POST['is_public']) ? 1 : 0,
            (int)($_POST['sort_order'] ?? 0),
            (int)$_SESSION['user_id']
        ]);

        $this->setSubmissionStatus($submissionId, 'galley', 'galley', 'galley_uploaded');

        header("Location: /easychair/admin/production");
        exit;
    }

    public function approve()
    {
        $this->requireAccess();
        $conference = $this->conference();

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

        $stmt = $this->db()->prepare("
            SELECT *
            FROM production_galleys
            WHERE id=?
              AND conference_id=?
              AND org_id=?
            LIMIT 1
        ");
        $stmt->execute([$id, (int)$conference['id'], (int)$conference['org_id']]);
        $galley = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$galley) {
            exit("Galley not found.");
        }

        $stmt = $this->db()->prepare("
            UPDATE production_galleys
            SET status='approved',
                approved_by=?,
                approved_at=NOW()
            WHERE id=?
        ");
        $stmt->execute([(int)$_SESSION['user_id'], $id]);

        $this->setSubmissionStatus((int)$galley['submission_id'], 'production', 'production', 'approved');

        header("Location: /easychair/admin/production");
        exit;
    }

    public function togglePublic()
    {
        $this->requireAccess();
        $conference = $this->conference();

        $stmt = $this->db()->prepare("
            UPDATE production_galleys
            SET is_public = IF(is_public=1,0,1)
            WHERE id=?
              AND conference_id=?
              AND org_id=?
        ");
        $stmt->execute([(int)($_GET['id'] ?? 0), (int)$conference['id'], (int)$conference['org_id']]);

        header("Location: /easychair/admin/production");
        exit;
    }

    public function delete()
    {
        $this->requireAccess();
        $conference = $this->conference();

        $stmt = $this->db()->prepare("
            DELETE FROM production_galleys
            WHERE id=?
              AND conference_id=?
              AND org_id=?
        ");
        $stmt->execute([(int)($_GET['id'] ?? 0), (int)$conference['id'], (int)$conference['org_id']]);

        header("Location: /easychair/admin/production");
        exit;
    }
}
