<?php
class BillingController {
    public function index(): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Auth::requirePermission('billing.view');

        $tid = Auth::tenantId();
        $subscription = PlanModel::getActiveSubscription($tid);
        $package = PlanModel::find($subscription['plan_id'] ?? 0);
        $plans   = PlanModel::all();
        $usage   = PlanGuard::getUsage($tid);

        // Get Paystack public key for frontend
        $paystack = new Paystack();
        $paystackPublicKey = $paystack->getPublicKey();

        $pageTitle = 'Billing & Plan Management';
        ob_start();
        include APP_ROOT . '/views/tenant/billing/index.php';
        $content = ob_get_clean();
        include APP_ROOT . '/views/tenant/layouts/main.php';
    }


    public function upgrade(): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Security::checkCsrf();

        $planId = (int)($_POST['plan_id'] ?? 0);
        $cycle  = $_POST['billing_cycle'] ?? 'monthly';
        $paymentMethod = $_POST['payment_method'] ?? 'paystack';
        
        $plan = PlanModel::find($planId);
        if (!$plan) { flash('error', 'Invalid plan selected'); redirect('billing'); }

        // Handle manual payment
        if ($paymentMethod === 'manual') {
            // Create a pending subscription with manual payment method
            $amount = PlanModel::calculatePrice($plan, $cycle);
            PlanModel::createManualSubscription(
                Auth::tenantId(),
                $planId,
                $cycle,
                $amount
            );
            flash('success', 'Upgrade request received! Our team will contact you with payment instructions.');
            redirect('billing');
        }

        // Initialize Paystack payment
        $paystack = new Paystack();
        $tenant = Auth::tenant();
        $user = Auth::user();
        
        // Generate unique reference
        $reference = 'TLP_' . uniqid() . '_' . time();
        
        // Validate email - use business_email if valid, otherwise fall back to user email
        $email = $tenant['business_email'] ?? '';
        if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $email = $user['email'] ?? '';
            if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
                flash('error', 'No valid email address found for payment. Please update your business email in settings.');
                redirect('billing');
            }
        }
        
        // Prepare payment data
        $paymentData = [
            'email' => $email,
            'amount' => PlanModel::calculatePrice($plan, $cycle),
            'reference' => $reference,
            'metadata' => [
                'tenant_id' => Auth::tenantId(),
                'plan_id' => $planId,
                'cycle' => $cycle,
                'custom_fields' => [
                    [
                        'display_name' => 'Business Name',
                        'variable_name' => 'business_name',
                        'value' => $tenant['business_name']
                    ]
                ]
            ]
        ];

        // If plan has Paystack code, use subscription
        if (!empty($plan['paystack_plan_code'])) {
            $paymentData['plan_code'] = $plan['paystack_plan_code'];
        }

        $result = $paystack->initializeTransaction($paymentData);
        
        if ($result['success']) {
            // Store transaction details in session for callback processing
            $_SESSION['pending_payment'] = [
                'reference' => $result['reference'],
                'plan_id' => $planId,
                'cycle' => $cycle,
                'tenant_id' => Auth::tenantId()
            ];
            
            // Redirect to Paystack payment page
            header('Location: ' . $result['authorization_url']);
            exit;
        } else {
            flash('error', 'Payment initialization failed: ' . $result['message']);
            redirect('billing');
        }
    }

    public function callback(): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();

        $reference = $_GET['reference'] ?? '';
        if (empty($reference)) {
            flash('error', 'No payment reference provided');
            redirect('billing');
        }

        $paystack = new Paystack();
        $result = $paystack->verifyTransaction($reference);

        if ($result['success']) {
            $transactionData = $result['data'];
            
            // Get pending payment details from session
            $pendingPayment = $_SESSION['pending_payment'] ?? [];
            
            if (!empty($pendingPayment) && $transactionData['status'] === 'success') {
                $planId = $pendingPayment['plan_id'];
                $cycle = $pendingPayment['cycle'];
                $tenantId = $pendingPayment['tenant_id'];
                
                // Extract payment details
                $paymentData = [
                    'reference' => $transactionData['reference'],
                    'customer_code' => $transactionData['customer']['customer_code'] ?? null,
                    'subscription_code' => $transactionData['subscription']['subscription_code'] ?? null
                ];
                
                // Create subscription with Paystack details
                PlanModel::createPaystackSubscription($tenantId, $planId, $cycle, $paymentData);
                
                // Clear pending payment from session
                unset($_SESSION['pending_payment']);
                
                flash('success', 'Payment successful! Your subscription has been upgraded.');
            } else {
                flash('error', 'Payment verification failed or session expired');
            }
        } else {
            flash('error', 'Payment verification failed: ' . $result['message']);
        }

        redirect('billing');
    }

    public function webhook(): void {
        // Get webhook payload
        $payload = file_get_contents('php://input');
        $signature = $_SERVER['HTTP_X_PAYSTACK_SIGNATURE'] ?? '';

        $paystack = new Paystack();
        
        if (!$paystack->validateWebhook($payload, $signature)) {
            http_response_code(401);
            exit('Unauthorized');
        }

        $event = json_decode($payload, true);
        
        // Process different event types
        switch ($event['event']) {
            case 'invoice.payment_success':
                $this->handleSuccessfulPayment($event['data']);
                break;
                
            case 'invoice.payment_failed':
                $this->handleFailedPayment($event['data']);
                break;
                
            case 'subscription.create':
                $this->handleSubscriptionCreate($event['data']);
                break;
                
            case 'subscription.disable':
                $this->handleSubscriptionDisable($event['data']);
                break;
        }

        http_response_code(200);
        exit('Webhook processed');
    }

    private function handleSuccessfulPayment(array $data): void {
        // Update subscription status to active
        if (isset($data['subscription'])) {
            $subscriptionCode = $data['subscription']['subscription_code'];
            $reference = $data['payment']['reference'];
            
            $stmt = db()->prepare(
                "UPDATE subscriptions SET status='active', current_period_end=? 
                 WHERE paystack_subscription_code=? OR paystack_reference=?"
            );
            $stmt->execute([
                date('Y-m-d H:i:s', strtotime($data['subscription']['next_payment_date'])),
                $subscriptionCode,
                $reference
            ]);
        }
    }

    private function handleFailedPayment(array $data): void {
        // Update subscription status to past_due
        if (isset($data['subscription'])) {
            $subscriptionCode = $data['subscription']['subscription_code'];
            
            $stmt = db()->prepare(
                "UPDATE subscriptions SET status='past_due' 
                 WHERE paystack_subscription_code=?"
            );
            $stmt->execute([$subscriptionCode]);
        }
    }

    private function handleSubscriptionCreate(array $data): void {
        // Update subscription with Paystack codes
        if (isset($data['subscription_code'])) {
            $subscriptionCode = $data['subscription_code'];
            $customerCode = $data['customer']['customer_code'];
            
            $stmt = db()->prepare(
                "UPDATE subscriptions SET 
                 paystack_subscription_code=?, paystack_customer_code=? 
                 WHERE paystack_subscription_code=?"
            );
            $stmt->execute([$subscriptionCode, $customerCode, $subscriptionCode]);
        }
    }

    private function handleSubscriptionDisable(array $data): void {
        // Cancel subscription
        if (isset($data['subscription_code'])) {
            $subscriptionCode = $data['subscription_code'];
            
            $stmt = db()->prepare(
                "UPDATE subscriptions SET status='cancelled', cancelled_at=NOW() 
                 WHERE paystack_subscription_code=?"
            );
            $stmt->execute([$subscriptionCode]);
        }
    }

    public function cancel(): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Security::checkCsrf();

        $tid = Auth::tenantId();
        $subscription = PlanModel::getActiveSubscription($tid);

        if ($subscription && $subscription['payment_method'] === 'paystack' && !empty($subscription['paystack_subscription_code'])) {
            // Cancel with Paystack
            $paystack = new Paystack();
            // Note: You would need to implement the cancel subscription method in Paystack class
            // For now, just mark as cancelled locally
        }

        PlanModel::cancelSubscription($tid);

        flash('warning', 'Your subscription will not renew, but remains active until expiry.');
        redirect('billing');
    }

    public function downloadInvoice(): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();

        $subscriptionId = (int)($_POST['subscription_id'] ?? 0);

        if (!$subscriptionId) {
            flash('error', 'Invalid subscription ID');
            redirect('billing');
        }

        $tid = Auth::tenantId();
        $subscription = db()->prepare(
            "SELECT s.*, p.name as plan_name, t.business_name, t.business_address, t.business_email, t.business_phone
             FROM subscriptions s
             JOIN plans p ON p.id = s.plan_id
             JOIN tenants t ON t.id = s.tenant_id
             WHERE s.id=? AND s.tenant_id=?"
        );
        $subscription->execute([$subscriptionId, $tid]);
        $subscription = $subscription->fetch();

        if (!$subscription) {
            flash('error', 'Subscription not found');
            redirect('billing');
        }

        // Generate simple invoice HTML
        $invoiceHtml = $this->generateInvoiceHtml($subscription);

        // Set headers for HTML download
        header('Content-Type: text/html');
        header('Content-Disposition: attachment; filename="invoice-' . $subscription['id'] . '.html"');
        header('Content-Length: ' . strlen($invoiceHtml));

        echo $invoiceHtml;
        exit;
    }

    private function generateInvoiceHtml(array $subscription): string {
        $tenant = Auth::tenant();
        $date = date('M j, Y', strtotime($subscription['created_at']));
        $invoiceNumber = 'INV-' . str_pad($subscription['id'], 6, '0', STR_PAD_LEFT);

        return '<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Invoice ' . $invoiceNumber . '</title>
    <style>
        body { font-family: Arial, sans-serif; padding: 40px; max-width: 800px; margin: 0 auto; }
        .header { border-bottom: 2px solid #333; padding-bottom: 20px; margin-bottom: 30px; }
        .header h1 { margin: 0; color: #333; }
        .header p { margin: 5px 0; color: #666; }
        .info { display: flex; justify-content: space-between; margin-bottom: 30px; }
        .info div { width: 45%; }
        .info h3 { margin: 0 0 10px 0; color: #333; }
        .info p { margin: 5px 0; color: #666; }
        table { width: 100%; border-collapse: collapse; margin-bottom: 30px; }
        th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }
        th { background: #f5f5f5; font-weight: bold; }
        .total { text-align: right; font-size: 1.2em; font-weight: bold; }
        .footer { margin-top: 40px; padding-top: 20px; border-top: 1px solid #ddd; text-align: center; color: #666; font-size: 0.9em; }
    </style>
</head>
<body>
    <div class="header">
        <h1>INVOICE</h1>
        <p>' . $invoiceNumber . '</p>
        <p>Date: ' . $date . '</p>
    </div>

    <div class="info">
        <div>
            <h3>Bill To:</h3>
            <p><strong>' . htmlspecialchars($subscription['business_name']) . '</strong></p>
            <p>' . htmlspecialchars($subscription['business_address'] ?? 'N/A') . '</p>
            <p>Email: ' . htmlspecialchars($subscription['business_email']) . '</p>
            <p>Phone: ' . htmlspecialchars($subscription['business_phone'] ?? 'N/A') . '</p>
        </div>
        <div>
            <h3>From:</h3>
            <p><strong>TellerPro</strong></p>
            <p>Platform Subscription</p>
        </div>
    </div>

    <table>
        <thead>
            <tr>
                <th>Description</th>
                <th>Billing Cycle</th>
                <th>Amount</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>' . htmlspecialchars($subscription['plan_name']) . ' Plan</td>
                <td>' . htmlspecialchars($subscription['billing_cycle']) . '</td>
                <td>$' . number_format($subscription['amount'], 2) . '</td>
            </tr>
        </tbody>
    </table>

    <div class="total">
        Total: $' . number_format($subscription['amount'], 2) . '
    </div>

    <div class="footer">
        <p>Thank you for your business!</p>
        <p>This is a computer-generated invoice. No signature required.</p>
    </div>
</body>
</html>';
    }
}
