<?php
/**
 * Paystack Dedicated Virtual Account (DVA) Helper
 * Creates a unique bank account per user for receiving transfers.
 * 
 * Paystack DVA API: https://paystack.com/docs/payments/dedicated-virtual-accounts/
 * 
 * Requirements:
 * - Paystack business account with DVA enabled
 * - paystack_secret_key in settings table
 * - paystack_dva_enabled in settings table (1 = enabled)
 * - paystack_dva_provider in settings (wema-bank or titan-paystack)
 */

function createPaystackDVA(PDO $pdo, array $site_data, int $user_id, string $full_name, string $email, string $phone): array
{
    $secret_key  = trim($site_data['paystack_secret_key'] ?? '');
    $dva_enabled = intval($site_data['paystack_dva_enabled'] ?? 0);
    $provider    = trim($site_data['paystack_dva_provider'] ?? 'wema-bank'); // wema-bank or titan-paystack

    if (!$dva_enabled || empty($secret_key)) {
        return ['success' => false, 'message' => 'Paystack DVA not configured.', 'data' => null];
    }

    // Ensure valid phone number (Paystack requires it for DVA)
    $phone_clean = preg_replace('/[^0-9]/', '', $phone);
    if (strlen($phone_clean) === 13 && substr($phone_clean, 0, 3) === '234') {
        $phone_clean = '0' . substr($phone_clean, 3);
    } elseif (strlen($phone_clean) === 10 && $phone_clean[0] !== '0') {
        $phone_clean = '0' . $phone_clean;
    }
    if (strlen($phone_clean) < 11) {
        return ['success' => false, 'message' => 'Please update your phone number in your profile to get a virtual account.', 'data' => null];
    }
    // Convert to international format for Paystack
    $phone_intl = '+234' . substr($phone_clean, 1);

    // Step 1: Create or fetch customer on Paystack
    $customer_code = getOrCreatePaystackCustomer($secret_key, $user_id, $email, $full_name, $phone_intl, $pdo);
    if (!$customer_code) {
        return ['success' => false, 'message' => 'Could not create Paystack customer.', 'data' => null];
    }

    // Step 2: Create Dedicated Virtual Account
    $dva_url = 'https://api.paystack.co/dedicated_account';
    $name_parts = explode(' ', trim($full_name), 2);
    $first_name = $name_parts[0] ?? 'User';
    $last_name  = $name_parts[1] ?? $first_name;

    $payload = json_encode([
        'customer'           => $customer_code,
        'preferred_bank'     => $provider,
        'phone'              => $phone_intl,
        'first_name'         => $first_name,
        'last_name'          => $last_name,
    ]);

    $ch = curl_init($dva_url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $payload,
        CURLOPT_HTTPHEADER     => [
            'Authorization: Bearer ' . $secret_key,
            'Content-Type: application/json',
            'Cache-Control: no-cache',
        ],
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_CONNECTTIMEOUT => 15,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => 0,
        CURLOPT_FOLLOWLOCATION => true,
    ]);

    $response  = curl_exec($ch);
    $curl_err  = curl_error($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($curl_err) {
        error_log("[Paystack DVA] cURL error for user {$user_id}: {$curl_err}");
        return ['success' => false, 'message' => 'Connection error. Please try again.', 'data' => null];
    }

    $result = json_decode($response, true);
    error_log("[Paystack DVA] Create response for user {$user_id}: HTTP {$http_code} | " . $response);

    if (!$result || !isset($result['status']) || $result['status'] !== true) {
        $msg = $result['message'] ?? 'Failed to create virtual account.';
        error_log("[Paystack DVA] Failed for user {$user_id}: {$msg}");
        return ['success' => false, 'message' => $msg, 'data' => null];
    }

    $data = $result['data'] ?? [];
    $acct_number = $data['account_number'] ?? '';
    $acct_name   = $data['account_name']   ?? $full_name;
    $bank_name   = $data['bank']['name']   ?? 'Wema Bank';
    $bank_slug   = $data['bank']['slug']   ?? $provider;
    $dva_id      = $data['id']             ?? 0;

    if (empty($acct_number)) {
        error_log("[Paystack DVA] No account_number in response for user {$user_id}");
        return ['success' => false, 'message' => 'No account number returned. Please try again.', 'data' => null];
    }

    // Save to users table
    try {
        // Ensure columns exist
        $pdo->exec("ALTER TABLE users
            ADD COLUMN IF NOT EXISTS paystack_dva_account_number VARCHAR(20) DEFAULT NULL,
            ADD COLUMN IF NOT EXISTS paystack_dva_account_name VARCHAR(150) DEFAULT NULL,
            ADD COLUMN IF NOT EXISTS paystack_dva_bank_name VARCHAR(100) DEFAULT NULL,
            ADD COLUMN IF NOT EXISTS paystack_dva_id INT DEFAULT NULL,
            ADD COLUMN IF NOT EXISTS paystack_customer_code VARCHAR(50) DEFAULT NULL");
    } catch (PDOException $e) {}

    try {
        $pdo->prepare(
            "UPDATE users SET
                paystack_dva_account_number = :acct_num,
                paystack_dva_account_name   = :acct_name,
                paystack_dva_bank_name      = :bank_name,
                paystack_dva_id             = :dva_id,
                paystack_customer_code      = :cust_code
             WHERE id = :uid"
        )->execute([
            'acct_num'  => $acct_number,
            'acct_name' => $acct_name,
            'bank_name' => $bank_name,
            'dva_id'    => $dva_id,
            'cust_code' => $customer_code,
            'uid'       => $user_id,
        ]);
        error_log("[Paystack DVA] Saved for user {$user_id}: {$acct_number} ({$bank_name})");
    } catch (PDOException $e) {
        error_log("[Paystack DVA] DB save error for user {$user_id}: " . $e->getMessage());
    }

    return [
        'success' => true,
        'message' => 'Virtual account created.',
        'data'    => [
            'account_number' => $acct_number,
            'account_name'   => $acct_name,
            'bank_name'      => $bank_name,
        ],
    ];
}

function getOrCreatePaystackCustomer(string $secret_key, int $user_id, string $email, string $full_name, string $phone, PDO $pdo): ?string
{
    // Check if we already have a customer code stored
    try {
        $stmt = $pdo->prepare("SELECT paystack_customer_code FROM users WHERE id = :uid");
        $stmt->execute(['uid' => $user_id]);
        $existing = $stmt->fetchColumn();
        if (!empty($existing)) return $existing;
    } catch (PDOException $e) {}

    // Create customer on Paystack
    $name_parts = explode(' ', trim($full_name), 2);
    $first_name = $name_parts[0] ?? 'User';
    $last_name  = $name_parts[1] ?? $first_name;

    // Phone is required by Paystack — use a placeholder if empty
    $phone_clean = preg_replace('/[^0-9+]/', '', $phone);
    if (empty($phone_clean) || strlen($phone_clean) < 10) {
        $phone_clean = '+234' . str_pad($user_id, 10, '0', STR_PAD_LEFT);
    }

    $payload = json_encode([
        'email'      => $email,
        'first_name' => $first_name,
        'last_name'  => $last_name,
        'phone'      => $phone_clean,
    ]);

    $ch = curl_init('https://api.paystack.co/customer');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $payload,
        CURLOPT_HTTPHEADER     => [
            'Authorization: Bearer ' . $secret_key,
            'Content-Type: application/json',
        ],
        CURLOPT_TIMEOUT        => 20,
        CURLOPT_CONNECTTIMEOUT => 15,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => 0,
        CURLOPT_FOLLOWLOCATION => true,
    ]);

    $response = curl_exec($ch);
    $curl_err = curl_error($ch);
    curl_close($ch);

    if ($curl_err) {
        error_log("[Paystack DVA] Customer create cURL error: {$curl_err}");
        return null;
    }

    $result = json_decode($response, true);
    if (!$result || !isset($result['status']) || $result['status'] !== true) {
        error_log("[Paystack DVA] Customer create failed: " . ($result['message'] ?? $response));
        return null;
    }

    $customer_code = $result['data']['customer_code'] ?? '';
    if (empty($customer_code)) return null;

    // Store it
    try {
        $pdo->exec("ALTER TABLE users ADD COLUMN IF NOT EXISTS paystack_customer_code VARCHAR(50) DEFAULT NULL");
        $pdo->prepare("UPDATE users SET paystack_customer_code = :code WHERE id = :uid")
            ->execute(['code' => $customer_code, 'uid' => $user_id]);
    } catch (PDOException $e) {}

    return $customer_code;
}
