<?php
/**
 * سودانا — CashFlowEngine v1
 * PRINCIPLE: Sudanna NEVER holds money (NO_CUSTODY)
 * Analyzes spending patterns + calculates available flow
 * Works as shadow ledger — bank is source of truth
 */
class CashFlowEngine {

    /**
     * Analyze user spending patterns + available flow
     * Returns structured cash flow summary
     */
    public static function analyze(int $userId, string $period = '30d'): array {
        $days = self::periodToDays($period);
        $since = date('Y-m-d H:i:s', strtotime("-{$days} days"));

        try {
            // Wallet balance (shadow — bank is truth)
            $balance = (float)(db()->query(
                "SELECT COALESCE(balance_sdg,0) FROM wallet WHERE user_id=$userId"
            )->fetchColumn() ?: 0);

            // Total spent in period
            $spent = (float)(db()->prepare(
                "SELECT COALESCE(SUM(amount_sdg),0) FROM wallet_transactions
                 WHERE user_id=? AND type='debit' AND created_at>=?"
            )->execute([$userId,$since]) ?
                db()->prepare(
                    "SELECT COALESCE(SUM(amount_sdg),0) FROM wallet_transactions
                     WHERE user_id=? AND type='debit' AND created_at>=?"
                )->execute([$userId,$since]) : 0);

            // Re-run query properly
            $spentQ = db()->prepare(
                "SELECT COALESCE(SUM(amount_sdg),0) FROM wallet_transactions
                 WHERE user_id=? AND type='debit' AND created_at>=?"
            );
            $spentQ->execute([$userId, $since]);
            $spent = (float)$spentQ->fetchColumn();

            // Total deposited in period
            $depositQ = db()->prepare(
                "SELECT COALESCE(SUM(amount_sdg),0) FROM wallet_transactions
                 WHERE user_id=? AND type='credit' AND created_at>=?"
            );
            $depositQ->execute([$userId, $since]);
            $deposited = (float)$depositQ->fetchColumn();

            // Transaction count
            $txnQ = db()->prepare(
                "SELECT COUNT(*) FROM wallet_transactions
                 WHERE user_id=? AND created_at>=?"
            );
            $txnQ->execute([$userId, $since]);
            $txnCount = (int)$txnQ->fetchColumn();

            // Average transaction size
            $avgSize = $txnCount > 0 ? round($spent / $txnCount, 2) : 0;

            // Daily burn rate
            $dailyBurn = $days > 0 ? round($spent / $days, 2) : 0;

            // Projected runway (days with current balance)
            $runway = $dailyBurn > 0 ? round($balance / $dailyBurn) : 999;

            // Spending categories
            $catQ = db()->prepare(
                "SELECT ref_type, COUNT(*) as cnt, COALESCE(SUM(amount_sdg),0) as total
                 FROM wallet_transactions
                 WHERE user_id=? AND type='debit' AND created_at>=?
                 GROUP BY ref_type ORDER BY total DESC"
            );
            $catQ->execute([$userId, $since]);
            $categories = $catQ->fetchAll(PDO::FETCH_ASSOC);

            return [
                'user_id'     => $userId,
                'period'      => $period,
                'balance_sdg' => $balance,
                'spent_sdg'   => $spent,
                'deposited_sdg'=> $deposited,
                'net_flow'    => $deposited - $spent,
                'txn_count'   => $txnCount,
                'avg_txn_size'=> $avgSize,
                'daily_burn'  => $dailyBurn,
                'runway_days' => $runway,
                'categories'  => $categories,
                'health'      => self::healthScore($balance, $dailyBurn, $txnCount),
                'trace_id'    => uniqid('cf_', true),
                'generated_at'=> date('Y-m-d H:i:s'),
            ];
        } catch (Throwable $e) {
            error_log("[CashFlowEngine] " . $e->getMessage());
            return ['error' => $e->getMessage(), 'user_id' => $userId];
        }
    }

    /**
     * Check if user can afford a specific amount
     */
    public static function canAfford(int $userId, float $amount): array {
        try {
            $balance = (float)(db()->query(
                "SELECT COALESCE(balance_sdg,0) FROM wallet WHERE user_id=$userId"
            )->fetchColumn() ?: 0);

            $canAfford = $balance >= $amount;
            return [
                'can_afford'   => $canAfford,
                'balance'      => $balance,
                'amount'       => $amount,
                'shortfall'    => $canAfford ? 0 : round($amount - $balance, 2),
                'trace_id'     => uniqid('ca_', true),
            ];
        } catch (Throwable $e) {
            return ['can_afford' => false, 'error' => $e->getMessage()];
        }
    }

    // ── Private helpers ─────────────────────────────────────────
    private static function periodToDays(string $period): int {
        return match($period) {
            '7d'  => 7,
            '30d' => 30,
            '90d' => 90,
            default => 30,
        };
    }

    private static function healthScore(float $balance, float $burn, int $txns): string {
        if ($balance <= 0)          return 'critical';
        if ($burn > 0 && $balance / $burn < 3) return 'low';
        if ($txns > 50)             return 'active';
        return 'healthy';
    }

    // ── record(): تسجيل حركة تدفق نقدي ──────────────────────
    public static function record(string $type, float $amount, string $reference = ''): void {
        require_once __DIR__ . '/AccountingEngine.php';
        AccountingEngine::updatePlatformRevenue($type, $amount);
    }

    // ── forecast(): توقعات التدفق النقدي ─────────────────────
    public static function forecast(int $days = 30): array {
        try {
            // متوسط الإيراد اليومي (آخر 7 أيام)
            $st = db()->prepare(
                "SELECT AVG(daily_rev) as avg_daily FROM (
                   SELECT DATE(created_at) as d, SUM(fee_sdg) as daily_rev
                   FROM sdpay_transactions WHERE status='completed' AND created_at >= DATE_SUB(NOW(),INTERVAL 7 DAY)
                   GROUP BY DATE(created_at)
                 ) t"
            );
            $st->execute([]);
            $avgDaily = (float)($st->fetchColumn() ?? 0);
            return [
                'avg_daily_revenue' => $avgDaily,
                'forecast_30d'      => $avgDaily * $days,
                'days'              => $days,
                'basis'             => 'last_7_days',
            ];
        } catch (\Throwable $e) { return ['error'=>$e->getMessage()]; }
    }

}
