<?php
require_once '../core/bootstrap.php';

// --- Configuration ---
$settingModel = new Setting();
$settings = $settingModel->getAll();
$secretHash = $settings['flutterwave_secret_key'] ?? '';

// --- Verify Signature ---
$signature = (isset($_SERVER['HTTP_VERIF_HASH']) ? $_SERVER['HTTP_VERIF_HASH'] : '');
if (!$signature || ($signature !== $secretHash)) {
    // Silently fail if signature doesn't match
    http_response_code(401);
    exit();
}

// --- Get Payload ---
$body = @file_get_contents("php://input");
$data = json_decode($body, true);

if (!$data || !isset($data['event']) || $data['event'] !== 'charge.completed') {
    http_response_code(200);
    exit();
}

$txData = $data['data'];
$tx_ref = $txData['tx_ref'];
$status = $txData['status'];
$amount = $txData['amount'];
$currency = $txData['currency'];
$customerEmail = $txData['customer']['email'];

if ($status === 'successful') {
    // Instantiate Models
    $db = new Database();
    $paymentModel = new Payment();
    $walletModel = new Wallet();
    $clubModel = new Club();
    $fineModel = new Fine();
    $fixtureModel = new Fixture();
    $notificationModel = new Notification();

    // --- DUPLICATE TRANSACTION CHECK ---
    if ($paymentModel->findByRef($tx_ref)) {
        http_response_code(200);
        exit();
    }

    // --- CURRENCY VERIFICATION ---
    $expected_currency = $settings['system_currency'] ?? 'USD';
    if ($currency !== $expected_currency) {
        error_log("Webhook currency mismatch for tx_ref: $tx_ref. Expected $expected_currency, got $currency.");
        http_response_code(400); // Bad request
        exit();
    }

    // Find User
    $userModel = new User();
    $user = $userModel->findByEmail($customerEmail);
    if (!$user) {
        // Can't find user, but acknowledge receipt to stop retries.
        http_response_code(200);
        exit();
    }
    $user_id = $user->id;

    // --- Logic based on tx_ref prefix ---

    // 1. Wallet Deposit
    if (strpos($tx_ref, 'wallet_') === 0) {
        $userWallet = $walletModel->getOrCreateWallet('user', $user_id);
        $walletModel->deposit($userWallet->id, $amount, "Deposit via Flutterwave (Webhook)", $tx_ref);
        
        $paymentModel->create([
            'user_id' => $user_id,
            'amount' => $amount,
            'currency' => $currency,
            'transaction_ref' => $tx_ref,
            'payment_gateway' => 'flutterwave',
            'status' => 'successful',
            'metadata' => json_encode($txData)
        ]);
    }
    
    // 2. Membership Purchase
    elseif (strpos($tx_ref, 'mem_') === 0) {
        $package_id = null;
        $club_id = null;
        
        if (isset($txData['meta']['package_id'])) {
            $package_id = $txData['meta']['package_id'];
            $club_id = $txData['meta']['club_id'] ?? null;
        } elseif (is_array($txData['meta'])) {
            foreach ($txData['meta'] as $m) {
                if (isset($m['metaname']) && $m['metaname'] == 'package_id') $package_id = $m['metavalue'];
                if (isset($m['metaname']) && $m['metaname'] == 'club_id') $club_id = $m['metavalue'];
            }
        }

        if ($package_id && $club_id) {
            $package = $clubModel->getMembershipPackageById($package_id);
            if ($package) {
                // Verify Amount
                if (abs($amount - $package->price) > 0.01) {
                    error_log("Webhook amount mismatch for membership tx_ref: $tx_ref. Expected {$package->price}, got {$amount}.");
                    http_response_code(400);
                    exit();
                }

                $expiry_date = date('Y-m-d');
                if ($package->duration_type === 'monthly') $expiry_date = date('Y-m-d', strtotime('+1 month'));
                elseif ($package->duration_type === 'termly') $expiry_date = date('Y-m-d', strtotime('+3 months'));
                elseif ($package->duration_type === 'yearly') $expiry_date = date('Y-m-d', strtotime('+1 year'));

                $clubModel->createMembership([
                    'user_id' => $user_id,
                    'club_id' => $club_id,
                    'membership_type' => $package->name,
                    'start_date' => date('Y-m-d'),
                    'expiry_date' => $expiry_date
                ]);

                $walletModel->distributePaymentWithCommission($amount, 'membership', 'club', $club_id, "Membership: " . $package->name, $tx_ref);

                $paymentModel->create([
                    'user_id' => $user_id,
                    'amount' => $amount,
                    'currency' => $currency,
                    'transaction_ref' => $tx_ref,
                    'payment_gateway' => 'flutterwave',
                    'status' => 'successful',
                    'metadata' => json_encode($txData)
                ]);
            }
        }
    }

    // 3. Referee Fee
    elseif (strpos($tx_ref, 'REF-FEE-GW-') === 0) {
        $fixture_id = null;
        $team_id = null;
        
        if (isset($txData['meta']['fixture_id'])) {
            $fixture_id = $txData['meta']['fixture_id'];
            $team_id = $txData['meta']['team_id'];
        } elseif (is_array($txData['meta'])) {
            foreach ($txData['meta'] as $m) {
                if (isset($m['metaname']) && $m['metaname'] == 'fixture_id') $fixture_id = $m['metavalue'];
                if (isset($m['metaname']) && $m['metaname'] == 'team_id') $team_id = $m['metavalue'];
            }
        }

        if ($fixture_id && $team_id) {
            $fixture = $fixtureModel->findById($fixture_id);
            if ($fixture) {
                // Verify Amount
                $expected_amount = (float)($settings['referee_fee'] ?? 50);
                if (abs($amount - $expected_amount) > 0.01) {
                    error_log("Webhook amount mismatch for referee fee tx_ref: $tx_ref. Expected {$expected_amount}, got {$amount}.");
                    http_response_code(400);
                    exit();
                }

                $column = ($fixture->home_team_id == $team_id) ? 'home_team_paid_referee' : 'away_team_paid_referee';
                $db->query("UPDATE fixtures SET $column = 1 WHERE id = :id");
                $db->bind(':id', $fixture_id);
                $db->execute();

                $walletModel->distributePaymentWithCommission($amount, 'referee_fee', 'board', 0, "Referee Fee: Match #$fixture_id", $tx_ref);

                $paymentModel->create([
                    'user_id' => $user_id,
                    'amount' => $amount,
                    'currency' => $currency,
                    'transaction_ref' => $tx_ref,
                    'payment_gateway' => 'flutterwave',
                    'status' => 'successful',
                    'metadata' => json_encode($txData)
                ]);
            }
        }
    }

    // 4. Fines
    elseif (strpos($tx_ref, 'club_fine_') === 0 || strpos($tx_ref, 'team_fine_') === 0 || strpos($tx_ref, 'SF-FINES-') === 0) {
        $fine_ids_string = null;
        
        if (isset($txData['meta']['fine_ids'])) {
            $fine_ids_string = $txData['meta']['fine_ids'];
        } elseif (is_array($txData['meta'])) {
            foreach ($txData['meta'] as $m) {
                if (isset($m['metaname']) && $m['metaname'] == 'fine_ids') $fine_ids_string = $m['metavalue'];
            }
        }

        if ($fine_ids_string) {
            $fine_ids = explode(',', $fine_ids_string);
            $fines = $fineModel->getFinesByIds($fine_ids);

            // Verify Amount
            $expected_amount = 0;
            foreach ($fines as $fine) {
                $expected_amount += $fine->amount;
            }
            if (abs($amount - $expected_amount) > 0.01) {
                error_log("Webhook amount mismatch for fines tx_ref: $tx_ref. Expected {$expected_amount}, got {$amount}.");
                http_response_code(400);
                exit();
            }
            
            $fineModel->markAsPaid($fine_ids);
            
            $walletModel->distributePaymentWithCommission($amount, 'fine', 'board', 0, "Fine Payment (" . count($fines) . " items)", $tx_ref);

           // --- Determine Source Wallet for Ledger ---
            $source_wallet_id = null;
            $deposit_desc = "Deposit for Fine Payment (Online)";
            
            if (isset($txData['meta']['user_id'])) {
                // team_manager context has a user_id
                $teamModel = new Team();
                $team = $teamModel->getTeamByManagerId($txData['meta']['user_id']);
                if ($team) {
                    $wallet = $walletModel->getOrCreateWallet('team', $team->id);
                    $source_wallet_id = $wallet->id;
                    $walletModel->deposit($source_wallet_id, $amount, $deposit_desc, $tx_ref);
                }
            } else {
                 //club_manager context doesn't have a user_id
                //Wallet deposit handled in verify, because it already contains the appropriate club context.
            }

            foreach ($fines as $fine) {
                if ($fine->entity_type === 'player' && !empty($fine->player_id)) {
                    $msg = "Your fine of {$currency} " . number_format($fine->amount, 2) . " for '{$fine->reason}' has been paid.";
                    $notificationModel->create($fine->player_id, 'fine_paid', $msg);
                }
            }

            $paymentModel->create([
                'user_id' => $user_id,
                'amount' => $amount,
                'currency' => $currency,
                'transaction_ref' => $tx_ref,
                'payment_gateway' => 'flutterwave',
                'status' => 'successful',
                'metadata' => json_encode(['fine_ids' => $fine_ids_string])
            ]);
        }
    }
}

http_response_code(200);

?>