<?php
declare(strict_types=1);

namespace App\Modules\Temporary\Services;

use App\Core\App;
use App\Modules\Rules\Services\RuleEngine;
use App\Modules\Members\Services\FormFeeService;

final class TemporaryFeeCalculator
{
    public static function calculate(int $memberId, array $tempData): array
    {
        $db = App::getInstance()->db();
        $member = $db->selectOne("SELECT * FROM members WHERE id = ? AND is_archived = 0", [$memberId]);
        if (!$member) {
            return ['fee' => '0.00', 'error' => 'العضو غير موجود'];
        }

        $membershipValue = $member['membership_value'] ?? '0.00';
        $isOnInitialForm = FormFeeService::isOnInitialForm($member);
        if (bccomp($membershipValue, '0.00', 2) <= 0 && !$isOnInitialForm) {
            return ['fee' => '0.00', 'error' => 'قيمة العضوية غير محددة'];
        }

        $hasChampionship = (bool) ($tempData['has_championship'] ?? false);

        $exemptData = RuleEngine::get('TEMP_CHAMPIONSHIP_EXEMPT');
        $isExempt = $hasChampionship && ($exemptData['exempt'] ?? true);

        if ($isExempt) {
            return [
                'fee'              => '0.00',
                'percentage'       => '0.00',
                'membership_value' => $membershipValue,
                'form_fee'         => '0.00',
                'total_fee'        => '0.00',
                'rule_applied'     => 'TEMP_CHAMPIONSHIP_EXEMPT',
                'exempt'           => true,
                'error'            => null,
            ];
        }

        $feeData = RuleEngine::get('TEMP_MEMBER_FEE');
        $pct = $feeData['percentage'] ?? '10.00';
        $fee = bcmul($membershipValue, bcdiv($pct, '100', 4), 2);

        $formFee = FormFeeService::getFormFee($memberId, $member);
        $totalFee = bcadd($fee, $formFee, 2);

        $category = $tempData['category'] ?? '—';
        $catLabels = [
            'parent' => 'والد/ة', 'special_needs' => 'ذوي احتياجات خاصة',
            'unmarried_daughter' => 'ابنة غير متزوجة', 'sister' => 'شقيقة',
            'stepchild' => 'ابن/ة زوج', 'orphan' => 'يتيم',
            'disabled_sibling' => 'شقيق معاق', 'nanny' => 'مربية',
        ];

        $breakdown = [];
        $breakdown[] = '📋 القاعدة المطبقة: TEMP_MEMBER_FEE';
        $breakdown[] = '💰 قيمة العضوية: ' . money($membershipValue);
        $breakdown[] = '📌 الفئة: ' . ($catLabels[$category] ?? $category);
        $breakdown[] = '📊 نسبة ' . $pct . '% × ' . money($membershipValue) . ' = ' . money($fee);
        if (bccomp($formFee, '0', 2) > 0) {
            $breakdown[] = '📝 رسوم استمارة إضافة: ' . money($formFee);
        }
        $breakdown[] = '═══════════════════════════';
        $breakdown[] = '💵 الإجمالي المطلوب: ' . money($totalFee);

        return [
            'membership_value' => $membershipValue,
            'fee'              => $fee,
            'percentage'       => $pct,
            'form_fee'         => $formFee,
            'total_fee'        => $totalFee,
            'rule_applied'     => 'TEMP_MEMBER_FEE',
            'exempt'           => false,
            'error'            => null,
            'breakdown'        => $breakdown,
        ];
    }

    public static function validateCategory(string $category, array $tempData, array $member): array
    {
        $errors = [];
        $age = (int) ($tempData['age_years'] ?? 0);

        $maxAgeRules = [
            'sister'    => 'SISTER_MAX_AGE',
            'stepchild' => 'STEPCHILD_MAX_AGE',
            'orphan'    => 'ORPHAN_MAX_AGE',
        ];

        switch ($category) {
            case 'parent':
                break;

            case 'special_needs':
                $minAge = (int) (RuleEngine::getValue('SPOUSE_WORKING_AGE_THRESHOLD', 'value') ?? 21);
                if ($age < $minAge) {
                    $errors[] = 'أبناء ذوي الاحتياجات الخاصة يجب أن يكونوا فوق ' . $minAge . ' سنة';
                }
                if (empty($tempData['disability_documentation'])) {
                    $errors[] = 'يجب تقديم وثائق الإعاقة';
                }
                break;

            case 'unmarried_daughter':
                if (($tempData['gender'] ?? '') !== 'female') {
                    $errors[] = 'هذه الفئة للإناث فقط';
                }
                break;

            case 'sister':
                $maxAge = (int) (RuleEngine::getValue('SISTER_MAX_AGE', 'value') ?? 25);
                if ($age >= $maxAge) {
                    $errors[] = 'شقيقة العضو يجب أن تكون أقل من ' . $maxAge . ' سنة';
                }
                if (($tempData['gender'] ?? '') !== 'female') {
                    $errors[] = 'هذه الفئة للإناث فقط';
                }
                break;

            case 'stepchild':
                $maxAge = (int) (RuleEngine::getValue('STEPCHILD_MAX_AGE', 'value') ?? 25);
                if ($age >= $maxAge) {
                    $errors[] = 'أبناء الزوج/الزوجة يجب أن تكون أعمارهم أقل من ' . $maxAge . ' سنة';
                }
                break;

            case 'orphan':
                $maxAge = (int) (RuleEngine::getValue('ORPHAN_MAX_AGE', 'value') ?? 25);
                if ($age >= $maxAge) {
                    $errors[] = 'الطفل اليتيم يجب أن يكون أقل من ' . $maxAge . ' سنة';
                }
                break;

            case 'disabled_sibling':
                if (empty($tempData['disability_documentation'])) {
                    $errors[] = 'يجب تقديم وثائق الإعاقة';
                }
                break;

            case 'nanny':
                break;

            default:
                $errors[] = 'فئة غير معروفة';
        }

        return $errors;
    }

    public static function canSeparate(string $category): bool
    {
        $noSeparation = ['orphan', 'disabled_sibling', 'nanny', 'parent'];
        return !in_array($category, $noSeparation, true);
    }

    public static function canGetIndependent(string $category): bool
    {
        $noIndependent = ['orphan', 'disabled_sibling', 'nanny'];
        return !in_array($category, $noIndependent, true);
    }

}
