<?php
declare(strict_types=1);

namespace App\Modules\Installments\Services;

use App\Core\App;
use App\Core\Logger;
use App\Modules\Members\Services\MemberNumberGenerator;
use App\Core\EventBus;

final class ChequeService
{
    /**
     * Return the next sequential cheque number across ALL plans (global).
     * Used for single-upload suggestions only.
     */
    public static function nextChequeNumber(): int
    {
        $db  = App::getInstance()->db();
        $row = $db->selectOne(
            "SELECT MAX(CAST(cheque_number AS UNSIGNED)) AS max_num
             FROM installment_cheques
             WHERE cheque_number REGEXP '^[0-9]+$'",
            []
        );
        return (int) ($row['max_num'] ?? 0) + 1;
    }

    /**
     * Return the next sequential cheque number within a specific plan.
     * Auto-generator uses this to continue from where the last cheque left off.
     */
    public static function nextChequeNumberForPlan(int $planId): int
    {
        $db  = App::getInstance()->db();
        $row = $db->selectOne(
            "SELECT MAX(CAST(cheque_number AS UNSIGNED)) AS max_num
             FROM installment_cheques
             WHERE installment_plan_id = ? AND cheque_number REGEXP '^[0-9]+$'",
            [$planId]
        );
        return (int) ($row['max_num'] ?? 0) + 1;
    }

    /**
     * Check if all required cheques have been uploaded for an installment plan.
     */
    public static function allChequesSubmitted(int $planId): bool
    {
        $db = App::getInstance()->db();

        $plan = $db->selectOne(
            "SELECT number_of_months FROM installment_plans WHERE id = ? AND status = 'active'",
            [$planId]
        );
        if (!$plan) {
            return false;
        }

        $uploadedCount = (int) $db->selectOne(
            "SELECT COUNT(*) as cnt FROM installment_cheques WHERE installment_plan_id = ?",
            [$planId]
        )['cnt'];

        return $uploadedCount >= (int) $plan['number_of_months'];
    }

    /**
     * After all cheques are submitted, activate the member and assign membership number.
     */
    public static function activateMemberAfterCheques(int $planId): array
    {
        $db = App::getInstance()->db();

        $plan = $db->selectOne(
            "SELECT id, member_id FROM installment_plans WHERE id = ? AND status = 'active'",
            [$planId]
        );
        if (!$plan) {
            return ['success' => false, 'error' => 'خطة التقسيط غير موجودة'];
        }

        $memberId = (int) $plan['member_id'];

        $member = $db->selectOne(
            "SELECT id, status, membership_number FROM members WHERE id = ? AND is_archived = 0",
            [$memberId]
        );
        if (!$member) {
            return ['success' => false, 'error' => 'العضو غير موجود'];
        }

        if ($member['status'] !== 'pending_cheques') {
            if ($member['status'] === 'active') {
                return ['success' => true, 'already_active' => true];
            }
            return ['success' => false, 'error' => 'حالة العضو لا تسمح بالتفعيل'];
        }

        if (!self::allChequesSubmitted($planId)) {
            return ['success' => false, 'error' => 'لم يتم رفع جميع الشيكات المطلوبة'];
        }

        $number = MemberNumberGenerator::assign($memberId);

        $db->update('members', [
            'status'     => 'active',
            'activated_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ], '`id` = ?', [$memberId]);

        EventBus::dispatch('member.activated', [
            'member_id'         => $memberId,
            'membership_number' => $number,
            'payment_method'    => 'installment',
        ]);

        Logger::info("ChequeService: member #{$memberId} activated after all cheques submitted for plan #{$planId}");

        return ['success' => true, 'membership_number' => $number];
    }
}
