<?php
/**
 * Branch Result Edit/Delete Controller — NEW
 * 
 * Upload to: /gmind/branch/Controllers/BranchResultEditController.php
 * 
 * Features:
 *   - Edit result (marks, completion month, payment, etc.)
 *   - Delete result (with confirmation)
 *   - Both work for pending AND approved certificates
 *   - Branch admin can only edit/delete their own branch's certificates
 */

namespace BranchAdmin\Controllers;

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

class BranchResultEditController extends BranchBaseController
{
    /**
     * Show edit form for a certificate
     */
    public function edit(?int $id = null): void
    {
        requireBranchAdmin();
        $branchId = $this->getBranchId();

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

        // Load certificate (ensure it belongs to this branch)
        $stmt = $this->db->prepare(
            "SELECT c.*,
                    COALESCE(c.student_name, u.name, 'Unknown') AS student_name,
                    s.enrollment_no, s.father_name,
                    COALESCE(c.course_name, cs.name, '—') AS course_name,
                    cs.duration, cs.subjects AS course_subjects,
                    t.name AS template_name, t.type AS doc_type
             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
             WHERE c.id = :id AND c.branch_id = :bid LIMIT 1"
        );
        $stmt->execute([':id' => $id, ':bid' => $branchId]);
        $doc = $stmt->fetch() ?: null;

        if (!$doc) {
            flash('error', 'Document not found or access denied.');
            redirect(BASE_PATH . '/branch/cert-gen');
        }

        // Parse subjects JSON
        $subjectsData = [];
        if (!empty($doc['subjects_json'])) {
            $subjectsData = json_decode($doc['subjects_json'], true) ?: [];
        }

        // Build subjects array for the form
        $subjects = [];
        if (!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],
                    'max_marks' => $maxList[$i] ?? 100,
                    'obtained'  => $obtList[$i] ?? 0,
                ];
            }
        }
        // Fallback to course subjects
        if (empty($subjects) && !empty($doc['course_subjects'])) {
            $courseSubjs = json_decode($doc['course_subjects'], true);
            if (is_array($courseSubjs)) {
                foreach ($courseSubjs as $s) {
                    $subjects[] = [
                        'name'      => $s['name'] ?? 'Subject',
                        'max_marks' => $s['max_marks'] ?? 100,
                        'obtained'  => 0,
                    ];
                }
            }
        }
        if (empty($subjects)) {
            $subjects = [
                ['name' => 'Theory', 'max_marks' => 100, 'obtained' => 0],
                ['name' => 'Practical', 'max_marks' => 100, 'obtained' => 0],
            ];
        }

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

        // Completion month (from session_to)
        $completionMonth = '';
        if (!empty($doc['session_to'])) {
            $dt = \DateTime::createFromFormat('Y-m-d', $doc['session_to']);
            if ($dt) $completionMonth = $dt->format('Y-m');
        }

        $this->branchAdminView('cert_gen/edit_result', [
            'title'           => 'Edit Result: ' . ($doc['student_name'] ?? ''),
            'currentPage'     => 'cert_gen',
            'doc'             => $doc,
            'subjects'        => $subjects,
            'months'          => $months,
            'completionMonth' => $completionMonth,
            'subjectsData'    => $subjectsData,
        ]);
    }

    /**
     * Update result
     */
    public function update(?int $id = null): void
    {
        requireBranchAdmin();
        $this->validateCsrf();
        $branchId = $this->getBranchId();

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

        // Load certificate
        $stmt = $this->db->prepare(
            "SELECT c.*, cs.duration, cs.cert_pattern_id, cs.marksheet_pattern_id
             FROM certificates c
             LEFT JOIN courses cs ON c.course_id = cs.id
             WHERE c.id = :id AND c.branch_id = :bid LIMIT 1"
        );
        $stmt->execute([':id' => $id, ':bid' => $branchId]);
        $doc = $stmt->fetch() ?: null;

        if (!$doc) {
            flash('error', 'Document not found or access denied.');
            redirect(BASE_PATH . '/branch/cert-gen');
        }

        // Read POST data
        $studentName     = trim($_POST['student_name'] ?? '');
        $fatherName      = trim($_POST['father_name'] ?? '');
        $subjectNames    = $_POST['subject_name'] ?? [];
        $maxMarks        = $_POST['max_marks'] ?? [];
        $obtMarks        = $_POST['obtained_marks'] ?? [];

        // Calculate totals
        $totalMax = 0; $totalObt = 0;
        for ($i = 0; $i < count($subjectNames); $i++) {
            $m = (float)($maxMarks[$i] ?? 100);
            $o = (float)($obtMarks[$i] ?? 0);
            if ($o > $m) $o = $m;
            $totalMax += $m;
            $totalObt += $o;
        }
        $percentage = $totalMax > 0 ? round(($totalObt / $totalMax) * 100, 2) : 0;
        $grade = $this->calculateGrade($percentage);
        $division = $this->calculateDivision($percentage);

        // Get existing subjects JSON to preserve session dates
        $subjectsData = [];
        if (!empty($doc['subjects_json'])) {
            $subjectsData = json_decode($doc['subjects_json'], true) ?: [];
        }

        // Build new subjects JSON (keep old session labels)
        $subjectsJson = json_encode([
            'subjects'       => $subjectNames,
            'max_marks'      => $maxMarks,
            'obtained_marks' => $obtMarks,
            'from_label'     => $subjectsData['from_label'] ?? '',
            'to_label'       => $subjectsData['to_label'] ?? '',
        ]);

        try {
            // ✅ FIX: If document was already 'generated' (approved), keep it generated
            // Only set to 'pending_approval' if it was NOT already approved
            $currentStatus = $doc['status'] ?? 'pending_approval';
            $newStatus = ($currentStatus === 'generated') ? 'generated' : 'pending_approval';

            // If approved, keep old PDF path; if pending, clear it
            $pdfPathValue = ($newStatus === 'generated') ? $doc['pdf_path'] : null;

            // Update certificate record
            $stmt = $this->db->prepare(
                "UPDATE certificates SET
                    student_name = :sname,
                    grade = :grade,
                    percentage = :pct,
                    division = :div,
                    subjects_json = :sj,
                    pdf_path = :pdf,
                    status = :status,
                    updated_at = NOW()
                 WHERE id = :id"
            );
            $stmt->execute([
                ':sname'  => $studentName,
                ':grade'  => $grade,
                ':pct'    => $percentage,
                ':div'    => $division,
                ':sj'     => $subjectsJson,
                ':pdf'    => $pdfPathValue,
                ':status' => $newStatus,
                ':id'     => $id,
            ]);

            // Update father name in students table
            if (!empty($doc['student_id']) && !empty($fatherName)) {
                $stmt = $this->db->prepare("UPDATE students SET father_name = :fn WHERE id = :sid");
                $stmt->execute([':fn' => $fatherName, ':sid' => $doc['student_id']]);
            }

            // Timeline entry
            $this->db->prepare(
                "INSERT INTO certificate_timeline (certificate_id, event, description, created_at)
                 VALUES (:cid, 'edited', :desc, NOW())"
            )->execute([
                ':cid'  => $id,
                ':desc' => "Result edited by branch admin. New: {$grade} ({$percentage}%)",
            ]);

            $this->auditLog('certificate_edit', 'certificates', $id, "Edited certificate #{$doc['certificate_no']}");

            flash('success', "✅ Result updated successfully! Status reset to 'pending_approval'. Super Admin needs to re-approve.");
            redirect(BASE_PATH . '/branch/cert-gen');

        } catch (\Throwable $e) {
            error_log('BranchResultEdit update error: ' . $e->getMessage());
            flash('error', 'Error updating result: ' . $e->getMessage());
            redirect(BASE_PATH . '/branch/cert-gen/edit/' . $id);
        }
    }

    /**
     * Delete a certificate (with confirmation)
     */
    public function delete(?int $id = null): void
    {
        requireBranchAdmin();
        $this->validateCsrf();
        $branchId = $this->getBranchId();

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

        // Load certificate
        $stmt = $this->db->prepare(
            "SELECT * FROM certificates WHERE id = :id AND branch_id = :bid LIMIT 1"
        );
        $stmt->execute([':id' => $id, ':bid' => $branchId]);
        $doc = $stmt->fetch() ?: null;

        if (!$doc) {
            flash('error', 'Document not found or access denied.');
            redirect(BASE_PATH . '/branch/cert-gen');
        }

        // Check if certificate is approved — if so, restrict deletion
        if ($doc['status'] === 'generated' && !empty($doc['pdf_path'])) {
            // Allow deletion but warn
            $pdfPath = $doc['pdf_path'];
            // Try to delete the PDF file
            $candidates = [
                $_SERVER['DOCUMENT_ROOT'] . $pdfPath,
                $_SERVER['DOCUMENT_ROOT'] . '/' . ltrim($pdfPath, '/'),
                '/home/advaysin/public_html' . $pdfPath,
                '/home/advaysin/public_html/gmind' . $pdfPath,
            ];
            if ($pdfPath[0] !== '/') {
                $candidates[] = $_SERVER['DOCUMENT_ROOT'] . '/' . $pdfPath;
                $candidates[] = '/home/advaysin/public_html/' . $pdfPath;
                $candidates[] = '/home/advaysin/public_html/gmind/' . $pdfPath;
            }
            foreach ($candidates as $c) {
                if (file_exists($c)) {
                    @unlink($c);
                    break;
                }
            }
        }

        try {
            // Delete timeline entries
            $this->db->prepare("DELETE FROM certificate_timeline WHERE certificate_id = :cid")
                ->execute([':cid' => $id]);

            // Delete certificate
            $this->db->prepare("DELETE FROM certificates WHERE id = :id AND branch_id = :bid")
                ->execute([':id' => $id, ':bid' => $branchId]);

            $this->auditLog('certificate_delete', 'certificates', $id, "Deleted certificate #{$doc['certificate_no']}");

            flash('success', "✅ Certificate #{$doc['certificate_no']} deleted successfully.");
        } catch (\Throwable $e) {
            error_log('BranchResultEdit delete error: ' . $e->getMessage());
            flash('error', 'Error deleting certificate: ' . $e->getMessage());
        }

        redirect(BASE_PATH . '/branch/cert-gen');
    }

    /**
     * Confirm delete page
     */
    public function confirmDelete(?int $id = null): void
    {
        requireBranchAdmin();
        $branchId = $this->getBranchId();

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

        $stmt = $this->db->prepare(
            "SELECT c.*,
                    COALESCE(c.student_name, u.name, 'Unknown') AS student_name,
                    s.enrollment_no,
                    COALESCE(c.course_name, cs.name, '—') AS course_name
             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
             WHERE c.id = :id AND c.branch_id = :bid LIMIT 1"
        );
        $stmt->execute([':id' => $id, ':bid' => $branchId]);
        $doc = $stmt->fetch() ?: null;

        if (!$doc) {
            flash('error', 'Document not found.');
            redirect(BASE_PATH . '/branch/cert-gen');
        }

        $this->branchAdminView('cert_gen/confirm_delete', [
            'title'       => 'Confirm Delete',
            'currentPage' => 'cert_gen',
            'doc'         => $doc,
        ]);
    }

    // ─── Private Helpers ────────────────────────────────────────────────────

    private function calculateGrade(float $pct): string
    {
        if ($pct >= 90) return 'A+';
        if ($pct >= 80) return 'A';
        if ($pct >= 70) return 'B+';
        if ($pct >= 60) return 'B';
        if ($pct >= 45) return 'C';
        if ($pct >= 33) return 'D';
        return 'F';
    }

    private function calculateDivision(float $pct): string
    {
        if ($pct >= 60) return 'First Division';
        if ($pct >= 45) return 'Second Division';
        if ($pct >= 33) return 'Third Division';
        return 'Fail';
    }

    private function parseDurationMonths(string $duration): int
    {
        $duration = trim($duration);
        if (preg_match('/^([\d.]+)\s*month/i', $duration, $m)) {
            return (int)round((float)$m[1]);
        }
        if (preg_match('/^([\d.]+)\s*year/i', $duration, $m)) {
            return (int)round((float)$m[1] * 12);
        }
        if (preg_match('/^([\d.]+)\s*week/i', $duration, $m)) {
            return (int)round((float)$m[1] / 4);
        }
        if (preg_match('/^([\d.]+)\s*day/i', $duration, $m)) {
            return (int)round((float)$m[1] / 30);
        }
        return 6;
    }
}
