<?php
/**
 * سودانا — InvestmentEngine v2
 * الاستثمار الإسلامي الكامل
 * مضاربة — مشاركة — مرابحة — سلم — إجارة
 */
require_once __DIR__ . '/BankAdapter.php';
require_once __DIR__ . '/AccountingEngine.php';

class InvestmentEngine {

    const PLATFORM_FEE_PCT  = 0.02;  // 2% رسوم إدارة
    const PROFIT_SHARE_PCT  = 0.05;  // 5% من الأرباح
    const SAFETY_POOL_PCT   = 0.01;  // 1% صندوق ضمان
    const MIN_INVEST_SDG    = 5000;
    const MAX_RISK_LEVEL    = 3;

    // ── createProject(): إنشاء مشروع ─────────────────────────
    public static function createProject(int $userId, array $data): array {
        try {
            // تحقق من KYC
            $kyc = db()->prepare("SELECT kyc_level FROM sdpay_accounts WHERE user_id=? LIMIT 1");
            $kyc->execute([$userId]);
            $kycRow = $kyc->fetch();
            if (!$kycRow || (int)$kycRow['kyc_level'] < 2)
                return ['ok'=>false,'error'=>'kyc_required','message'=>'يجب إكمال التحقق من الهوية'];

            $projectId = self::insertProject($userId, $data);
            return ['ok'=>true,'project_id'=>$projectId,'status'=>'draft'];
        } catch (Throwable $e) {
            return ['ok'=>false,'error'=>$e->getMessage()];
        }
    }

    // ── invest(): الاشتراك في مشروع ──────────────────────────
    public static function invest(int $userId, int $projectId, float $amount, string $pin): array {
        require_once __DIR__ . '/SudannaPayEngine.php';
        try {
            if ($amount < self::MIN_INVEST_SDG)
                return ['ok'=>false,'error'=>'min_amount','message'=>'الحد الأدنى '.number_format(self::MIN_INVEST_SDG).' SDG'];

            // تحقق من المشروع
            $proj = db()->prepare("SELECT * FROM invest_projects WHERE id=? AND status='active' LIMIT 1");
            $proj->execute([$projectId]);
            $p = $proj->fetch();
            if (!$p) return ['ok'=>false,'error'=>'project_not_found'];

            // تحقق من الحد الأقصى
            $remaining = (float)$p['target_sdg'] - (float)$p['collected_sdg'];
            if ($amount > $remaining) $amount = $remaining;

            // تحقق من PIN وخصم
            if (!SudannaPayEngine::verifyPin($userId, $pin))
                return ['ok'=>false,'error'=>'invalid_pin'];

            $acc = SudannaPayEngine::getAccount($userId);
            if (!$acc || (float)$acc['balance_sdg'] < $amount)
                return ['ok'=>false,'error'=>'insufficient_balance'];

            db()->beginTransaction();
            try {
                // خصم من المحفظة
                db()->prepare("UPDATE sdpay_accounts SET balance_sdg=balance_sdg-? WHERE user_id=?")->execute([$amount,$userId]);

                // خصم صندوق الضمان
                $safetyPool = $amount * self::SAFETY_POOL_PCT;
                db()->prepare(
                    "INSERT INTO invest_safety_pool (project_id,contributor_user_id,amount_sdg)
                     VALUES (?,?,?)"
                )->execute([$projectId,$userId,$safetyPool]);

                // حصة المستثمر
                $sharePct = $amount / (float)$p['target_sdg'] * 100;
                $contractRef = 'MDR' . date('Y') . strtoupper(substr(md5(uniqid()),0,8));
                db()->prepare(
                    "INSERT INTO invest_shares (project_id,investor_user_id,amount_sdg,share_pct,contract_ref,contract_signed_at)
                     VALUES (?,?,?,?,?,NOW())"
                )->execute([$projectId,$userId,$amount,$sharePct,$contractRef]);

                // تحديث المجموع المجمَّع
                db()->prepare("UPDATE invest_projects SET collected_sdg=collected_sdg+? WHERE id=?")->execute([$amount,$projectId]);

                // تحقق من اكتمال التمويل
                $newCollected = (float)$p['collected_sdg'] + $amount;
                if ($newCollected >= (float)$p['target_sdg']) {
                    db()->prepare("UPDATE invest_projects SET status='funded' WHERE id=?")->execute([$projectId]);
                }

                // معاملة في سجل Pay
                db()->prepare(
                    "INSERT INTO sdpay_transactions (txn_ref,type,from_account,amount_sdg,fee_sdg,net_sdg,status,narration,metadata)
                     VALUES (?,?,?,?,0,?,'completed',?,?)"
                )->execute([
                    'INV'.date('YmdHis').substr(md5(uniqid()),0,6),
                    'invest', $acc['account_no'], $amount, $amount,
                    'استثمار في: '.$p['title'],
                    json_encode(['project_id'=>$projectId,'contract_ref'=>$contractRef,'share_pct'=>$sharePct])
                ]);

                db()->commit();
                // القيد المحاسبي
                try { AccountingEngine::updatePlatformRevenue('invest_fee', $amount * self::PLATFORM_FEE_PCT); }
                catch (\Throwable $ignored) {}
                return [
                    'ok'           => true,
                    'contract_ref' => $contractRef,
                    'amount_sdg'   => $amount,
                    'share_pct'    => round($sharePct,2),
                    'project'      => $p['title'],
                    'expected_return'=> round($amount * (float)$p['expected_return_pct']/100, 2),
                    'message'      => 'تم الاشتراك في المشروع بنجاح',
                ];
            } catch (Throwable $e) {
                db()->rollBack();
                throw $e;
            }
        } catch (Throwable $e) {
            return ['ok'=>false,'error'=>$e->getMessage()];
        }
    }

    // ── distributeReturns(): توزيع الأرباح ───────────────────
    public static function distributeReturns(int $projectId, float $totalProfitSdg, string $bankRef = ''): array {
        // تأكيد إيداع خارجي من البنك
        if ($bankRef && class_exists('BankAdapter')) {
            $bc = BankAdapter::confirmExternalCredit($bankRef, $totalProfitSdg, $projectId, 0);
            if (!($bc['confirmed']??false) && !($bc['sandbox']??false)) {
                return ['ok'=>false,'error'=>'bank_credit_not_confirmed','bank_ref'=>$bankRef];
            }
        }
        require_once __DIR__ . '/SudannaPayEngine.php';
        try {
            $shares = db()->prepare(
                "SELECT * FROM invest_shares WHERE project_id=? AND status='active'"
            );
            $shares->execute([$projectId]);
            $allShares = $shares->fetchAll();

            $proj = db()->prepare("SELECT * FROM invest_projects WHERE id=? LIMIT 1");
            $proj->execute([$projectId]);
            $p = $proj->fetch();

            $investorSharePct = (float)($p['investor_share_pct'] ?? 60) / 100;
            $platformFee      = $totalProfitSdg * self::PROFIT_SHARE_PCT;
            $investorTotal    = $totalProfitSdg * $investorSharePct - $platformFee;

            $distributed = 0;
            foreach ($allShares as $share) {
                $investorProfit = $investorTotal * ((float)$share['share_pct'] / 100);
                $payout = (float)$share['amount_sdg'] + $investorProfit;

                // أعِد رأس المال + الربح
                db()->prepare("UPDATE sdpay_accounts SET balance_sdg=balance_sdg+? WHERE user_id=?")
                   ->execute([$payout, $share['investor_user_id']]);

                db()->prepare("UPDATE invest_shares SET profit_sdg=?,status='completed' WHERE id=?")
                   ->execute([$investorProfit, $share['id']]);

                $distributed += $payout;
            }

            db()->prepare("UPDATE invest_projects SET status='completed' WHERE id=?")->execute([$projectId]);

            return ['ok'=>true,'distributed_sdg'=>$distributed,'platform_fee_sdg'=>$platformFee];
        } catch (Throwable $e) {
            return ['ok'=>false,'error'=>$e->getMessage()];
        }
    }

    // ── getProjects(): قائمة المشاريع ─────────────────────────
    public static function getProjects(string $status='active', string $model='', int $limit=20): array {
        try {
            $where = '1=1';
            $params = [];
            if ($status) { $where .= ' AND status=?'; $params[] = $status; }
            if ($model)  { $where .= ' AND model=?'; $params[] = $model; }
            $st = db()->prepare(
                "SELECT p.*,
                 ROUND((p.collected_sdg/p.target_sdg)*100,1) as progress_pct,
                 (SELECT COUNT(*) FROM invest_shares WHERE project_id=p.id AND status='active') as investor_count
                 FROM invest_projects p WHERE {$where} ORDER BY p.created_at DESC LIMIT ?"
            );
            $st->execute(array_merge($params, [$limit]));
            return $st->fetchAll();
        } catch (Throwable $e) { return []; }
    }

    // ── getMyPortfolio(): محفظتي الاستثمارية ─────────────────
    public static function getMyPortfolio(int $userId): array {
        try {
            $st = db()->prepare(
                "SELECT s.*, p.title, p.model, p.status as project_status,
                 p.expected_return_pct, p.end_date, p.collected_sdg, p.target_sdg
                 FROM invest_shares s
                 JOIN invest_projects p ON p.id=s.project_id
                 WHERE s.investor_user_id=? ORDER BY s.created_at DESC"
            );
            $st->execute([$userId]);
            $shares = $st->fetchAll();

            $totalInvested = array_sum(array_column($shares,'amount_sdg'));
            $totalProfit   = array_sum(array_column($shares,'profit_sdg'));
            return [
                'shares'         => $shares,
                'total_invested' => (float)$totalInvested,
                'total_profit'   => (float)$totalProfit,
                'active_count'   => count(array_filter($shares, fn($s)=>$s['status']==='active')),
            ];
        } catch (Throwable $e) { return ['shares'=>[],'total_invested'=>0,'total_profit'=>0,'active_count'=>0]; }
    }

    // ── insertProject() ───────────────────────────────────────
    private static function insertProject(int $userId, array $data): int {
        db()->prepare(
            "INSERT INTO invest_projects
             (owner_user_id,title,description,model,risk_level,target_sdg,
              min_invest_sdg,expected_return_pct,investor_share_pct,duration_days)
             VALUES (?,?,?,?,?,?,?,?,?,?)"
        )->execute([
            $userId,
            trim($data['title'] ?? ''),
            trim($data['description'] ?? ''),
            in_array($data['model']??'',['mudarabah','musharakah','salam','ijarah','murabahah'])
                ? $data['model'] : 'mudarabah',
            min(max((int)($data['risk_level']??1),1),3),
            (float)($data['target_sdg'] ?? 0),
            max((float)($data['min_invest_sdg']??self::MIN_INVEST_SDG), self::MIN_INVEST_SDG),
            (float)($data['expected_return_pct'] ?? 15),
            min(max((float)($data['investor_share_pct']??60),40),80),
            max((int)($data['duration_days']??90),30),
        ]);
        return (int)db()->lastInsertId();
    }
}
