<?php
declare(strict_types=1);

namespace App\Modules\Members\Services;

use App\Core\App;
use App\Modules\Rules\Services\RuleEngine;
use App\Modules\ServiceCatalog\Models\ServicePrice;

/**
 * Determines whether a dependant addition needs a form fee (570 EGP).
 *
 * Business rule — the boundary is the MEMBERSHIP NUMBER:
 * - Before the member gets a membership number (hasn't paid membership yet),
 *   all additions are on the initial 505 EGP form — no extra form fee.
 *   This covers all pre-activation statuses: potential, under_review,
 *   interview_scheduled, accepted, payment_pending.
 * - After activation (member has a membership number), every addition costs
 *   an additional 570 EGP form fee PER PERSON on top of the dependant's own fees.
 *   Free dependants (1st spouse, first 2 children under 18) remain free — only
 *   the 570 form fee applies, and free slots are still free (no 570 either).
 */
final class FormFeeService
{
    /**
     * Check if the member is still on the initial membership form.
     * True = no membership number yet = pre-activation = all on same 505 form.
     */
    public static function isOnInitialForm(array $member): bool
    {
        return empty($member['membership_number']);
    }

    /**
     * Get the form fee for adding a dependant.
     * Returns '0.00' if still on initial form (no membership number).
     * Returns 570 EGP + annual subscription after activation.
     * Per regulations: "أي إضافة بعد إنشاء العضوية: 570 جنيه + الاشتراك السنوي"
     */
    public static function getFormFee(int $memberId, array $member): string
    {
        if (self::isOnInitialForm($member)) {
            return '0.00';
        }

        $feeData = RuleEngine::get('FORM_ADDITION_FEE');
        return ($feeData && isset($feeData['amount'])) ? $feeData['amount'] : ServicePrice::getPrice('SVC_ADDITION_FORM', '570.00');
    }

    /**
     * Get just the 570 form fee portion (without annual subscription).
     */
    public static function getFormFeeOnly(int $memberId, array $member): string
    {
        if (self::isOnInitialForm($member)) {
            return '0.00';
        }

        $feeData = RuleEngine::get('FORM_ADDITION_FEE');
        if ($feeData && isset($feeData['amount'])) {
            return $feeData['amount'];
        }
        return ServicePrice::getPrice('SVC_ADDITION_FORM', '570.00');
    }

    private static function getAnnualSubscriptionForAddition(): string
    {
        $month = (int) date('n');
        $year = (int) date('Y');
        $fy = $month >= 7 ? $year . '/' . ($year + 1) : ($year - 1) . '/' . $year;

        $ratesData = RuleEngine::get('membership.annual_rates.' . $fy);
        $childRate = $ratesData['child'] ?? '222';
        $devFee = $ratesData['dev'] ?? '35';

        return bcadd($childRate, $devFee, 2);
    }

    /**
     * Check if this spouse is in a "free" slot (zero dependant fee).
     * Free slots apply ALWAYS — on initial form AND after activation.
     * The only difference: after activation the 570 form fee is added.
     * On initial form: free slot = no fee at all.
     * After activation: free slot = 0 dependant fee + 570 form fee.
     */
    public static function isSpouseFreeSlot(int $memberId, int $spouseOrder): bool
    {
        $maxFree = (int) RuleEngine::requireValue('INITIAL_FREE_SPOUSES_COUNT', 'value');
        return $spouseOrder <= $maxFree;
    }

    /**
     * @deprecated Use isSpouseFreeSlot() instead
     */
    public static function isSpouseFreeOnInitialForm(int $memberId, int $spouseOrder, array $member): bool
    {
        return self::isSpouseFreeSlot($memberId, $spouseOrder);
    }

    /**
     * Check if this child is in a "free" slot (zero dependant fee).
     * Free slots apply ALWAYS. After activation: 0 dependant fee + 570 form fee.
     * On initial form: no fee at all.
     */
    public static function isChildFreeSlot(int $memberId, int $childOrder, int $childAge): bool
    {
        $maxFreeCount = (int) RuleEngine::requireValue('INITIAL_FREE_CHILDREN_COUNT', 'value');
        $maxFreeAge = (int) RuleEngine::requireValue('CHILD_INCLUDED_MAX_AGE', 'value');
        return $childOrder <= $maxFreeCount && $childAge < $maxFreeAge;
    }

    /**
     * @deprecated Use isChildFreeSlot() instead
     */
    public static function isChildFreeOnInitialForm(int $memberId, int $childOrder, int $childAge, array $member): bool
    {
        return self::isChildFreeSlot($memberId, $childOrder, $childAge);
    }
}
