<?php
/**
 * Branch Print Queue Controller
 *
 * Dedicated page for bulk printing of approved certificates + marksheets.
 * Features:
 *   - Filter by course, date range, month
 *   - Cart system (select multiple certificates)
 *   - Download combined PDF (all selected in one file)
 *   - Print All (opens browser print dialog)
 *
 * URL prefix: /branch/print-queue/*
 */

namespace BranchAdmin\Controllers;

use BranchAdmin\Controllers\BranchAdminController;
use App\Helpers\DocumentGenerator;

class BranchPrintQueueController extends BranchAdminController
{
    /**
     * Show the print queue page with filters + cart.
     */
    public function index(): void
    {
        requireBranchAdmin();
        $branchId = $this->getBranchId();

        // Filters
        $courseFilter = trim($_GET['course_id'] ?? '');
        $dateFrom     = trim($_GET['date_from'] ?? '');
        $dateTo       = trim($_GET['date_to'] ?? '');
        $monthFilter  = trim($_GET['month'] ?? '');
        $docType      = trim($_GET['doc_type'] ?? '');

        // Build query — only show generated (approved) certificates for this branch
        $sql = "SELECT c.*,
                       COALESCE(c.student_name, u.name, 'Unknown') AS student_name,
                       s.enrollment_no, u.photo,
                       COALESCE(c.course_name, cs.name, '—') AS course_name,
                       t.type AS doc_type, t.name AS template_name,
                       b.branch_code
                FROM certificates c
                LEFT JOIN students s ON c.student_id = s.id
                LEFT JOIN users u ON s.user_id = u.id
                LEFT JOIN courses cs ON c.course_id = cs.id
                LEFT JOIN certificate_templates t ON c.template_id = t.id
                LEFT JOIN branches b ON c.branch_id = b.id
                WHERE c.branch_id = :bid AND c.status = 'generated'";
        $params = [':bid' => $branchId];

        if ($courseFilter !== '') {
            $sql .= " AND c.course_id = :cid";
            $params[':cid'] = $courseFilter;
        }
        if ($dateFrom !== '') {
            $sql .= " AND DATE(c.issue_date) >= :df";
            $params[':df'] = $dateFrom;
        }
        if ($dateTo !== '') {
            $sql .= " AND DATE(c.issue_date) <= :dt";
            $params[':dt'] = $dateTo;
        }
        if ($monthFilter !== '') {
            $sql .= " AND DATE_FORMAT(c.issue_date, '%Y-%m') = :mf";
            $params[':mf'] = $monthFilter;
        }
        if ($docType !== '' && in_array($docType, ['certificate', 'marksheet'], true)) {
            $sql .= " AND t.type = :dt2";
            $params[':dt2'] = $docType;
        }

        $sql .= " ORDER BY c.created_at DESC LIMIT 500";

        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        $documents = $stmt->fetchAll(\PDO::FETCH_ASSOC) ?: [];

        // Stats
        $stats = [
            'total'      => count($documents),
            'cert_count' => 0,
            'ms_count'   => 0,
        ];
        foreach ($documents as $d) {
            if (($d['doc_type'] ?? '') === 'marksheet') $stats['ms_count']++;
            else $stats['cert_count']++;
        }

        // Fetch all courses for filter dropdown
        $courses = [];
        try {
            $courses = $this->db->query("SELECT id, name FROM courses WHERE active=1 ORDER BY name")->fetchAll(\PDO::FETCH_ASSOC) ?: [];
        } catch (\Throwable $e) {}

        // Build months list (last 12 months)
        $months = [];
        $current = strtotime('first day of this month');
        for ($i = 0; $i < 12; $i++) {
            $ts = strtotime("-{$i} months", $current);
            $months[date('Y-m', $ts)] = date('F Y', $ts);
        }

        $this->branchAdminView('print_queue/index', [
            'title'        => 'Print Queue',
            'currentPage'  => 'print_queue',
            'documents'    => $documents,
            'stats'        => $stats,
            'courses'      => $courses,
            'months'       => $months,
            'courseFilter' => $courseFilter,
            'dateFrom'     => $dateFrom,
            'dateTo'       => $dateTo,
            'monthFilter'  => $monthFilter,
            'docType'      => $docType,
            'csrfToken'    => $this->csrfToken ?? '',
        ]);
    }

    /**
     * Bulk download — combine selected certificates into one PDF.
     */
    public function bulkDownload(): void
    {
        requireBranchAdmin();
        $this->validateCsrf();
        $branchId = $this->getBranchId();

        $selectedIds = $_POST['selected'] ?? [];
        if (is_string($selectedIds)) {
            $selectedIds = explode(',', $selectedIds);
        }
        $selectedIds = array_filter(array_map('intval', $selectedIds));

        if (empty($selectedIds)) {
            flash('error', '❌ No certificates selected. Please select at least one to download.');
            redirect(BASE_PATH . '/branch/print-queue');
        }

        // Fetch all selected certificates
        $placeholders = implode(',', array_fill(0, count($selectedIds), '?'));
        $sql = "SELECT c.*,
                       COALESCE(c.student_name, u.name, 'Unknown') AS student_name,
                       s.enrollment_no, s.father_name, s.mother_name, s.dob, s.admission_date,
                       u.photo, u.phone,
                       COALESCE(c.course_name, cs.name, '—') AS course_name,
                       cs.duration, cs.cert_pattern_id, cs.marksheet_pattern_id,
                       t.type AS doc_type, t.name AS template_name,
                       b.name AS branch_name, b.branch_code
                FROM certificates c
                LEFT JOIN students s ON c.student_id = s.id
                LEFT JOIN users u ON s.user_id = u.id
                LEFT JOIN courses cs ON c.course_id = cs.id
                LEFT JOIN certificate_templates t ON c.template_id = t.id
                LEFT JOIN branches b ON c.branch_id = b.id
                WHERE c.id IN ($placeholders) AND c.branch_id = ? AND c.status = 'generated'
                ORDER BY c.created_at ASC";

        $params = array_merge($selectedIds, [$branchId]);
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        $documents = $stmt->fetchAll(\PDO::FETCH_ASSOC) ?: [];

        if (empty($documents)) {
            flash('error', '❌ No valid certificates found. They may not belong to your branch.');
            redirect(BASE_PATH . '/branch/print-queue');
        }

        // Generate combined PDF
        try {
            $generator = new DocumentGenerator();
            $pdf = null;

            foreach ($documents as $doc) {
                $docType = $doc['doc_type'] ?? 'certificate';

                // Determine pattern ID
                $patternId = $doc['pattern_id'] ?? null;
                if (!$patternId) {
                    $patternId = ($docType === 'marksheet')
                        ? ($doc['marksheet_pattern_id'] ?? null)
                        : ($doc['cert_pattern_id'] ?? null);
                }
                if (!$patternId) {
                    try {
                        $stmt = $this->db->query("SELECT id FROM certificate_patterns WHERE is_default = 1 AND status = 'locked' LIMIT 1");
                        $patternId = $stmt->fetchColumn() ?: null;
                    } catch (\Throwable $e) {}
                }
                if (!$patternId) continue;

                // Load pattern
                $stmt = $this->db->prepare("SELECT * FROM certificate_patterns WHERE id = :pid LIMIT 1");
                $stmt->execute([':pid' => $patternId]);
                $pattern = $stmt->fetch(\PDO::FETCH_ASSOC) ?: null;
                if (!$pattern) continue;

                // Background path
                $bgPath = $docType === 'certificate'
                    ? ($pattern['cert_background_path'] ?? '')
                    : ($pattern['marksheet_background_path'] ?? '');
                if (empty($bgPath)) continue;

                // Pattern fields
                $stmt = $this->db->prepare(
                    "SELECT * FROM certificate_pattern_fields
                     WHERE pattern_id = :pid AND doc_type = :dt AND is_enabled = 1
                     ORDER BY id ASC"
                );
                $stmt->execute([':pid' => $patternId, ':dt' => $docType]);
                $fields = $stmt->fetchAll(\PDO::FETCH_ASSOC) ?: [];

                // Parse subjects_json
                $subjectsData = [];
                if (!empty($doc['subjects_json'])) {
                    $subjectsData = json_decode($doc['subjects_json'], true) ?: [];
                }
                $subjects = [];
                if ($docType === 'marksheet' && !empty($subjectsData['subjects'])) {
                    $subjList = $subjectsData['subjects'];
                    $maxList  = $subjectsData['max_marks'] ?? [];
                    $obtList  = $subjectsData['obtained_marks'] ?? [];
                    for ($i = 0; $i < count($subjList); $i++) {
                        $subjects[] = [
                            'name'     => $subjList[$i] ?? 'Subject ' . ($i + 1),
                            'max'      => (int)($maxList[$i] ?? 100),
                            'obtained' => (int)($obtList[$i] ?? 0),
                        ];
                    }
                }

                // Division
                $pct = (float)($doc['percentage'] ?? 0);
                $division = $doc['division'] ?? '';
                if (empty($division)) {
                    if ($pct >= 60)      $division = 'First Division';
                    elseif ($pct >= 45)  $division = 'Second Division';
                    elseif ($pct >= 33)  $division = 'Third Division';
                    else                 $division = 'Fail';
                }

                // Photo
                $photoPath = '';
                if (!empty($doc['photo'])) {
                    $candidates = [
                        $doc['photo'],
                        $_SERVER['DOCUMENT_ROOT'] . '/' . ltrim($doc['photo'], '/'),
                        $_SERVER['DOCUMENT_ROOT'] . '/gmind/' . ltrim($doc['photo'], '/'),
                        '/home/advaysin/public_html/' . ltrim($doc['photo'], '/'),
                        '/home/advaysin/public_html/gmind/' . ltrim($doc['photo'], '/'),
                    ];
                    foreach ($candidates as $c) {
                        if (file_exists($c)) {
                            $photoPath = $c;
                            break;
                        }
                    }
                }

                // Address
                $addrLine = '';
                try {
                    $stmt = $this->db->prepare("SELECT address, city, state, pin_code FROM students WHERE id = :sid LIMIT 1");
                    $stmt->execute([':sid' => $doc['student_id']]);
                    $addrRow = $stmt->fetch(\PDO::FETCH_ASSOC);
                    if ($addrRow) {
                        $parts = array_filter([$addrRow['address'] ?? '', $addrRow['city'] ?? '', $addrRow['state'] ?? '', $addrRow['pin_code'] ?? '']);
                        $addrLine = implode(', ', $parts);
                    }
                } catch (\Throwable $e) {}

                // Session labels
                $fromLabel = $subjectsData['from_label'] ?? '';
                $toLabel   = $subjectsData['to_label'] ?? '';
                if (empty($fromLabel) || empty($toLabel)) {
                    $admissionDate = $doc['admission_date'] ?? null;
                    $courseDuration = $doc['duration'] ?? '6 Months';
                    if ($admissionDate) {
                        $fromDt = \DateTime::createFromFormat('Y-m-d', $admissionDate);
                        if ($fromDt) {
                            if (empty($fromLabel)) $fromLabel = strtoupper($fromDt->format('M Y'));
                            if (empty($toLabel)) {
                                $toDt = clone $fromDt;
                                $monthsToAdd = 0;
                                if (preg_match('/^([\d.]+)\s*month/i', $courseDuration, $m)) {
                                    $monthsToAdd = max(0, (int)round((float)$m[1]) - 1);
                                } elseif (preg_match('/^([\d.]+)\s*year/i', $courseDuration, $m)) {
                                    $monthsToAdd = max(0, (int)round((float)$m[1] * 12) - 1);
                                }
                                $toDt->modify("+{$monthsToAdd} months");
                                $toLabel = strtoupper($toDt->format('M Y'));
                            }
                        }
                    }
                }
                if (empty($fromLabel) && !empty($doc['session_from'])) {
                    $dt = \DateTime::createFromFormat('Y-m-d', $doc['session_from']);
                    if ($dt) $fromLabel = strtoupper($dt->format('M Y'));
                }
                if (empty($toLabel) && !empty($doc['session_to'])) {
                    $dt = \DateTime::createFromFormat('Y-m-d', $doc['session_to']);
                    if ($dt) $toLabel = strtoupper($dt->format('M Y'));
                }

                // Student data array
                $studentData = [
                    'student_name'    => $doc['student_name'] ?? '',
                    'father_name'     => $doc['father_name'] ?? '',
                    'mother_name'     => $doc['mother_name'] ?? '',
                    'enrollment_no'   => $doc['enrollment_no'] ?? '',
                    'certificate_no'  => $doc['certificate_no'] ?? '',
                    'percentage'      => ($doc['percentage'] ?? 0) . '%',
                    'grade'           => $doc['grade'] ?? '',
                    'division'        => $division,
                    'branch_name'     => $doc['branch_name'] ?? '',
                    'branch_code'     => $doc['branch_code'] ?? '',
                    'course'          => $doc['course_name'] ?? '',
                    'duration'        => $doc['duration'] ?? '',
                    'date_of_issue'   => !empty($doc['issue_date']) ? date('d/m/Y', strtotime($doc['issue_date'])) : date('d/m/Y'),
                    'from_date'       => $fromLabel,
                    'to_date'         => $toLabel,
                    'verification_url'=> $doc['verification_url'] ?? '',
                    'qr_code'         => $doc['verification_url'] ?? '',
                    'qr_data'         => $doc['verification_url'] ?? $doc['certificate_no'] ?? '',
                    'institute_name'  => 'Gmind Institute',
                    'photo'           => $photoPath,
                    'address'         => $addrLine,
                    'subjects'        => $subjects,
                ];

                // Resolve background path
                $resolvedBg = $this->resolveBackgroundPath($bgPath);
                if (!$resolvedBg) continue;

                // Generate page — use addPatternPage if PDF already exists, otherwise create new
                if ($pdf === null) {
                    $pdf = $generator->generateFromPattern([
                        'pattern'    => $pattern,
                        'fields'     => $fields,
                        'student'    => $studentData,
                        'doc_type'   => $docType,
                        'bg_path'    => $resolvedBg,
                        'is_preview' => false,
                    ]);
                } else {
                    // Add another page to existing PDF
                    $generator->addPatternPage($pdf, [
                        'pattern'    => $pattern,
                        'fields'     => $fields,
                        'student'    => $studentData,
                        'doc_type'   => $docType,
                        'bg_path'    => $resolvedBg,
                        'is_preview' => false,
                    ]);
                }
            }

            if ($pdf === null) {
                flash('error', '❌ Could not generate PDF. Ensure patterns are assigned and backgrounds uploaded.');
                redirect(BASE_PATH . '/branch/print-queue');
            }

            // Output combined PDF
            $filename = 'Bulk_Print_' . count($documents) . '_docs_' . date('Y-m-d') . '.pdf';
            header('Content-Type: application/pdf');
            header('Content-Disposition: attachment; filename="' . $filename . '"');
            header('Cache-Control: private, max-age=0, must-revalidate');
            while (ob_get_level()) ob_end_clean();
            $pdf->Output('D', $filename);
            exit;

        } catch (\Throwable $e) {
            error_log('Bulk print error: ' . $e->getMessage() . "\n" . $e->getTraceAsString());
            flash('error', '❌ Bulk PDF generation failed: ' . $e->getMessage());
            redirect(BASE_PATH . '/branch/print-queue');
        }
    }

    /**
     * Resolve background image path (try multiple locations).
     */
    private function resolveBackgroundPath(string $bgPath): ?string
    {
        if (empty($bgPath)) return null;
        if ($bgPath[0] === '/' && file_exists($bgPath)) return realpath($bgPath);

        $candidates = [
            $_SERVER['DOCUMENT_ROOT'] . '/' . ltrim($bgPath, '/'),
            $_SERVER['DOCUMENT_ROOT'] . '/gmind/' . ltrim($bgPath, '/'),
            '/home/advaysin/public_html/' . ltrim($bgPath, '/'),
            '/home/advaysin/public_html/gmind/' . ltrim($bgPath, '/'),
            dirname(dirname(dirname(__DIR__))) . '/' . ltrim($bgPath, '/'),
        ];
        foreach ($candidates as $c) {
            if (file_exists($c)) return realpath($c);
        }
        return null;
    }
}
