<?php
// Isolated Stripe API endpoints - no output buffer conflicts
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Include necessary files
require_once 'lib/mysql_functions.php';
require_once 'jwt-utils.php';

// Load settings (guard against direct-access die in data file)
if (!isset($LOADSTRUCT)) { $LOADSTRUCT = true; }
$settings = require 'data/settings.dat.php';
$GLOBALS['SETTINGS'] = $settings;

// Helper: verify JWT from Authorization header (supports raw or Bearer <token>)
function verify_jwt($authHeader) {
    if (!$authHeader) { return false; }
    $token = preg_replace('/^Bearer\s+/i', '', trim($authHeader));
    if (!$token) { return false; }
    list($ok, $payload) = jwt_validateToken($token);
    if (!$ok) { return false; }
    return $payload; // array
}

// Polyfill for getallheaders() if not available
if (!function_exists('getallheaders')) {
    function getallheaders() {
        $headers = [];
        foreach ($_SERVER as $name => $value) {
            if (substr($name, 0, 5) == 'HTTP_') {
                $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
            }
        }
        return $headers;
    }
}

// Connect to database
$conn = mysqli_connect(
    $settings['mysql']['hostname'],
    $settings['mysql']['username'],
    $settings['mysql']['password'],
    $settings['mysql']['database']
);

if (!$conn) {
    http_response_code(500);
    echo json_encode(['success' => false, 'errors' => 'Database connection failed']);
    exit();
}

$GLOBALS['conn'] = $conn;

// Set headers
header('Content-Type: application/json');
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET,POST,OPTIONS,DELETE,PUT');

// Handle preflight request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

// Get request path
$request_uri = $_SERVER['REQUEST_URI'];
$path = parse_url($request_uri, PHP_URL_PATH);
$query = parse_url($request_uri, PHP_URL_QUERY);

// Parse query parameters
parse_str($query, $query_params);

// Route to appropriate endpoint
if (isset($query_params['payment/stripe/setup_intent'])) {
    handleSetupIntent();
} elseif (isset($query_params['payment/stripe/save_method'])) {
    handleSaveMethod();
} elseif (isset($query_params['payment/stripe/list_methods'])) {
    handleListMethods();
} else {
    http_response_code(404);
    echo json_encode(['success' => false, 'errors' => 'Endpoint not found']);
}

// --- Lightweight DB helpers (no CMS dependencies)
function db_table($name) {
    $prefix = isset($GLOBALS['SETTINGS']['mysql']['tablePrefix']) ? $GLOBALS['SETTINGS']['mysql']['tablePrefix'] : '';
    return $prefix . $name;
}

function db_get_member($userNum) {
    $userNum = (int)$userNum;
    $table = db_table('members');
    $sql = "SELECT num, email FROM `$table` WHERE `num` = $userNum LIMIT 1";
    $res = mysqli_query($GLOBALS['conn'], $sql);
    if (!$res) { throw new Exception('DB error: ' . mysqli_error($GLOBALS['conn'])); }
    $row = mysqli_fetch_assoc($res);
    if (is_resource($res)) { mysqli_free_result($res); }
    return $row ?: [];
}

function db_get_member_card($userNum) {
    $userNum = (int)$userNum;
    $table = db_table('member_cards');
    $sql = "SELECT `num`, `stripe_customer_id` FROM `$table` WHERE `membersNum` = $userNum LIMIT 1";
    $res = mysqli_query($GLOBALS['conn'], $sql);
    if (!$res) { throw new Exception('DB error: ' . mysqli_error($GLOBALS['conn'])); }
    $row = mysqli_fetch_assoc($res);
    if (is_resource($res)) { mysqli_free_result($res); }
    return $row ?: null;
}

function db_update_member_card_customer($cardNum, $customerId) {
    $cardNum = (int)$cardNum;
    $customerId = mysqli_real_escape_string($GLOBALS['conn'], $customerId);
    $table = db_table('member_cards');
    $sql = "UPDATE `$table` SET `stripe_customer_id` = '$customerId' WHERE `num` = $cardNum LIMIT 1";
    if (!mysqli_query($GLOBALS['conn'], $sql)) { throw new Exception('DB error: ' . mysqli_error($GLOBALS['conn'])); }
}

function db_insert_member_card($userNum, $customerId) {
    $userNum = (int)$userNum;
    $customerId = mysqli_real_escape_string($GLOBALS['conn'], $customerId);
    $table = db_table('member_cards');
    $sql = "INSERT INTO `$table` (`membersNum`, `stripe_customer_id`, `createdDate`) VALUES ($userNum, '$customerId', NOW())";
    if (!mysqli_query($GLOBALS['conn'], $sql)) { throw new Exception('DB error: ' . mysqli_error($GLOBALS['conn'])); }
}

function db_ensure_member_cards_schema() {
    $dbName = $GLOBALS['SETTINGS']['mysql']['database'];
    $table = db_table('member_cards');
    
    // Temporarily disable strict mode to handle legacy table issues
    $oldModeRes = mysqli_query($GLOBALS['conn'], "SELECT @@SESSION.SQL_MODE");
    $oldModeRow = $oldModeRes ? mysqli_fetch_row($oldModeRes) : null;
    $oldMode = $oldModeRow ? $oldModeRow[0] : '';
    if (is_resource($oldModeRes)) { mysqli_free_result($oldModeRes); }
    
    // Set SQL mode to be more permissive for table creation/alteration
    @mysqli_query($GLOBALS['conn'], "SET SESSION SQL_MODE=''");
    
    // create table if not exists (minimal columns)
    $sqlCreate = "CREATE TABLE IF NOT EXISTS `$table` (
        `num` INT UNSIGNED NOT NULL AUTO_INCREMENT,
        `membersNum` INT UNSIGNED NOT NULL,
        `stripe_customer_id` VARCHAR(255) DEFAULT NULL,
        `createdDate` DATETIME NULL DEFAULT NULL,
        PRIMARY KEY (`num`),
        KEY `idx_membersNum` (`membersNum`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4";
    if (!mysqli_query($GLOBALS['conn'], $sqlCreate)) { 
        // Restore original SQL mode before throwing error
        if ($oldMode !== '') { @mysqli_query($GLOBALS['conn'], "SET SESSION SQL_MODE='" . mysqli_real_escape_string($GLOBALS['conn'], $oldMode) . "'"); }
        throw new Exception('DB error: ' . mysqli_error($GLOBALS['conn'])); 
    }

    // ensure stripe_customer_id column exists
    $sqlCol = "SELECT 1 FROM information_schema.columns WHERE table_schema='" . mysqli_real_escape_string($GLOBALS['conn'], $dbName) .
             "' AND table_name='" . mysqli_real_escape_string($GLOBALS['conn'], $table) . "' AND column_name='stripe_customer_id'";
    $res = mysqli_query($GLOBALS['conn'], $sqlCol);
    if (!$res) { 
        if ($oldMode !== '') { @mysqli_query($GLOBALS['conn'], "SET SESSION SQL_MODE='" . mysqli_real_escape_string($GLOBALS['conn'], $oldMode) . "'"); }
        throw new Exception('DB error: ' . mysqli_error($GLOBALS['conn'])); 
    }
    $exists = mysqli_fetch_row($res);
    if (is_resource($res)) { mysqli_free_result($res); }
    if (!$exists) {
        $sqlAlter = "ALTER TABLE `$table` ADD COLUMN `stripe_customer_id` VARCHAR(255) DEFAULT NULL";
        if (!mysqli_query($GLOBALS['conn'], $sqlAlter)) { 
            if ($oldMode !== '') { @mysqli_query($GLOBALS['conn'], "SET SESSION SQL_MODE='" . mysqli_real_escape_string($GLOBALS['conn'], $oldMode) . "'"); }
            throw new Exception('DB error: ' . mysqli_error($GLOBALS['conn'])); 
        }
    }

    // ensure createdDate column is compatible
    $sqlCol2 = "SELECT 1 FROM information_schema.columns WHERE table_schema='" . mysqli_real_escape_string($GLOBALS['conn'], $dbName) .
              "' AND table_name='" . mysqli_real_escape_string($GLOBALS['conn'], $table) . "' AND column_name='createdDate'";
    $res2 = mysqli_query($GLOBALS['conn'], $sqlCol2);
    if (!$res2) { 
        if ($oldMode !== '') { @mysqli_query($GLOBALS['conn'], "SET SESSION SQL_MODE='" . mysqli_real_escape_string($GLOBALS['conn'], $oldMode) . "'"); }
        throw new Exception('DB error: ' . mysqli_error($GLOBALS['conn'])); 
    }
    $exists2 = mysqli_fetch_row($res2);
    if (is_resource($res2)) { mysqli_free_result($res2); }
    
    if (!$exists2) {
        $sqlAlter2 = "ALTER TABLE `$table` ADD COLUMN `createdDate` DATETIME NULL DEFAULT NULL";
        if (!mysqli_query($GLOBALS['conn'], $sqlAlter2)) { 
            if ($oldMode !== '') { @mysqli_query($GLOBALS['conn'], "SET SESSION SQL_MODE='" . mysqli_real_escape_string($GLOBALS['conn'], $oldMode) . "'"); }
            throw new Exception('DB error: ' . mysqli_error($GLOBALS['conn'])); 
        }
    } else {
        // Clean up any existing zero-dates which cause strict-mode errors
        @mysqli_query($GLOBALS['conn'], "UPDATE `$table` SET `createdDate` = NULL WHERE `createdDate` = '0000-00-00 00:00:00'");
        
        // Fix the column definition to be compatible with strict mode
        $sqlFix = "ALTER TABLE `$table` MODIFY `createdDate` DATETIME NULL DEFAULT NULL";
        if (!mysqli_query($GLOBALS['conn'], $sqlFix)) { 
            // If that fails, try dropping and recreating the column
            @mysqli_query($GLOBALS['conn'], "ALTER TABLE `$table` DROP COLUMN `createdDate`");
            @mysqli_query($GLOBALS['conn'], "ALTER TABLE `$table` ADD COLUMN `createdDate` DATETIME NULL DEFAULT NULL");
        }
    }
    
    // Restore original SQL mode
    if ($oldMode !== '') { 
        @mysqli_query($GLOBALS['conn'], "SET SESSION SQL_MODE='" . mysqli_real_escape_string($GLOBALS['conn'], $oldMode) . "'"); 
    }
}

function handleSetupIntent() {
    try {
        error_log('STRIPE setup_intent: start');
        
        $requestHeaders = getallheaders();
        $authHeader = null;
        foreach ($requestHeaders as $key => $value) {
            if (strtolower($key) === 'authorization') {
                $authHeader = $value;
                break;
            }
        }
        
        if (!$authHeader) {
            http_response_code(401);
            echo json_encode(['success' => false, 'errors' => 'Authorization token is required']);
            exit();
        }
        
        $decoded = verify_jwt($authHeader);
        if (!$decoded) {
            http_response_code(401);
            echo json_encode(['success' => false, 'errors' => 'Invalid or expired token']);
            exit();
        }
        
        $userNum = isset($decoded['sub']) ? $decoded['sub'] : null;
        if (!$userNum) {
            http_response_code(400);
            echo json_encode(['success' => false, 'errors' => 'User not found in token']);
            exit();
        }
        
        // Check Stripe SDK
        $autoloadPath = __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
        if (!file_exists($autoloadPath)) {
            error_log('STRIPE setup_intent: autoload missing');
            http_response_code(500);
            echo json_encode(['success' => false, 'errors' => 'Stripe SDK not installed. Run composer install.']);
            exit();
        }
        
        require_once $autoloadPath;
        
        $stripeSecret = @$GLOBALS['SETTINGS']['stripe_test']['secretKey'];
        if (empty($stripeSecret)) {
            error_log('STRIPE setup_intent: secret key missing');
            http_response_code(500);
            echo json_encode(['success' => false, 'errors' => 'Stripe secret key missing in settings.stripe_test.secretKey']);
            exit();
        }
        
        \Stripe\Stripe::setApiKey($stripeSecret);
        
        // Ensure schema exists and get or create stripe customer id for this user
        db_ensure_member_cards_schema();
        $memberCard = db_get_member_card($userNum);
        $stripeCustomerId = $memberCard ? $memberCard['stripe_customer_id'] : null;
        
        if (!$stripeCustomerId) {
            $member = db_get_member($userNum);
            // Get name from JWT token if available, otherwise use email
            $customerName = null;
            if (isset($decoded['name']) && !empty($decoded['name'])) {
                $customerName = $decoded['name'];
            } elseif (isset($decoded['full_name']) && !empty($decoded['full_name'])) {
                $customerName = $decoded['full_name'];
            } elseif (isset($decoded['first_name']) || isset($decoded['last_name'])) {
                $firstName = @$decoded['first_name'] ?: '';
                $lastName = @$decoded['last_name'] ?: '';
                $customerName = trim($firstName . ' ' . $lastName) ?: null;
            }
            
            $customer = \Stripe\Customer::create([
                'email' => @$member['email'],
                'name' => $customerName,
                'metadata' => ['cms_user_id' => (string) $userNum]
            ]);
            $stripeCustomerId = $customer->id;
            
            if ($memberCard) {
                db_update_member_card_customer($memberCard['num'], $stripeCustomerId);
            } else {
                db_insert_member_card($userNum, $stripeCustomerId);
            }
        }
        
        $setup = \Stripe\SetupIntent::create([
            'customer' => $stripeCustomerId,
            'payment_method_types' => ['card'],
            'usage' => 'off_session'
        ]);
        
        error_log('STRIPE setup_intent: success - client_secret: ' . $setup->client_secret);
        
        $response = [
            'success' => true, 
            'client_secret' => $setup->client_secret, 
            'stripe_customer_id' => $stripeCustomerId
        ];
        
        echo json_encode($response);
        error_log('STRIPE setup_intent: response sent successfully');
        
    } catch (Exception $e) {
        error_log('Stripe setup_intent error: ' . $e->getMessage());
        http_response_code(500);
        echo json_encode(['success' => false, 'errors' => $e->getMessage()]);
    }
}

function handleSaveMethod() {
    try {
        error_log('STRIPE save_method: start');
        
        // Get authorization header
        $headers = getallheaders();
        $authHeader = null;
        foreach ($headers as $k => $v) {
            if (strtolower($k) === 'authorization') {
                $authHeader = $v;
                break;
            }
        }
        
        if (!$authHeader) {
            http_response_code(401);
            echo json_encode(['success' => false, 'errors' => 'Authorization token is required']);
            exit();
        }
        
        $decoded = verify_jwt($authHeader);
        if (!$decoded) {
            http_response_code(401);
            echo json_encode(['success' => false, 'errors' => 'Invalid or expired token']);
            exit();
        }
        
        $userNum = isset($decoded['sub']) ? $decoded['sub'] : null;
        if (!$userNum) {
            http_response_code(400);
            echo json_encode(['success' => false, 'errors' => 'User not found in token']);
            exit();
        }
        
        $input = json_decode(file_get_contents('php://input'), true);
        if (empty($input['payment_method_id'])) {
            http_response_code(400);
            echo json_encode(['success' => false, 'errors' => 'payment_method_id is required']);
            exit();
        }
        
        // Check Stripe SDK
        $autoloadPath = __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
        if (!file_exists($autoloadPath)) {
            error_log('STRIPE save_method: autoload missing');
            http_response_code(500);
            echo json_encode(['success' => false, 'errors' => 'Stripe SDK not installed. Run composer install.']);
            exit();
        }
        
        require_once $autoloadPath;
        
        $stripeSecret = @$GLOBALS['SETTINGS']['stripe_test']['secretKey'];
        if (empty($stripeSecret)) {
            error_log('STRIPE save_method: secret key missing');
            http_response_code(500);
            echo json_encode(['success' => false, 'errors' => 'Stripe secret key missing in settings.stripe_test.secretKey']);
            exit();
        }
        
        \Stripe\Stripe::setApiKey($stripeSecret);
        
        // Ensure schema exists and load or create Stripe customer for this user
        db_ensure_member_cards_schema();
        $memberCard = db_get_member_card($userNum);
        $stripeCustomerId = $memberCard ? $memberCard['stripe_customer_id'] : null;
        
        if (!$stripeCustomerId) {
            $member = db_get_member($userNum);
            // Get name from JWT token if available, otherwise use email
            $customerName = null;
            if (isset($decoded['name']) && !empty($decoded['name'])) {
                $customerName = $decoded['name'];
            } elseif (isset($decoded['full_name']) && !empty($decoded['full_name'])) {
                $customerName = $decoded['full_name'];
            } elseif (isset($decoded['first_name']) || isset($decoded['last_name'])) {
                $firstName = @$decoded['first_name'] ?: '';
                $lastName = @$decoded['last_name'] ?: '';
                $customerName = trim($firstName . ' ' . $lastName) ?: null;
            }
            
            $customer = \Stripe\Customer::create([
                'email' => @$member['email'],
                'name' => $customerName,
                'metadata' => ['cms_user_id' => (string) $userNum]
            ]);
            $stripeCustomerId = $customer->id;
            
            if ($memberCard) {
                db_update_member_card_customer($memberCard['num'], $stripeCustomerId);
            } else {
                db_insert_member_card($userNum, $stripeCustomerId);
            }
        }
        
        \Stripe\PaymentMethod::retrieve($input['payment_method_id'])->attach(['customer' => $stripeCustomerId]);
        
        if (!empty($input['set_default'])) {
            \Stripe\Customer::update($stripeCustomerId, ['invoice_settings' => ['default_payment_method' => $input['payment_method_id']]]);
        }
        
        $pm = \Stripe\PaymentMethod::retrieve($input['payment_method_id']);
        
        $response = [
            'success' => true,
            'payment_method' => [
                'id' => $pm->id,
                'brand' => @$pm->card->brand,
                'last4' => @$pm->card->last4,
                'exp_month' => @$pm->card->exp_month,
                'exp_year' => @$pm->card->exp_year,
                'customer_id' => $stripeCustomerId
            ]
        ];
        
        echo json_encode($response);
        
    } catch (Exception $e) {
        error_log('Stripe save_method error: ' . $e->getMessage());
        http_response_code(500);
        echo json_encode(['success' => false, 'errors' => $e->getMessage()]);
    }
}

function handleListMethods() {
    try {
        error_log('STRIPE list_methods: start');
        
        // Get authorization header
        $headers = getallheaders();
        $authHeader = null;
        foreach ($headers as $k => $value) {
            if (strtolower($k) === 'authorization') {
                $authHeader = $value;
                break;
            }
        }
        
        if (!$authHeader) {
            http_response_code(401);
            echo json_encode(['success' => false, 'errors' => 'Authorization token is required']);
            exit();
        }
        
        $decoded = verify_jwt($authHeader);
        if (!$decoded) {
            http_response_code(401);
            echo json_encode(['success' => false, 'errors' => 'Invalid or expired token']);
            exit();
        }
        
        $userNum = isset($decoded['sub']) ? $decoded['sub'] : null;
        if (!$userNum) {
            http_response_code(400);
            echo json_encode(['success' => false, 'errors' => 'User not found in token']);
            exit();
        }
        
        // Check Stripe SDK
        $autoloadPath = __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
        if (!file_exists($autoloadPath)) {
            http_response_code(500);
            echo json_encode(['success' => false, 'errors' => 'Stripe SDK not installed. Run composer install.']);
            exit();
        }
        
        require_once $autoloadPath;
        
        $stripeSecret = @$GLOBALS['SETTINGS']['stripe_test']['secretKey'];
        if (empty($stripeSecret)) {
            http_response_code(500);
            echo json_encode(['success' => false, 'errors' => 'Stripe secret key missing in settings.stripe_test.secretKey']);
            exit();
        }
        
        \Stripe\Stripe::setApiKey($stripeSecret);
        
        db_ensure_member_cards_schema();
        $memberCard = db_get_member_card($userNum);
        $stripeCustomerId = $memberCard ? $memberCard['stripe_customer_id'] : null;
        
        if (!$stripeCustomerId) {
            echo json_encode(['success' => true, 'urban_data' => []]);
            exit();
        }
        
        $list = \Stripe\PaymentMethod::all(['customer' => $stripeCustomerId, 'type' => 'card']);
        $out = [];
        
        foreach ($list->data as $pm) {
            $out[] = [
                'id' => $pm->id, 
                'brand' => @$pm->card->brand, 
                'last4' => @$pm->card->last4, 
                'exp_month' => @$pm->card->exp_month, 
                'exp_year' => @$pm->card->exp_year
            ];
        }
        
        echo json_encode(['success' => true, 'urban_data' => $out]);
        
    } catch (Exception $e) {
        error_log('Stripe list_methods error: ' . $e->getMessage());
        http_response_code(500);
        echo json_encode(['success' => false, 'errors' => $e->getMessage()]);
    }
}

function getTableName($table) {
    global $settings;
    
    if (!isset($settings)) {
        $settings = require 'data/settings.dat.php';
    }
    
    if (!isset($settings['mysql']) || !isset($settings['mysql']['tablePrefix'])) {
        error_log("MySQL table prefix not found in settings");
        return $table;
    }
    
    return $settings['mysql']['tablePrefix'] . $table;
}
?>