<?php

declare(strict_types=1);

namespace SuperAdmin\Controllers;

/**
 * Super Admin Branch Admin Controller
 *
 * CRUD for users where role='branch_admin'. Super Admin can:
 *   - List all branch admin accounts
 *   - Create new branch admin (assign to a branch, set password)
 *   - Edit branch admin (change name, email, phone, password, status, branch)
 *   - Delete branch admin (hard delete from users table — but only if no
 *     students/certificates/etc are linked to prevent orphaning data)
 */
class SuperAdminBranchAdminController extends SuperAdminBaseController
{
    /**
     * List all branch admin users.
     */
    public function index(): void
    {
        requireSuperAdmin();

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

        $sql = "SELECT u.*, b.`name` AS branch_name, b.`branch_code`,
                    (SELECT COUNT(*) FROM `students` s WHERE s.`branch_id` = u.`branch_id`) AS student_count
                FROM `users` u
                LEFT JOIN `branches` b ON u.`branch_id` = b.`id`
                WHERE u.`role` = 'branch_admin'";
        $params = [];

        if ($search !== '') {
            $sql .= " AND (u.`name` LIKE :s1 OR u.`email` LIKE :s2 OR u.`phone` LIKE :s3 OR b.`branch_code` LIKE :s4 OR b.`name` LIKE :s5)";
            $params[':s1'] = "%{$search}%";
            $params[':s2'] = "%{$search}%";
            $params[':s3'] = "%{$search}%";
            $params[':s4'] = "%{$search}%";
            $params[':s5'] = "%{$search}%";
        }
        if ($statusFilter !== '' && in_array($statusFilter, ['active','inactive','suspended'], true)) {
            $sql .= " AND u.`status` = :status";
            $params[':status'] = $statusFilter;
        }
        $sql .= " ORDER BY u.`created_at` DESC";

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

        $this->superAdminView('branch_admins/index', [
            'title'        => 'Branch Admins',
            'currentPage'  => 'branch_admins',
            'admins'       => $admins,
            'search'       => $search,
            'statusFilter' => $statusFilter,
        ]);
    }

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

        // Fetch all branches for dropdown
        $branches = [];
        try {
            $stmt = $this->db->query("SELECT `id`, `name`, `branch_code`, `city`, `state` FROM `branches` WHERE `status` IN ('active','pending') ORDER BY `branch_code` ASC");
            $branches = $stmt->fetchAll() ?: [];
        } catch (\Throwable $e) {}

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

    /**
     * Store a new branch admin user.
     */
    public function store(): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        $name      = trim($_POST['name'] ?? '');
        $email     = trim($_POST['email'] ?? '');
        $phone     = trim($_POST['phone'] ?? '') ?: null;
        $password  = $_POST['password'] ?? '';
        $branchId  = (int) ($_POST['branch_id'] ?? 0);
        $status    = trim($_POST['status'] ?? 'active');

        if (empty($name) || empty($email) || empty($password) || $branchId <= 0) {
            flash('error', 'Please fill in all required fields: Name, Email, Password, Branch.');
            redirect(BASE_PATH . '/super-admin/branch-admins/create');
        }

        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            flash('error', 'Please enter a valid email address.');
            redirect(BASE_PATH . '/super-admin/branch-admins/create');
        }

        if (strlen($password) < 6) {
            flash('error', 'Password must be at least 6 characters.');
            redirect(BASE_PATH . '/super-admin/branch-admins/create');
        }

        // Check email uniqueness
        $stmt = $this->db->prepare("SELECT id FROM `users` WHERE `email` = :email LIMIT 1");
        $stmt->execute([':email' => $email]);
        if ($stmt->fetch()) {
            flash('error', "A user with email '{$email}' already exists.");
            redirect(BASE_PATH . '/super-admin/branch-admins/create');
        }

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

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

        try {
            $hashedPassword = password_hash($password, 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,
                     :active, :status, NOW(), NOW())"
            );
            $stmt->execute([
                ':name'     => $name,
                ':email'    => $email,
                ':password' => $hashedPassword,
                ':phone'    => $phone,
                ':bid'      => $branchId,
                ':bcode'    => $branch['branch_code'],
                ':active'   => $status === 'active' ? 1 : 0,
                ':status'   => $status,
            ]);
            $userId = (int) $this->db->lastInsertId();

            // Link this user as the branch's admin_user_id (if branch doesn't already have one)
            $stmt = $this->db->prepare("UPDATE `branches` SET `admin_user_id` = :uid WHERE `id` = :bid AND (`admin_user_id` IS NULL OR `admin_user_id` = 0)");
            $stmt->execute([':uid' => $userId, ':bid' => $branchId]);

            $this->auditLog('branch_admin_create', 'user', $userId, "Created branch_admin '{$email}' for branch {$branch['branch_code']}");
            flash('success', "Branch admin '{$name}' created successfully. Login: {$email}");
        } catch (\Throwable $e) {
            error_log('SuperAdmin branch_admin store error: ' . $e->getMessage());
            flash('error', 'Failed to create branch admin: ' . $e->getMessage());
        }
        redirect(BASE_PATH . '/super-admin/branch-admins');
    }

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

        $stmt = $this->db->prepare(
            "SELECT u.*, b.`name` AS branch_name, b.`branch_code` AS current_branch_code
             FROM `users` u
             LEFT JOIN `branches` b ON u.`branch_id` = b.`id`
             WHERE u.`id` = :id AND u.`role` = 'branch_admin' LIMIT 1"
        );
        $stmt->execute([':id' => $id]);
        $admin = $stmt->fetch() ?: null;

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

        $branches = [];
        try {
            $stmt = $this->db->query("SELECT `id`, `name`, `branch_code`, `city` FROM `branches` WHERE `status` IN ('active','pending') ORDER BY `branch_code` ASC");
            $branches = $stmt->fetchAll() ?: [];
        } catch (\Throwable $e) {}

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

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

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

        $name     = trim($_POST['name'] ?? '');
        $email    = trim($_POST['email'] ?? '');
        $phone    = trim($_POST['phone'] ?? '') ?: null;
        $password = $_POST['password'] ?? '';
        $branchId = (int) ($_POST['branch_id'] ?? 0);
        $status   = trim($_POST['status'] ?? $admin['status']);

        if (empty($name) || empty($email) || $branchId <= 0) {
            flash('error', 'Name, Email, and Branch are required.');
            redirect(BASE_PATH . '/super-admin/branch-admins/' . $id . '/edit');
        }

        // Check email uniqueness (excluding self)
        $stmt = $this->db->prepare("SELECT id FROM `users` WHERE `email` = :email AND `id` != :id LIMIT 1");
        $stmt->execute([':email' => $email, ':id' => $id]);
        if ($stmt->fetch()) {
            flash('error', "Email '{$email}' is already in use by another user.");
            redirect(BASE_PATH . '/super-admin/branch-admins/' . $id . '/edit');
        }

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

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

        try {
            if (!empty($password)) {
                if (strlen($password) < 6) {
                    flash('error', 'Password must be at least 6 characters.');
                    redirect(BASE_PATH . '/super-admin/branch-admins/' . $id . '/edit');
                }
                $hashed = password_hash($password, PASSWORD_DEFAULT);
                $stmt = $this->db->prepare(
                    "UPDATE `users` SET `name`=:name, `email`=:email, `phone`=:phone, `password`=:pwd,
                     `branch_id`=:bid, `branch_code`=:bcode, `is_active`=:active, `status`=:status, `updated_at`=NOW()
                     WHERE `id`=:id"
                );
                $stmt->execute([
                    ':name'=>$name, ':email'=>$email, ':phone'=>$phone, ':pwd'=>$hashed,
                    ':bid'=>$branchId, ':bcode'=>$branch['branch_code'],
                    ':active'=>$status==='active'?1:0, ':status'=>$status, ':id'=>$id,
                ]);
            } else {
                $stmt = $this->db->prepare(
                    "UPDATE `users` SET `name`=:name, `email`=:email, `phone`=:phone,
                     `branch_id`=:bid, `branch_code`=:bcode, `is_active`=:active, `status`=:status, `updated_at`=NOW()
                     WHERE `id`=:id"
                );
                $stmt->execute([
                    ':name'=>$name, ':email'=>$email, ':phone'=>$phone,
                    ':bid'=>$branchId, ':bcode'=>$branch['branch_code'],
                    ':active'=>$status==='active'?1:0, ':status'=>$status, ':id'=>$id,
                ]);
            }

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

    /**
     * Delete a branch admin.
     * Soft-delete — set status='suspended' + is_active=0 (preserves audit trail).
     */
    public function delete(int $id): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        try {
            $stmt = $this->db->prepare(
                "UPDATE `users` SET `status`='suspended', `is_active`=0, `updated_at`=NOW()
                 WHERE `id`=:id AND `role`='branch_admin'"
            );
            $stmt->execute([':id' => $id]);

            $this->auditLog('branch_admin_delete', 'user', $id, "Suspended branch_admin id={$id}");
            flash('success', 'Branch admin account suspended. (Data preserved — set status back to active to restore.)');
        } catch (\Throwable $e) {
            flash('error', 'Failed to suspend branch admin: ' . $e->getMessage());
        }
        redirect(BASE_PATH . '/super-admin/branch-admins');
    }
}
