<?php
/**
 * سودانا — ROSCAEngine v2
 * الصندوق الرقمي (شيل/صندوق) — ROSCA
 * Rotating Savings and Credit Association
 */
require_once __DIR__ . '/AccountingEngine.php';

class ROSCAEngine {

    // ── create(): إنشاء صندوق جديد ───────────────────────────
    public static function create(int $userId, array $data): array {
        require_once __DIR__ . '/SudannaPayEngine.php';
        try {
            $acc = SudannaPayEngine::getAccount($userId);
            if (!$acc) return ['ok'=>false,'error'=>'no_pay_account'];

            db()->prepare(
                "INSERT INTO sdpay_roscas
                 (creator_user_id,name,description,monthly_amount_sdg,max_members,
                  order_type,status,collection_day)
                 VALUES (?,?,?,?,?,?,'open',?)"
            )->execute([
                $userId,
                trim($data['name'] ?? 'صندوقي'),
                trim($data['description'] ?? ''),
                (float)($data['monthly_amount_sdg'] ?? 0),
                min((int)($data['max_members'] ?? 10), 50),
                in_array($data['order_type']??'',['sequential','lottery'])?$data['order_type']:'sequential',
                (int)($data['collection_day'] ?? 1),
            ]);
            $id = db()->lastInsertId();

            // منشئ الصندوق يكون أول عضو
            db()->prepare(
                "INSERT INTO sdpay_rosca_members (rosca_id,user_id,turn_order,status)
                 VALUES (?,?,1,'active')"
            )->execute([$id, $userId]);

            return ['ok'=>true,'rosca_id'=>$id];
        } catch (Throwable $e) {
            return ['ok'=>false,'error'=>$e->getMessage()];
        }
    }

    // ── join(): الانضمام لصندوق ───────────────────────────────
    public static function join(int $userId, int $roscaId): array {
        require_once __DIR__ . '/SudannaPayEngine.php';
        try {
            $acc = SudannaPayEngine::getAccount($userId);
            if (!$acc) return ['ok'=>false,'error'=>'no_pay_account'];

            $rosca = db()->prepare("SELECT * FROM sdpay_roscas WHERE id=? AND status='open' LIMIT 1");
            $rosca->execute([$roscaId]);
            $r = $rosca->fetch();
            if (!$r) return ['ok'=>false,'error'=>'rosca_not_found_or_closed'];

            // تحقق من العضوية
            $mem = db()->prepare("SELECT id FROM sdpay_rosca_members WHERE rosca_id=? AND user_id=? LIMIT 1");
            $mem->execute([$roscaId, $userId]);
            if ($mem->fetch()) return ['ok'=>false,'error'=>'already_member'];

            // عدد الأعضاء الحاليين
            $cnt = db()->prepare("SELECT COUNT(*) FROM sdpay_rosca_members WHERE rosca_id=?");
            $cnt->execute([$roscaId]);
            $currentCount = (int)$cnt->fetchColumn();

            if ($currentCount >= $r['max_members'])
                return ['ok'=>false,'error'=>'rosca_full'];

            $turnOrder = $currentCount + 1;
            db()->prepare(
                "INSERT INTO sdpay_rosca_members (rosca_id,user_id,turn_order,status)
                 VALUES (?,?,?,'active')"
            )->execute([$roscaId, $userId, $turnOrder]);

            // إذا اكتمل الصندوق — ابدأ
            if ($turnOrder >= $r['max_members']) {
                db()->prepare("UPDATE sdpay_roscas SET status='active',current_round=1 WHERE id=?")->execute([$roscaId]);
                if ($r['order_type'] === 'lottery') self::shuffleTurns($roscaId);
            }

            return ['ok'=>true,'turn_order'=>$turnOrder,'members_count'=>$turnOrder];
        } catch (Throwable $e) {
            return ['ok'=>false,'error'=>$e->getMessage()];
        }
    }

    // ── collect(): تحصيل الدفعة الشهرية ──────────────────────
    public static function collect(int $roscaId): array {
        require_once __DIR__ . '/SudannaPayEngine.php';
        try {
            $rosca = db()->prepare("SELECT * FROM sdpay_roscas WHERE id=? AND status='active' LIMIT 1");
            $rosca->execute([$roscaId]);
            $r = $rosca->fetch();
            if (!$r) return ['ok'=>false,'error'=>'rosca_not_active'];

            // المستفيد هذا الشهر
            $currentRound = (int)$r['current_round'];
            $beneficiary = db()->prepare(
                "SELECT rm.*, u.name, sa.account_no
                 FROM sdpay_rosca_members rm
                 JOIN users u ON u.id=rm.user_id
                 JOIN sdpay_accounts sa ON sa.user_id=rm.user_id
                 WHERE rm.rosca_id=? AND rm.turn_order=? LIMIT 1"
            );
            $beneficiary->execute([$roscaId, $currentRound]);
            $ben = $beneficiary->fetch();
            if (!$ben) return ['ok'=>false,'error'=>'beneficiary_not_found'];

            // جمع من كل الأعضاء
            $members = db()->prepare(
                "SELECT rm.user_id, u.name, sa.account_no, sa.balance_sdg
                 FROM sdpay_rosca_members rm
                 JOIN users u ON u.id=rm.user_id
                 JOIN sdpay_accounts sa ON sa.user_id=rm.user_id
                 WHERE rm.rosca_id=? AND rm.status='active'"
            );
            $members->execute([$roscaId]);
            $allMembers = $members->fetchAll();

            $amount = (float)$r['monthly_amount_sdg'];
            $collected = 0;
            $failed = [];

            db()->beginTransaction();
            try {
                foreach ($allMembers as $m) {
                    if ((float)$m['balance_sdg'] >= $amount) {
                        db()->prepare("UPDATE sdpay_accounts SET balance_sdg=balance_sdg-? WHERE user_id=?")
                           ->execute([$amount, $m['user_id']]);
                        $collected += $amount;
                    } else {
                        $failed[] = $m['name'];
                    }
                }

                // حوِّل المجموع للمستفيد
                if ($collected > 0) {
                    db()->prepare("UPDATE sdpay_accounts SET balance_sdg=balance_sdg+? WHERE user_id=?")
                       ->execute([$collected, $ben['user_id']]);

                    db()->prepare("UPDATE sdpay_rosca_members SET has_received=1 WHERE rosca_id=? AND user_id=?")
                       ->execute([$roscaId, $ben['user_id']]);
                }

                // الدورة التالية
                $totalMembers = count($allMembers);
                if ($currentRound >= $totalMembers) {
                    db()->prepare("UPDATE sdpay_roscas SET status='completed' WHERE id=?")->execute([$roscaId]);
                } else {
                    db()->prepare("UPDATE sdpay_roscas SET current_round=current_round+1 WHERE id=?")->execute([$roscaId]);
                }

                db()->commit();
                // القيد المحاسبي
                try {
                    AccountingEngine::updatePlatformRevenue('transfer_fee', 0);
                } catch (\Throwable $ignored) {}
                return [
                    'ok'          => true,
                    'collected'   => $collected,
                    'beneficiary' => $ben['name'],
                    'failed'      => $failed,
                    'next_round'  => $currentRound + 1,
                ];
            } catch (Throwable $e) {
                db()->rollBack();
                throw $e;
            }
        } catch (Throwable $e) {
            return ['ok'=>false,'error'=>$e->getMessage()];
        }
    }

    // ── getMyRoscas(): صناديقي ────────────────────────────────
    public static function getMyRoscas(int $userId): array {
        try {
            $st = db()->prepare(
                "SELECT r.*, rm.turn_order, rm.has_received,
                 (SELECT COUNT(*) FROM sdpay_rosca_members WHERE rosca_id=r.id) as member_count
                 FROM sdpay_roscas r
                 JOIN sdpay_rosca_members rm ON rm.rosca_id=r.id AND rm.user_id=?
                 ORDER BY r.created_at DESC"
            );
            $st->execute([$userId]);
            return $st->fetchAll();
        } catch (Throwable $e) { return []; }
    }

    // ── shuffleTurns(): ترتيب عشوائي (قرعة) ─────────────────
    private static function shuffleTurns(int $roscaId): void {
        try {
            $members = db()->prepare("SELECT id FROM sdpay_rosca_members WHERE rosca_id=? ORDER BY RAND()");
            $members->execute([$roscaId]);
            $rows = $members->fetchAll();
            foreach ($rows as $i => $row) {
                db()->prepare("UPDATE sdpay_rosca_members SET turn_order=? WHERE id=?")->execute([$i+1, $row['id']]);
            }
        } catch (Throwable $ignored) {}
    }
}
