<?php
declare(strict_types=1);
namespace BranchAdmin\Controllers;

/**
 * Branch Admit Card Controller
 *
 * Branch admins generate admit cards for admitted students. Each admit card
 * includes the student's portal login credentials (username + password).
 */
class BranchAdmitCardController extends BranchBaseController
{
    public function index(): void
    {
        requireBranchAdmin();
        $branchId = $this->getBranchId();
        $this->ensureCredentialsColumns();

        $stmt = $this->db->prepare("SELECT ac.*, u.name AS student_name, s.enrollment_no, e.title AS exam_name
            FROM admit_cards ac
            LEFT JOIN students s ON ac.student_id = s.id
            LEFT JOIN users u ON s.user_id = u.id
            LEFT JOIN exams e ON ac.exam_id = e.id
            WHERE ac.branch_id = :bid ORDER BY ac.created_at DESC");
        $stmt->execute([':bid'=>$branchId]);
        $cards = $stmt->fetchAll() ?: [];

        $exams = [];
        try { $stmt = $this->db->prepare("SELECT id, title FROM exams WHERE branch_id=:bid AND is_published=1 AND is_active=1 ORDER BY title"); $stmt->execute([':bid'=>$branchId]); $exams = $stmt->fetchAll() ?: []; } catch (\Throwable $e) {}

        $students = [];
        try { $stmt = $this->db->prepare("SELECT s.id,u.name,s.enrollment_no FROM students s LEFT JOIN users u ON s.user_id=u.id WHERE s.branch_id=:bid AND s.status='active' ORDER BY u.name"); $stmt->execute([':bid'=>$branchId]); $students = $stmt->fetchAll() ?: []; } catch (\Throwable $e) {}

        $this->branchAdminView('admit_cards/index', ['title'=>'Admit Cards','currentPage'=>'admit_cards','cards'=>$cards,'exams'=>$exams,'students'=>$students]);
    }

    public function generate(): void
    {
        requireBranchAdmin();
        $this->validateCsrf();
        $branchId = $this->getBranchId();
        $this->ensureCredentialsColumns();

        $studentId = (int)($_POST['student_id'] ?? 0);
        $examId    = (int)($_POST['exam_id'] ?? 0);
        $loginUsername = trim($_POST['login_username'] ?? '');
        $loginPassword = $_POST['login_password'] ?? '';

        if ($studentId <= 0 || $examId <= 0) {
            flash('error', 'Please select both student and exam.');
            redirect(BASE_PATH.'/branch/admit-cards');
        }
        if (strlen($loginPassword) < 4) {
            // Auto-generate password if empty/short
            $stmt = $this->db->prepare("SELECT s.id, s.enrollment_no, s.user_id, u.phone FROM students s LEFT JOIN users u ON s.user_id = u.id WHERE s.id=:sid AND s.branch_id=:bid LIMIT 1");
            $stmt->execute([':sid'=>$studentId, ':bid'=>$branchId]);
            $student = $stmt->fetch() ?: null;
            if (!$student) { flash('error', 'Student not found.'); redirect(BASE_PATH.'/branch/admit-cards'); }
            if ($loginUsername === '') $loginUsername = $student['enrollment_no'] ?? ('student'.$studentId);
            $phoneDigits = preg_replace('/\D/', '', (string)($student['phone'] ?? ''));
            if (strlen($phoneDigits) >= 4) {
                $loginPassword = substr($phoneDigits, -6);
                if (strlen($loginPassword) < 4) $loginPassword = str_pad($phoneDigits, 6, '0', STR_PAD_LEFT);
            } else {
                $loginPassword = str_pad((string)rand(100000, 999999), 6, '0', STR_PAD_LEFT);
            }
        }

        $stmt = $this->db->prepare("SELECT s.id, s.enrollment_no, s.user_id, u.phone FROM students s LEFT JOIN users u ON s.user_id = u.id WHERE s.id=:sid AND s.branch_id=:bid LIMIT 1");
        $stmt->execute([':sid'=>$studentId, ':bid'=>$branchId]);
        $student = $stmt->fetch() ?: null;
        if (!$student) { flash('error', 'Student not found in your branch.'); redirect(BASE_PATH.'/branch/admit-cards'); }
        if ($loginUsername === '') $loginUsername = $student['enrollment_no'] ?? ('student'.$studentId);

        $stmt = $this->db->prepare("SELECT id FROM exams WHERE id=:eid AND branch_id=:bid LIMIT 1");
        $stmt->execute([':eid'=>$examId, ':bid'=>$branchId]);
        if (!$stmt->fetch()) { flash('error', 'Exam not found in your branch.'); redirect(BASE_PATH.'/branch/admit-cards'); }

        $stmt = $this->db->prepare("SELECT id, card_number FROM admit_cards WHERE student_id=:sid AND exam_id=:eid AND branch_id=:bid LIMIT 1");
        $stmt->execute([':sid'=>$studentId, ':eid'=>$examId, ':bid'=>$branchId]);
        $existing = $stmt->fetch() ?: null;

        $cardNumber = 'ADM' . $this->getBranchCode() . date('Y') . str_pad((string)rand(1,9999), 4, '0', STR_PAD_LEFT);
        $hashedPassword = password_hash($loginPassword, PASSWORD_DEFAULT);

        try {
            if (!empty($student['user_id'])) {
                $stmt = $this->db->prepare("UPDATE users SET password=:pwd WHERE id=:uid");
                $stmt->execute([':pwd'=>$hashedPassword, ':uid'=>(int)$student['user_id']]);
            }

            if ($existing) {
                $stmt = $this->db->prepare("UPDATE admit_cards SET login_username=:lu, login_password=:lp, card_number=:cn, status='issued', issued_at=NOW() WHERE id=:id");
                $stmt->execute([':lu'=>$loginUsername, ':lp'=>$loginPassword, ':cn'=>$cardNumber, ':id'=>(int)$existing['id']]);
                $cardId = (int)$existing['id'];
                flash('success', "Admit card regenerated! Card No: {$cardNumber}. Login: {$loginUsername} / {$loginPassword}");
            } else {
                $stmt = $this->db->prepare("INSERT INTO admit_cards (student_id, exam_id, branch_id, card_number, login_username, login_password, status, issued_at, created_at) VALUES (:sid, :eid, :bid, :cn, :lu, :lp, 'issued', NOW(), NOW())");
                $stmt->execute([':sid'=>$studentId, ':eid'=>$examId, ':bid'=>$branchId, ':cn'=>$cardNumber, ':lu'=>$loginUsername, ':lp'=>$loginPassword]);
                $cardId = (int)$this->db->lastInsertId();
                flash('success', "Admit card generated! Card No: {$cardNumber}. Login: {$loginUsername} / {$loginPassword}");
            }
            redirect(BASE_PATH.'/branch/admit-cards/'.$cardId.'/view');
        } catch (\Throwable $e) {
            flash('error', 'Failed: '.$e->getMessage());
            redirect(BASE_PATH.'/branch/admit-cards');
        }
    }

    public function show(?int $id = null): void
    {
        requireBranchAdmin();
        $branchId = $this->getBranchId();
        $this->ensureCredentialsColumns();

        if (!$id || $id <= 0) { flash('error', 'Invalid ID.'); redirect(BASE_PATH.'/branch/admit-cards'); }

        $stmt = $this->db->prepare("SELECT ac.*, u.name AS student_name, u.email, u.phone, u.photo,
            s.enrollment_no, s.father_name, s.dob, s.course_id, c.name AS course_name,
            e.title AS exam_name, e.title_hindi, e.language AS exam_language, e.duration_minutes,
            e.total_marks, e.start_time, e.end_time, e.instructions, e.instructions_hindi,
            b.name AS branch_name, b.branch_code, b.address AS branch_address, b.phone AS branch_phone
            FROM admit_cards ac
            LEFT JOIN students s ON ac.student_id = s.id
            LEFT JOIN users u ON s.user_id = u.id
            LEFT JOIN courses c ON s.course_id = c.id
            LEFT JOIN exams e ON ac.exam_id = e.id
            LEFT JOIN branches b ON ac.branch_id = b.id
            WHERE ac.id=:id AND ac.branch_id=:bid LIMIT 1");
        $stmt->execute([':id'=>$id, ':bid'=>$branchId]);
        $card = $stmt->fetch() ?: null;
        if (!$card) { flash('error', 'Admit card not found.'); redirect(BASE_PATH.'/branch/admit-cards'); }

        $this->branchAdminView('admit_cards/view', ['title'=>'Admit Card: '.($card['card_number']??''),'currentPage'=>'admit_cards','card'=>$card]);
    }

    private function ensureCredentialsColumns(): void
    {
        static $done = false;
        if ($done) return;
        $checks = [
            'login_username' => "ADD COLUMN `login_username` VARCHAR(100) NULL DEFAULT NULL AFTER `card_number`",
            'login_password' => "ADD COLUMN `login_password` VARCHAR(100) NULL DEFAULT NULL AFTER `login_username`",
        ];
        foreach ($checks as $col => $ddl) {
            try {
                $stmt = $this->db->prepare("SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'admit_cards' AND COLUMN_NAME = :col");
                $stmt->execute([':col' => $col]);
                if ((int)$stmt->fetchColumn() === 0) {
                    $this->db->exec("ALTER TABLE `admit_cards` {$ddl}");
                }
            } catch (\Throwable $e) {}
        }
        $done = true;
    }
}
