<?php

namespace App\Controllers;

use Core\Request;
use Core\Redirect;
use Core\DB;
use Exception;
use DateTime;

include realpath(dirname(__DIR__) . '/include/function.php');
include_once realpath(dirname(__DIR__) . '/../config.php');

class Subscription
{
    public function callback()
    {
        header("Content-Type: application/json");
        $logPrefix = "[SUBSCRIPTION CALLBACK]";

        try {
            // Read and decode JSON payload
            $subscriptionResponse = file_get_contents('php://input');
            if ($subscriptionResponse === false) {
                throw new Exception("Failed to read input stream: " . error_get_last()['message']);
            }

            $content = json_decode($subscriptionResponse);
            if ($content === null) {
                throw new Exception("JSON decode error: " . json_last_error_msg());
            }

            // Validate required fields
            $requiredFields = ['TransID', 'BillRefNumber', 'TransactionType', 'TransTime', 
                              'TransAmount', 'BusinessShortCode', 'OrgAccountBalance', 
                              'MSISDN', 'FirstName'];
            foreach ($requiredFields as $field) {
                if (!isset($content->$field)) {
                    throw new Exception("Missing required field: $field");
                }
            }

            $username = $content->BillRefNumber;
            
            // Check user existence
            $db = new DB();
            $conn = $db->getConnection();
            $stmt = $conn->prepare("SELECT id, folder_path, subdomain, phone FROM users WHERE username = ?");
            if (!$stmt) {
                throw new Exception("Prepare failed: " . $conn->error);
            }
            
            $stmt->bind_param("s", $username);
            if (!$stmt->execute()) {
                throw new Exception("Execute failed: " . $stmt->error);
            }
            
            $result = $stmt->get_result();
            $user = $result->fetch_assoc();
            $stmt->close();
            
            if (!$user) {
                $this->logAndNotify("$logPrefix User not found: $username", "⚠️ *Unknown User Payment*\nUsername: `$username`");
                echo json_encode(['status' => 'success', 'message' => 'Callback processed (user not found)']);
                return;
            }

            // Process renewal
            $this->auto_renew($user['id'], $user);

            // Generate and send receipt
            $receipt = $this->generateReceipt($content);
            send_telegram_notification($receipt, BOT_TOKEN, CHAT_ID);

            echo json_encode(['status' => 'success', 'message' => 'Callback processed successfully']);
            
        } catch (Exception $e) {
            $errorMsg = "$logPrefix " . $e->getMessage();
            error_log($errorMsg);
            $this->logAndNotify($errorMsg, "❌ *Callback Processing Failed*\nError: `" . $e->getMessage() . "`");
            echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
        }
    }

    private function auto_renew($user_id, $user)
    {
        $db = new DB();
        $conn = $db->getConnection();
        $conn->begin_transaction();
        $licenseKey = null;

        try {
            // Validate user data
            $username = $user['username'];
            $folder_path = rtrim($user['folder_path'], '/');
            $subdomain = $user['subdomain'];
            $phone = $user['phone'] ?? '';
            $logPrefix = "[RENEWAL:$username]";

            // Remove suspension page
            $suspend_path = $folder_path . '/index.html';
            if (file_exists($suspend_path)) {
                if (!unlink($suspend_path)) {
                    throw new Exception("$logPrefix Failed to remove suspension page");
                }
            }

            // Get license information
            $stmt = $conn->prepare("SELECT license_key, expiry_date, status FROM licenses WHERE user_id = ?");
            if (!$stmt) {
                throw new Exception("$logPrefix License prepare failed: " . $conn->error);
            }
            
            $stmt->bind_param("i", $user_id);
            if (!$stmt->execute()) {
                throw new Exception("$logPrefix License execute failed: " . $stmt->error);
            }
            
            $result = $stmt->get_result();
            $license = $result->fetch_assoc();
            $stmt->close();
            
            if (!$license) {
                throw new Exception("$logPrefix No license found for user");
            }

            $licenseKey = $license['license_key'];
            $licenseExpiry = $license['expiry_date'];
            $licenseStatus = $license['status'];

            // Calculate new expiry date
            $currentDate = new DateTime();
            $expiryDate = new DateTime($licenseExpiry);
            $baseDate = ($licenseStatus === 'active' && $expiryDate > $currentDate) 
                        ? $expiryDate : $currentDate;
            $newExpiryDate = $baseDate->modify('+30 days')->format('Y-m-d H:i:s');

            // Update license
            $stmt = $conn->prepare("UPDATE licenses SET expiry_date = ?, status = 'active' WHERE user_id = ?");
            if (!$stmt) {
                throw new Exception("$logPrefix Update prepare failed: " . $conn->error);
            }
            
            $stmt->bind_param("si", $newExpiryDate, $user_id);
            if (!$stmt->execute()) {
                throw new Exception("$logPrefix Update execute failed: " . $stmt->error);
            }
            $stmt->close();

            // Update license file
            $licenseFilePath = $folder_path . '/license.txt';
            $licenseContent = $this->generateLicenseContent($licenseKey, $newExpiryDate, $username);
            if (file_put_contents($licenseFilePath, $licenseContent) === false) {
                throw new Exception("$logPrefix Failed to update license file");
            }

            $conn->commit();

            // Send notifications
            $this->sendRenewNotifications($username, $phone, $licenseKey, $newExpiryDate, $subdomain);

        } catch (Exception $e) {
            $conn->rollback();
            $errorMsg = "[RENEWAL ERROR] " . $e->getMessage();
            error_log($errorMsg);
            $this->logAndNotify(
                $errorMsg,
                "❌ *Renewal Failed*\nUser: `$username`\nLicense: `" . ($licenseKey ?? 'N/A') . "`\nError: `" . $e->getMessage() . "`"
            );
            throw $e; // Re-throw for callback handler
        } finally {
            if (isset($stmt) && $stmt) $stmt->close();
            if ($conn) $conn->close();
        }
    }

    private function generateReceipt($content): string
    {
        return "📄 *Account Subscription Payment Receipt*\n" .
               "---------------------------------------------\n" .
               "🧾 *Transaction Details*\n" .
               "  • Type: {$content->TransactionType}\n" .
               "  • ID: {$content->TransID}\n" .
               "  • Time: {$content->TransTime}\n" .
               "  • Amount: KES {$content->TransAmount}\n" .
               "---------------------------------------------\n" .
               "🏢 *Business Info*\n" .
               "  • Paybill: {$content->BusinessShortCode}\n" .
               "  • Account: {$content->BillRefNumber}\n" .
               "---------------------------------------------\n" .
               "💰 *Balance & Customer Info*\n" .
               "  • Account Balance: KES {$content->OrgAccountBalance}\n" .
               "  • MSISDN: {$content->MSISDN}\n" .
               "  • Name: {$content->FirstName} " . ($content->MiddleName ?? '') . " {$content->LastName}\n" .
               "---------------------------------------------\n" .
               "✅ *Payment Status*: Successful\n";
    }

    private function generateLicenseContent($licenseKey, $expiryDate, $username): string
    {
        return "License Key: " . htmlspecialchars($licenseKey) . "\n" .
               "Expiry Date: " . htmlspecialchars($expiryDate) . "\n" .
               "Status: Active\n" .
               "Contact: 0100449900 or 0711103820\n" .
               "Paybill: 4032619 (Account: $username)";
    }

    private function sendRenewNotifications($username, $phone, $licenseKey, $expiryDate, $subdomain)
    {
        // WhatsApp notification
        if (!empty($phone)) {
            $formattedPhone = formatPhoneNumber($phone);
            $whatsappMsg = urlencode(
                "Dear $username,\n\n" .
                "Your account has been *renewed* successfully.\n\n" .
                "🔑 *License Key:* $licenseKey\n" .
                "📅 *New Expiry Date:* $expiryDate\n\n" .
                "Thank you for your subscription!\n" .
                "Need help? Contact us:\n📞 0100449900/0711103820"
            );
            sendWhatsAppNotification($formattedPhone, $whatsappMsg);
        }

        // Admin notification
        $adminMsg = "✅ *License Renewed* \n\n" .
                   "👤 User: `$username`\n" .
                   "🔗 Subdomain: `$subdomain`\n" .
                   "🔑 License Key: `$licenseKey`\n" .
                   "📅 New Expiry Date: `$expiryDate`\n" .
                   "📞 Phone: `" . ($phone ?: 'N/A') . "`\n\n" .
                   "Notifications Sent:\n" .
                   (!empty($phone) ? "✅ WhatsApp\n" : "❌ WhatsApp (no phone)\n") .
                   "✅ SMS";
        send_telegram_notification($adminMsg, BOT_TOKEN, CHAT_ID);

        // SMS notification
        $smsMsg = "Dear $username, your account has been renewed.\n" .
                  "License Key: $licenseKey\n" .
                  "New Expiry Date: $expiryDate\n" .
                  "Contact us: 0100449900 or 0711103820";
        sendSMSNotification($phone, $smsMsg);

        
    }

    private function logAndNotify(string $logMessage, string $telegramMessage)
    {
        error_log($logMessage);
        send_telegram_notification($telegramMessage, BOT_TOKEN, CHAT_ID);
    }


    public function createSubscriptionPlan($planName, $amount, $interval, $currency = 'KES')
    {
        
    }

    public function getSubscriptionPlans()
    {
      
    }
}