<?php

declare(strict_types=1);

namespace SuperAdmin\Controllers;

/**
 * Super Admin Branch Controller
 *
 * CRUD operations for branches. Super Admin can:
 *   - List all branches (with filters: status, city, search)
 *   - View branch details (single branch dashboard)
 *   - Create new branch (auto-generates branch_code if blank)
 *   - Edit branch (name, owner, contact, wallet_balance, referral_code, status)
 *   - Delete branch (soft delete — sets status='suspended')
 *   - Auto-create linked branch_admin user when creating a branch
 */
class SuperAdminBranchController extends SuperAdminBaseController
{
    /**
     * List all branches with filters.
     */
    public function index(): void
    {
        requireSuperAdmin();

        $statusFilter = trim($_GET['status'] ?? '');
        $cityFilter   = trim($_GET['city'] ?? '');
        $search       = trim($_GET['search'] ?? '');

        $sql = "SELECT b.*,
                    u.`name` AS admin_name, u.`email` AS admin_email, u.`status` AS admin_status,
                    (SELECT COUNT(*) FROM `students` s WHERE s.`branch_id` = b.`id`) AS student_count,
                    (SELECT COUNT(*) FROM `certificates` c WHERE c.`branch_id` = b.`id`) AS certificate_count
                FROM `branches` b
                LEFT JOIN `users` u ON b.`admin_user_id` = u.`id`
                WHERE 1=1";
        $params = [];

        if ($statusFilter !== '' && in_array($statusFilter, ['active','pending','inactive','suspended'], true)) {
            $sql .= " AND b.`status` = :status";
            $params[':status'] = $statusFilter;
        }
        if ($cityFilter !== '') {
            $sql .= " AND b.`city` LIKE :city";
            $params[':city'] = "%{$cityFilter}%";
        }
        if ($search !== '') {
            $sql .= " AND (b.`name` LIKE :search OR b.`branch_code` LIKE :search2
                     OR b.`owner_name` LIKE :search3 OR b.`owner_email` LIKE :search4
                     OR b.`phone` LIKE :search5)";
            $params[':search']  = "%{$search}%";
            $params[':search2'] = "%{$search}%";
            $params[':search3'] = "%{$search}%";
            $params[':search4'] = "%{$search}%";
            $params[':search5'] = "%{$search}%";
        }
        $sql .= " ORDER BY b.`status` = 'active' DESC, b.`created_at` DESC";

        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        $branches = $stmt->fetchAll() ?: [];

        $this->superAdminView('branches/index', [
            'title'        => 'Manage Branches',
            'currentPage'  => 'branches',
            'branches'     => $branches,
            'statusFilter' => $statusFilter,
            'cityFilter'   => $cityFilter,
            'search'       => $search,
        ]);
    }

    /**
     * Show branch details page (single-branch overview).
     */
    public function show(int $id): void
    {
        requireSuperAdmin();

        $stmt = $this->db->prepare(
            "SELECT b.*, u.`name` AS admin_name, u.`email` AS admin_email, u.`phone` AS admin_phone,
                    u.`status` AS admin_status, u.`created_at` AS admin_created_at,
                    ref.`name` AS referred_by_name, ref.`branch_code` AS referred_by_code
             FROM `branches` b
             LEFT JOIN `users` u ON b.`admin_user_id` = u.`id`
             LEFT JOIN `branches` ref ON b.`referred_by` = ref.`id`
             WHERE b.`id` = :id LIMIT 1"
        );
        $stmt->execute([':id' => $id]);
        $branch = $stmt->fetch() ?: null;

        if (!$branch) {
            flash('error', 'Branch not found.');
            redirect(BASE_PATH . '/super-admin/branches');
        }

        // Stats for this branch
        $stats = ['students' => 0, 'certificates' => 0, 'fee_collected' => 0.00, 'exams' => 0];
        try {
            $stmt = $this->db->prepare("SELECT COUNT(*) AS c FROM `students` WHERE `branch_id` = :bid");
            $stmt->execute([':bid' => $id]);
            $stats['students'] = (int) ($stmt->fetch()['c'] ?? 0);
        } catch (\Throwable $e) {}
        try {
            $stmt = $this->db->prepare("SELECT COUNT(*) AS c FROM `certificates` WHERE `branch_id` = :bid");
            $stmt->execute([':bid' => $id]);
            $stats['certificates'] = (int) ($stmt->fetch()['c'] ?? 0);
        } catch (\Throwable $e) {}
        try {
            $stmt = $this->db->prepare("SELECT COALESCE(SUM(`amount`),0) AS t FROM `fee_payments` WHERE `branch_id` = :bid");
            $stmt->execute([':bid' => $id]);
            $stats['fee_collected'] = (float) ($stmt->fetch()['t'] ?? 0);
        } catch (\Throwable $e) {}
        try {
            $stmt = $this->db->prepare("SELECT COUNT(*) AS c FROM `exams` WHERE `branch_id` = :bid");
            $stmt->execute([':bid' => $id]);
            $stats['exams'] = (int) ($stmt->fetch()['c'] ?? 0);
        } catch (\Throwable $e) {}

        $this->superAdminView('branches/show', [
            'title'       => 'Branch: ' . ($branch['name'] ?? 'Details'),
            'currentPage' => 'branches',
            'branch'      => $branch,
            'stats'       => $stats,
        ]);
    }

    /**
     * Show create branch form.
     */
    public function create(): void
    {
        requireSuperAdmin();

        // Fetch franchise plans for dropdown
        $plans = [];
        try {
            $stmt = $this->db->query("SELECT * FROM `franchise_plans` WHERE `is_active` = 1 ORDER BY `price` ASC");
            $plans = $stmt->fetchAll() ?: [];
        } catch (\Throwable $e) {}

        // Generate next branch_code suggestion (GMBRxx)
        $nextCode = $this->generateNextBranchCode();

        $this->superAdminView('branches/create', [
            'title'       => 'Add New Branch',
            'currentPage' => 'branches',
            'plans'       => $plans,
            'nextCode'    => $nextCode,
        ]);
    }

    /**
     * Store a new branch + auto-create linked branch_admin user.
     */
    public function store(): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        $name           = trim($_POST['name'] ?? '');
        $branchCode     = strtoupper(trim($_POST['branch_code'] ?? ''));
        $city           = trim($_POST['city'] ?? '');
        $state          = trim($_POST['state'] ?? '');
        $pincode        = trim($_POST['pincode'] ?? '') ?: null;
        $address        = trim($_POST['address'] ?? '');
        $phone          = trim($_POST['phone'] ?? '') ?: null;
        $ownerName      = trim($_POST['owner_name'] ?? '') ?: null;
        $ownerPhone     = trim($_POST['owner_phone'] ?? '') ?: null;
        $ownerEmail     = trim($_POST['owner_email'] ?? '') ?: null;
        $planId         = (int) ($_POST['plan_id'] ?? 0) ?: null;
        $walletBalance  = (float) ($_POST['wallet_balance'] ?? 0);
        $status         = trim($_POST['status'] ?? 'pending');
        $adminName      = trim($_POST['admin_name'] ?? '');
        $adminEmail     = trim($_POST['admin_email'] ?? '');
        $adminPassword  = $_POST['admin_password'] ?? '';
        $adminPhone     = trim($_POST['admin_phone'] ?? '') ?: null;

        if (empty($name) || empty($city) || empty($state) || empty($address)) {
            flash('error', 'Please fill in all required fields: Name, City, State, Address.');
            redirect(BASE_PATH . '/super-admin/branches/create');
        }

        // Auto-generate branch_code if blank
        if (empty($branchCode)) {
            $branchCode = $this->generateNextBranchCode();
        }

        // Check branch_code uniqueness
        $stmt = $this->db->prepare("SELECT id FROM `branches` WHERE `branch_code` = :bc LIMIT 1");
        $stmt->execute([':bc' => $branchCode]);
        if ($stmt->fetch()) {
            flash('error', "Branch code '{$branchCode}' is already in use. Please choose a different code.");
            redirect(BASE_PATH . '/super-admin/branches/create');
        }

        // If admin email provided, check uniqueness in users table
        if (!empty($adminEmail)) {
            $stmt = $this->db->prepare("SELECT id FROM `users` WHERE `email` = :email LIMIT 1");
            $stmt->execute([':email' => $adminEmail]);
            if ($stmt->fetch()) {
                flash('error', "A user with email '{$adminEmail}' already exists.");
                redirect(BASE_PATH . '/super-admin/branches/create');
            }
        }

        // Validate status
        if (!in_array($status, ['pending','active','inactive','suspended'], true)) {
            $status = 'pending';
        }

        try {
            $this->db->beginTransaction();

            // 1. Insert branch
            $referralCode = 'REF-' . $branchCode;
            $isTrustedCreate = isset($_POST['is_trusted']) ? 1 : 0;
            $isVerifiedCreate = isset($_POST['is_verified']) ? 1 : 1;
            $stmt = $this->db->prepare(
                "INSERT INTO `branches`
                    (`name`, `branch_code`, `city`, `state`, `pincode`, `address`, `phone`,
                     `owner_name`, `owner_phone`, `owner_email`, `plan_id`, `wallet_balance`,
                     `referral_code`, `status`, `is_verified`, `is_trusted`, `approved_at`, `approved_by`,
                     `created_at`, `updated_at`)
                 VALUES
                    (:name, :bc, :city, :state, :pincode, :address, :phone,
                     :owner_name, :owner_phone, :owner_email, :plan_id, :wallet,
                     :ref_code, :status, :is_ver, :is_trust, NOW(), :approved_by, NOW(), NOW())"
            );
            $stmt->execute([
                ':name'        => $name,
                ':bc'          => $branchCode,
                ':city'        => $city,
                ':state'       => $state,
                ':pincode'     => $pincode,
                ':address'     => $address,
                ':phone'       => $phone,
                ':owner_name'  => $ownerName,
                ':owner_phone' => $ownerPhone,
                ':owner_email' => $ownerEmail,
                ':plan_id'     => $planId,
                ':wallet'      => $walletBalance,
                ':ref_code'    => $referralCode,
                ':status'      => $status,
                ':is_ver'      => $isVerifiedCreate,
                ':is_trust'    => $isTrustedCreate,
                ':approved_by' => $_SESSION['user_id'] ?? null,
            ]);
            $branchId = (int) $this->db->lastInsertId();

            // 2. If admin credentials provided, create the branch_admin user
            if (!empty($adminEmail) && !empty($adminName) && !empty($adminPassword)) {
                $hashedPassword = password_hash($adminPassword, PASSWORD_DEFAULT);
                $stmt = $this->db->prepare(
                    "INSERT INTO `users`
                        (`name`, `email`, `password`, `role`, `phone`, `branch_id`, `branch_code`,
                         `is_active`, `status`, `created_at`, `updated_at`)
                     VALUES
                        (:name, :email, :password, 'branch_admin', :phone, :bid, :bcode,
                         1, 'active', NOW(), NOW())"
                );
                $stmt->execute([
                    ':name'     => $adminName,
                    ':email'    => $adminEmail,
                    ':password' => $hashedPassword,
                    ':phone'    => $adminPhone,
                    ':bid'      => $branchId,
                    ':bcode'    => $branchCode,
                ]);
                $userId = (int) $this->db->lastInsertId();

                // Link admin_user_id back to branch
                $this->db->prepare("UPDATE `branches` SET `admin_user_id` = :uid WHERE `id` = :bid")
                    ->execute([':uid' => $userId, ':bid' => $branchId]);
            }

            $this->db->commit();

            $this->auditLog('branch_create', 'branch', $branchId, "Created branch '{$name}' ({$branchCode})");

            // ═══════════════════════════════════════════════════════════════════
            // ✅ SEND WELCOME EMAIL TO BRANCH ADMIN (if email provided)
            // ═══════════════════════════════════════════════════════════════════
            $emailSent = false;
            $emailError = '';
            if (!empty($adminEmail)) {
                try {
                    $helper = new \App\Helpers\EmailHelper($this->db);
                    if ($helper->isConfigured()) {
                        $loginUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http') . '://' . ($_SERVER['HTTP_HOST'] ?? 'localhost') . (defined('BASE_PATH') ? BASE_PATH : '/gmind') . '/branch/login';
                        $subject = "Welcome to GMIND Institute — Branch {$branchCode} Activated!";
                        $body = $this->buildBranchWelcomeEmailHtml([
                            'admin_name'    => $adminName ?: $name,
                            'center_name'   => $name,
                            'branch_code'   => $branchCode,
                            'admin_email'   => $adminEmail,
                            'admin_password'=> $adminPassword ?: '123456',
                            'login_url'     => $loginUrl,
                            'owner_name'    => $ownerName ?? '',
                            'owner_phone'   => $ownerPhone ?? '',
                            'state'         => $state ?? '',
                            'city'          => $city ?? '',
                        ]);
                        $emailSent = $helper->send($adminEmail, $adminName ?: $name, $subject, $body);
                        if (!$emailSent) {
                            $emailError = $helper->getLastError();
                        }
                    } else {
                        $emailError = 'SMTP not configured';
                    }
                } catch (\Throwable $e) {
                    $emailError = $e->getMessage();
                    error_log('Branch welcome email exception: ' . $e->getMessage());
                }
            }

            $successMsg = "Branch '{$name}' ({$branchCode}) created successfully."
                . (!empty($adminEmail) ? " Branch admin login: {$adminEmail}" : '');
            if ($emailSent) {
                $successMsg .= " 📧 Welcome email sent to {$adminEmail}.";
            } elseif (!empty($adminEmail)) {
                $successMsg .= " ⚠️ Email not sent ({$emailError}). Share login manually: email={$adminEmail}, password={$adminPassword}.";
            }
            flash('success', $successMsg);
        } catch (\Throwable $e) {
            if ($this->db->inTransaction()) {
                $this->db->rollBack();
            }
            error_log('SuperAdmin Branch store error: ' . $e->getMessage());
            flash('error', 'Failed to create branch: ' . $e->getMessage());
        }
        redirect(BASE_PATH . '/super-admin/branches');
    }

    /**
     * Build HTML email body for branch welcome.
     */
    private function buildBranchWelcomeEmailHtml(array $data): string
    {
        $adminName     = htmlspecialchars($data['admin_name'] ?? '', ENT_QUOTES);
        $centerName    = htmlspecialchars($data['center_name'] ?? '', ENT_QUOTES);
        $branchCode    = htmlspecialchars($data['branch_code'] ?? '', ENT_QUOTES);
        $adminEmail    = htmlspecialchars($data['admin_email'] ?? '', ENT_QUOTES);
        $adminPassword = htmlspecialchars($data['admin_password'] ?? '', ENT_QUOTES);
        $loginUrl      = htmlspecialchars($data['login_url'] ?? '', ENT_QUOTES);
        $ownerName     = htmlspecialchars($data['owner_name'] ?? '', ENT_QUOTES);
        $ownerPhone    = htmlspecialchars($data['owner_phone'] ?? '', ENT_QUOTES);
        $state         = htmlspecialchars($data['state'] ?? '', ENT_QUOTES);
        $city          = htmlspecialchars($data['city'] ?? '', ENT_QUOTES);

        return <<<HTML
<!DOCTYPE html>
<html><head><meta charset="UTF-8"></head>
<body style="margin:0;padding:0;font-family:'Segoe UI',Arial,sans-serif;background:#f3f4f6;">
  <table width="100%" cellpadding="0" cellspacing="0" style="background:#f3f4f6;padding:20px;">
    <tr><td align="center">
      <table width="600" cellpadding="0" cellspacing="0" style="background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,0.06);">
        <tr><td style="background:linear-gradient(135deg,#6c3fe8,#4a2db8);padding:24px 32px;text-align:center;">
          <h1 style="margin:0;color:#fff;font-size:1.6rem;">GMIND INSTITUTE</h1>
          <p style="margin:6px 0 0;color:rgba(255,255,255,0.9);font-size:0.88rem;">Branch Activation Confirmation</p>
        </td></tr>
        <tr><td style="padding:32px;">
          <h2 style="margin:0 0 16px;color:#2c1e4a;font-size:1.3rem;">🎉 Welcome to GMIND Institute Family!</h2>
          <p style="margin:0 0 16px;color:#4b5563;font-size:0.95rem;line-height:1.6;">
            Dear <strong>{$adminName}</strong>,<br><br>
            Congratulations! Your branch has been successfully activated. Below are your branch details and login credentials:
          </p>
          <table width="100%" cellpadding="12" cellspacing="0" style="border:1px solid #e5e7eb;border-radius:8px;margin:16px 0;">
            <tr style="background:#f8f4ff;"><td style="color:#6c3fe8;font-weight:600;font-size:0.85rem;">Center Name</td><td style="color:#2c1e4a;font-weight:700;">{$centerName}</td></tr>
            <tr><td style="color:#6c3fe8;font-weight:600;font-size:0.85rem;border-top:1px solid #e5e7eb;">Branch Code</td><td style="color:#2c1e4a;font-weight:700;font-family:monospace;border-top:1px solid #e5e7eb;">{$branchCode}</td></tr>
            <tr><td style="color:#6c3fe8;font-weight:600;font-size:0.85rem;border-top:1px solid #e5e7eb;">Location</td><td style="color:#2c1e4a;border-top:1px solid #e5e7eb;">{$city}, {$state}</td></tr>
          </table>
          <div style="background:#fef3c7;border-left:4px solid #d97706;padding:14px 18px;border-radius:6px;margin:20px 0;">
            <p style="margin:0 0 8px;color:#b45309;font-weight:700;font-size:0.9rem;">🔐 Your Branch Admin Login Credentials</p>
            <p style="margin:0;color:#92400e;font-size:0.88rem;">
              <strong>Login URL:</strong> <a href="{$loginUrl}" style="color:#2563eb;">{$loginUrl}</a><br>
              <strong>Email:</strong> {$adminEmail}<br>
              <strong>Password:</strong> {$adminPassword}<br>
              <em style="color:#6b7280;font-size:0.8rem;">You can also login using Branch Code: {$branchCode}</em>
            </p>
          </div>
          <p style="margin:16px 0;color:#4b5563;font-size:0.88rem;line-height:1.6;">
            Using your branch admin account, you can:
          </p>
          <ul style="margin:0 0 16px;padding-left:20px;color:#4b5563;font-size:0.85rem;line-height:1.7;">
            <li>Manage student admissions and fee collection</li>
            <li>Generate certificates and marksheets</li>
            <li>Create batches and schedule exams</li>
            <li>Update your branch profile and facilities</li>
            <li>View fee reports and wallet transactions</li>
          </ul>
          <p style="margin:16px 0;color:#4b5563;font-size:0.88rem;line-height:1.6;">
            Please change your password after first login for security.<br><br>
            If you need any assistance, please contact the Super Admin.<br><br>
            Best regards,<br>
            <strong>GMIND Institute Team</strong>
          </p>
        </td></tr>
        <tr><td style="background:#f8f9fa;padding:16px 32px;text-align:center;border-top:1px solid #e5e7eb;">
          <p style="margin:0;color:#9ca3af;font-size:0.75rem;">This is an automated email. Please do not reply.</p>
        </td></tr>
      </table>
    </td></tr>
  </table>
</body></html>
HTML;
    }

    /**
     * Show edit branch form.
     */
    public function edit(int $id): void
    {
        requireSuperAdmin();

        $stmt = $this->db->prepare(
            "SELECT b.*, u.`name` AS admin_name, u.`email` AS admin_email, u.`phone` AS admin_phone,
                    u.`status` AS admin_status
             FROM `branches` b
             LEFT JOIN `users` u ON b.`admin_user_id` = u.`id`
             WHERE b.`id` = :id LIMIT 1"
        );
        $stmt->execute([':id' => $id]);
        $branch = $stmt->fetch() ?: null;

        if (!$branch) {
            flash('error', 'Branch not found.');
            redirect(BASE_PATH . '/super-admin/branches');
        }

        $plans = [];
        try {
            $stmt = $this->db->query("SELECT * FROM `franchise_plans` WHERE `is_active` = 1 ORDER BY `price` ASC");
            $plans = $stmt->fetchAll() ?: [];
        } catch (\Throwable $e) {}

        $this->superAdminView('branches/edit', [
            'title'       => 'Edit Branch: ' . ($branch['name'] ?? ''),
            'currentPage' => 'branches',
            'branch'      => $branch,
            'plans'       => $plans,
        ]);
    }

    /**
     * Update a branch.
     */
    public function update(int $id): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        $stmt = $this->db->prepare("SELECT * FROM `branches` WHERE `id` = :id LIMIT 1");
        $stmt->execute([':id' => $id]);
        $branch = $stmt->fetch() ?: null;
        if (!$branch) {
            flash('error', 'Branch not found.');
            redirect(BASE_PATH . '/super-admin/branches');
        }

        $name           = trim($_POST['name'] ?? '');
        $city           = trim($_POST['city'] ?? '');
        $state          = trim($_POST['state'] ?? '');
        $pincode        = trim($_POST['pincode'] ?? '') ?: null;
        $address        = trim($_POST['address'] ?? '');
        $phone          = trim($_POST['phone'] ?? '') ?: null;
        $ownerName      = trim($_POST['owner_name'] ?? '') ?: null;
        $ownerPhone     = trim($_POST['owner_phone'] ?? '') ?: null;
        $ownerEmail     = trim($_POST['owner_email'] ?? '') ?: null;
        $planId         = (int) ($_POST['plan_id'] ?? 0) ?: null;
        $walletBalance  = (float) ($_POST['wallet_balance'] ?? 0);
        $status         = trim($_POST['status'] ?? $branch['status']);
        $isVerified     = isset($_POST['is_verified']) ? 1 : 0;
        $isTrusted      = isset($_POST['is_trusted']) ? 1 : 0;
        $openingTime    = trim($_POST['opening_time'] ?? '') ?: null;
        $closingTime    = trim($_POST['closing_time'] ?? '') ?: null;
        $mapLink        = trim($_POST['map_link'] ?? '') ?: null;
        $latitude       = $_POST['latitude'] !== '' ? (float) $_POST['latitude'] : null;
        $longitude      = $_POST['longitude'] !== '' ? (float) $_POST['longitude'] : null;

        if (empty($name) || empty($city) || empty($state) || empty($address)) {
            flash('error', 'Please fill in all required fields.');
            redirect(BASE_PATH . '/super-admin/branches/' . $id . '/edit');
        }

        if (!in_array($status, ['pending','active','inactive','suspended'], true)) {
            $status = $branch['status'];
        }

        try {
            $stmt = $this->db->prepare(
                "UPDATE `branches` SET
                    `name` = :name, `city` = :city, `state` = :state, `pincode` = :pincode,
                    `address` = :address, `phone` = :phone, `owner_name` = :owner_name,
                    `owner_phone` = :owner_phone, `owner_email` = :owner_email,
                    `plan_id` = :plan_id, `wallet_balance` = :wallet, `status` = :status,
                    `is_verified` = :is_verified, `is_trusted` = :is_trusted, `opening_time` = :opening,
                    `closing_time` = :closing, `map_link` = :map_link,
                    `latitude` = :lat, `longitude` = :lng, `updated_at` = NOW()
                 WHERE `id` = :id"
            );
            $stmt->execute([
                ':name'        => $name,
                ':city'        => $city,
                ':state'       => $state,
                ':pincode'     => $pincode,
                ':address'     => $address,
                ':phone'       => $phone,
                ':owner_name'  => $ownerName,
                ':owner_phone' => $ownerPhone,
                ':owner_email' => $ownerEmail,
                ':plan_id'     => $planId,
                ':wallet'      => $walletBalance,
                ':status'      => $status,
                ':is_verified' => $isVerified,
                ':is_trusted'  => $isTrusted,
                ':opening'     => $openingTime,
                ':closing'     => $closingTime,
                ':map_link'    => $mapLink,
                ':lat'         => $latitude,
                ':lng'         => $longitude,
                ':id'          => $id,
            ]);

            $this->auditLog('branch_update', 'branch', $id, "Updated branch '{$name}'");
            flash('success', 'Branch updated successfully.');
        } catch (\Throwable $e) {
            error_log('SuperAdmin Branch update error: ' . $e->getMessage());
            flash('error', 'Failed to update branch: ' . $e->getMessage());
        }
        redirect(BASE_PATH . '/super-admin/branches');
    }

    /**
     * Soft-delete a branch (set status='suspended').
     * Does NOT actually delete the row — preserves data integrity.
     */
    public function delete(int $id): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        try {
            $this->db->prepare("UPDATE `branches` SET `status` = 'suspended', `active` = 0, `updated_at` = NOW() WHERE `id` = :id")
                ->execute([':id' => $id]);
            $this->auditLog('branch_suspend', 'branch', $id, "Suspended branch id={$id}");
            flash('success', 'Branch suspended successfully. (Data preserved — set status back to active to restore.)');
        } catch (\Throwable $e) {
            flash('error', 'Failed to suspend branch: ' . $e->getMessage());
        }
        redirect(BASE_PATH . '/super-admin/branches');
    }

    /**
     * PERMANENTLY DELETE a branch and all its related data.
     *
     * This is a HARD delete — the branch row is removed from the database.
     * Also cleans up: students, users, certificates, fee_payments, batches,
     * branch_course_settings, branch_wallet_transactions, etc.
     *
     * Use this to remove duplicate branches or branches created by mistake.
     */
    public function hardDelete(int $id): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        // Get branch info before deleting (for audit log)
        $stmt = $this->db->prepare("SELECT * FROM `branches` WHERE `id` = :id LIMIT 1");
        $stmt->execute([':id' => $id]);
        $branch = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$branch) {
            flash('error', 'Branch not found.');
            redirect(BASE_PATH . '/super-admin/branches');
        }

        $branchName = $branch['name'] ?? 'Unknown';
        $branchCode = $branch['branch_code'] ?? '—';

        try {
            $this->db->beginTransaction();

            // 1. Get all student IDs for this branch
            $stmt = $this->db->prepare("SELECT id, user_id FROM `students` WHERE `branch_id` = :bid");
            $stmt->execute([':bid' => $id]);
            $students = $stmt->fetchAll(\PDO::FETCH_ASSOC) ?: [];
            $studentIds = array_column($students, 'id');
            $userIds = array_filter(array_column($students, 'user_id'));

            // 2. Delete fee_payments for these students
            if (!empty($studentIds)) {
                $placeholders = implode(',', array_fill(0, count($studentIds), '?'));
                $this->db->prepare("DELETE FROM `fee_payments` WHERE `student_id` IN ($placeholders)")->execute($studentIds);
            }

            // 3. Delete fee_payments by branch_id (for payments without student)
            try {
                $this->db->prepare("DELETE FROM `fee_payments` WHERE `branch_id` = :bid")->execute([':bid' => $id]);
            } catch (\Throwable $e) {}

            // 4. Delete certificates for these students
            if (!empty($studentIds)) {
                $placeholders = implode(',', array_fill(0, count($studentIds), '?'));
                try {
                    $this->db->prepare("DELETE FROM `certificates` WHERE `student_id` IN ($placeholders)")->execute($studentIds);
                } catch (\Throwable $e) {}
                try {
                    $this->db->prepare("DELETE FROM `certificate_timeline` WHERE `certificate_id` IN (SELECT id FROM `certificates` WHERE `student_id` IN ($placeholders))")->execute($studentIds);
                } catch (\Throwable $e) {}
            }

            // 5. Delete certificates by branch_id
            try {
                $this->db->prepare("DELETE FROM `certificates` WHERE `branch_id` = :bid")->execute([':bid' => $id]);
            } catch (\Throwable $e) {}

            // 6. Delete exam results for these students
            if (!empty($studentIds)) {
                $placeholders = implode(',', array_fill(0, count($studentIds), '?'));
                try {
                    $this->db->prepare("DELETE FROM `exam_results` WHERE `student_id` IN ($placeholders)")->execute($studentIds);
                } catch (\Throwable $e) {}
            }

            // 7. Delete students
            $this->db->prepare("DELETE FROM `students` WHERE `branch_id` = :bid")->execute([':bid' => $id]);

            // 8. Delete student user accounts
            if (!empty($userIds)) {
                $placeholders = implode(',', array_fill(0, count($userIds), '?'));
                try {
                    $this->db->prepare("DELETE FROM `users` WHERE `id` IN ($placeholders)")->execute($userIds);
                } catch (\Throwable $e) {}
            }

            // 9. Delete branch admin user accounts
            try {
                $this->db->prepare("DELETE FROM `users` WHERE `branch_id` = :bid AND `role` = 'branch_admin'")->execute([':bid' => $id]);
            } catch (\Throwable $e) {}

            // 10. Delete batches
            try {
                $this->db->prepare("DELETE FROM `batches` WHERE `branch_id` = :bid")->execute([':bid' => $id]);
            } catch (\Throwable $e) {}

            // 11. Delete branch_course_settings
            try {
                $this->db->prepare("DELETE FROM `branch_course_settings` WHERE `branch_id` = :bid")->execute([':bid' => $id]);
            } catch (\Throwable $e) {}

            // 12. Delete branch_course_fees (old table)
            try {
                $this->db->prepare("DELETE FROM `branch_course_fees` WHERE `branch_id` = :bid")->execute([':bid' => $id]);
            } catch (\Throwable $e) {}

            // 13. Delete branch_wallet_transactions
            try {
                $this->db->prepare("DELETE FROM `branch_wallet_transactions` WHERE `branch_id` = :bid")->execute([':bid' => $id]);
            } catch (\Throwable $e) {}

            // 14. Delete branch_news, facilities, faculty, etc.
            foreach (['branch_news', 'branch_facilities', 'branch_faculty', 'branch_gallery', 'branch_timings'] as $tbl) {
                try {
                    $this->db->prepare("DELETE FROM `$tbl` WHERE `branch_id` = :bid")->execute([':bid' => $id]);
                } catch (\Throwable $e) {}
            }

            // 15. FINALLY delete the branch itself
            $this->db->prepare("DELETE FROM `branches` WHERE `id` = :id")->execute([':id' => $id]);

            $this->db->commit();

            $this->auditLog('branch_hard_delete', 'branch', $id, "PERMANENTLY DELETED branch '{$branchName}' ({$branchCode}) and all related data");
            flash('success', "✅ Branch '{$branchName}' ({$branchCode}) permanently deleted with all related data.");
        } catch (\Throwable $e) {
            try { $this->db->rollBack(); } catch (\Throwable $e2) {}
            error_log('Hard delete branch failed: ' . $e->getMessage());
            flash('error', '❌ Failed to delete branch: ' . $e->getMessage() . ' — Try suspending instead.');
        }
        redirect(BASE_PATH . '/super-admin/branches');
    }

    /**
     * Generate the next sequential branch code (GMBRxx).
     */
    private function generateNextBranchCode(): string
    {
        try {
            $stmt = $this->db->query(
                "SELECT `branch_code` FROM `branches`
                 WHERE `branch_code` LIKE 'GMBR%'
                 ORDER BY CAST(SUBSTRING(`branch_code`, 5) AS UNSIGNED) DESC
                 LIMIT 1"
            );
            $last = $stmt->fetch();
            if ($last && !empty($last['branch_code'])) {
                $num = (int) substr($last['branch_code'], 4);
                return 'GMBR' . str_pad($num + 1, 2, '0', STR_PAD_LEFT);
            }
        } catch (\Throwable $e) {}
        return 'GMBR01';
    }
}
