<?php

declare(strict_types=1);

namespace SuperAdmin\Controllers;

/**
 * Super Admin Branch Application Controller
 *
 * Reviews franchise applications submitted from the public /branch/register form.
 * Super Admin can:
 *   - List all applications (filter by status)
 *   - View application details
 *   - Approve application → auto-create branch + branch_admin user
 *   - Reject application (with reason)
 *   - Delete application
 */
class SuperAdminBranchApplicationController extends SuperAdminBaseController
{
    /**
     * List all branch applications.
     */
    public function index(): void
    {
        requireSuperAdmin();

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

        $sql = "SELECT * FROM `branch_applications` WHERE 1=1";
        $params = [];

        if ($statusFilter !== '' && in_array($statusFilter, ['pending','approved','rejected'], true)) {
            $sql .= " AND `status` = :status";
            $params[':status'] = $statusFilter;
        }
        if ($search !== '') {
            $sql .= " AND (`name` LIKE :s1 OR `email` LIKE :s2 OR `phone` LIKE :s3 OR `city` LIKE :s4)";
            $params[':s1'] = "%{$search}%";
            $params[':s2'] = "%{$search}%";
            $params[':s3'] = "%{$search}%";
            $params[':s4'] = "%{$search}%";
        }
        $sql .= " ORDER BY FIELD(`status`,'pending','approved','rejected'), `created_at` DESC";

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

        $this->superAdminView('branch_applications/index', [
            'title'        => 'Franchise Applications',
            'currentPage'  => 'branch_applications',
            'applications' => $applications,
            'statusFilter' => $statusFilter,
            'search'       => $search,
        ]);
    }

    /**
     * Show application details.
     */
    public function show(int $id): void
    {
        requireSuperAdmin();

        $stmt = $this->db->prepare(
            "SELECT ba.*, u.`name` AS reviewer_name,
                    b.`id` AS created_branch_id, b.`name` AS created_branch_name, b.`branch_code` AS created_branch_code,
                    bu.`email` AS created_admin_email
             FROM `branch_applications` ba
             LEFT JOIN `users` u ON ba.`reviewed_by` = u.`id`
             LEFT JOIN `branches` b ON ba.`email` = (SELECT bu2.`email` FROM `users` bu2 WHERE bu2.`branch_id` = b.`id` AND bu2.`role`='branch_admin' LIMIT 1)
             LEFT JOIN `users` bu ON bu.`branch_id` = b.`id` AND bu.`role` = 'branch_admin'
             WHERE ba.`id` = :id LIMIT 1"
        );
        $stmt->execute([':id' => $id]);
        $application = $stmt->fetch() ?: null;

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

        // Fetch franchise plans for display
        $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 suggested branch_code for approve action
        $nextCode = $this->generateNextBranchCode();

        $this->superAdminView('branch_applications/show', [
            'title'       => 'Application: ' . ($application['name'] ?? ''),
            'currentPage' => 'branch_applications',
            'application' => $application,
            'plans'       => $plans,
            'nextCode'    => $nextCode,
        ]);
    }

    /**
     * Approve an application → auto-create branch + branch_admin user.
     */
    public function approve(int $id): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

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

        if ($app['status'] !== 'pending') {
            flash('error', 'This application has already been processed.');
            redirect(BASE_PATH . '/super-admin/branch-applications/' . $id);
        }

        // Super admin can override branch_code + password
        $branchCode    = strtoupper(trim($_POST['branch_code'] ?? ''));
        $adminPassword = $_POST['admin_password'] ?? 'Branch@123';

        if (empty($branchCode)) {
            $branchCode = $this->generateNextBranchCode();
        }
        if (strlen($adminPassword) < 6) {
            flash('error', 'Password must be at least 6 characters.');
            redirect(BASE_PATH . '/super-admin/branch-applications/' . $id);
        }

        // 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/branch-applications/' . $id);
        }

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

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

            // 1. Create branch
            $referralCode = 'REF-' . $branchCode;
            $stmt = $this->db->prepare(
                "INSERT INTO `branches`
                    (`name`, `branch_code`, `city`, `state`, `address`, `phone`,
                     `owner_name`, `owner_email`, `owner_phone`, `plan_id`,
                     `investment_range`, `wallet_balance`, `referral_code`,
                     `status`, `kyc_status`, `affiliation_status`, `is_verified`,
                     `approved_at`, `approved_by`, `created_at`, `updated_at`)
                 VALUES
                    (:name, :bc, :city, :state, :addr, :phone,
                     :owner_name, :owner_email, :owner_phone, :plan_id,
                     :investment, 0.00, :ref_code,
                     'active', 'pending', 'pending', 1,
                     NOW(), :approved_by, NOW(), NOW())"
            );
            $stmt->execute([
                ':name'         => $app['name'],
                ':bc'           => $branchCode,
                ':city'         => $app['city'],
                ':state'        => $app['state'],
                ':addr'         => $app['address'] ?: '',
                ':phone'        => $app['phone'],
                ':owner_name'   => $app['name'],
                ':owner_email'  => $app['email'],
                ':owner_phone'  => $app['phone'],
                ':plan_id'      => $app['plan_id'] ?: null,
                ':investment'   => $app['investment_range'] ?: null,
                ':ref_code'     => $referralCode,
                ':approved_by'  => $_SESSION['user_id'] ?? null,
            ]);
            $branchId = (int) $this->db->lastInsertId();

            // 2. Create branch_admin user
            $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'     => $app['name'],
                ':email'    => $app['email'],
                ':password' => $hashedPassword,
                ':phone'    => $app['phone'],
                ':bid'      => $branchId,
                ':bcode'    => $branchCode,
            ]);
            $userId = (int) $this->db->lastInsertId();

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

            // 4. Mark application as approved
            $stmt = $this->db->prepare(
                "UPDATE `branch_applications`
                 SET `status` = 'approved', `reviewed_at` = NOW(), `reviewed_by` = :reviewer,
                     `admin_notes` = :notes
                 WHERE `id` = :id"
            );
            $stmt->execute([
                ':reviewer' => $_SESSION['user_id'] ?? null,
                ':notes'    => "Approved — branch {$branchCode} created with admin user {$app['email']}",
                ':id'       => $id,
            ]);

            $this->db->commit();

            $this->auditLog('branch_application_approve', 'branch_applications', $id,
                "Approved application from {$app['email']} — created branch {$branchCode} (id={$branchId}) + admin user {$app['email']}");

            flash('success', "Application approved! Branch '{$branchCode}' created. Login email: {$app['email']} | Password: {$adminPassword}");
        } catch (\Throwable $e) {
            if ($this->db->inTransaction()) {
                $this->db->rollBack();
            }
            error_log('SuperAdmin approve application error: ' . $e->getMessage());
            flash('error', 'Failed to approve application: ' . $e->getMessage());
        }
        redirect(BASE_PATH . '/super-admin/branch-applications');
    }

    /**
     * Reject an application.
     */
    public function reject(int $id): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        $reason = trim($_POST['reason'] ?? 'Application rejected by Super Admin.');

        try {
            $stmt = $this->db->prepare(
                "UPDATE `branch_applications`
                 SET `status` = 'rejected', `reviewed_at` = NOW(), `reviewed_by` = :reviewer,
                     `admin_notes` = :notes
                 WHERE `id` = :id AND `status` = 'pending'"
            );
            $stmt->execute([
                ':reviewer' => $_SESSION['user_id'] ?? null,
                ':notes'    => $reason,
                ':id'       => $id,
            ]);

            $this->auditLog('branch_application_reject', 'branch_applications', $id, "Rejected: {$reason}");
            flash('success', 'Application rejected.');
        } catch (\Throwable $e) {
            flash('error', 'Failed to reject application: ' . $e->getMessage());
        }
        redirect(BASE_PATH . '/super-admin/branch-applications');
    }

    /**
     * Delete an application (only if rejected or approved — not pending).
     */
    public function delete(int $id): void
    {
        requireSuperAdmin();
        $this->validateCsrf();

        try {
            $stmt = $this->db->prepare("SELECT `status` FROM `branch_applications` WHERE `id` = :id LIMIT 1");
            $stmt->execute([':id' => $id]);
            $app = $stmt->fetch() ?: null;
            if (!$app) {
                flash('error', 'Application not found.');
                redirect(BASE_PATH . '/super-admin/branch-applications');
            }
            if ($app['status'] === 'pending') {
                flash('error', 'Cannot delete a pending application. Reject it first.');
                redirect(BASE_PATH . '/super-admin/branch-applications');
            }

            $this->db->prepare("DELETE FROM `branch_applications` WHERE `id` = :id")->execute([':id' => $id]);
            $this->auditLog('branch_application_delete', 'branch_applications', $id, 'Deleted application');
            flash('success', 'Application deleted.');
        } catch (\Throwable $e) {
            flash('error', 'Failed to delete application: ' . $e->getMessage());
        }
        redirect(BASE_PATH . '/super-admin/branch-applications');
    }

    /**
     * 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';
    }
}
