<?php
declare(strict_types=1);

namespace App\Modules\Divorce\Services;

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

final class DivorceFeeCalculator
{
    public static function getFormFee(): string
    {
        $feeData = RuleEngine::get('FORM_TRANSFER_FEE');
        if ($feeData && isset($feeData['amount'])) {
            return $feeData['amount'];
        }
        return ServicePrice::getPrice('SVC_ADDITION_FORM', '570.00');
    }

    public static function getAnnualSubscription(): string
    {
        $db = App::getInstance()->db();
        $childRate = $db->selectOne(
            "SELECT base_amount FROM service_catalog WHERE service_code LIKE 'SVC_ANNUAL_CHILD%' AND is_active = 1 ORDER BY effective_from DESC LIMIT 1"
        );
        $devFeeData = RuleEngine::get('DEVELOPMENT_FEE');

        $rate = $childRate ? $childRate['base_amount'] : '222.00';
        $dev = $devFeeData['amount'] ?? '35.00';

        return bcadd($rate, $dev, 2);
    }

    public static function getSuggestedPercentage(int $spouseOrder, string $caseType): array
    {
        if ($caseType === 'both_working') {
            return [
                'percentage' => '0.00',
                'label' => 'كلاهما عامل قبل الزواج — الاشتراك السنوي فقط',
            ];
        }

        if ($caseType === 'same_form') {
            $data = RuleEngine::get('DIVORCE_SAME_FORM_FEE');
            return [
                'percentage' => $data['percentage'] ?? '10.00',
                'label' => 'قُبلا في استمارة واحدة — 10%',
            ];
        }

        $data = RuleEngine::get('DIVORCE_JOINED_AFTER_FEE');
        return [
            'percentage' => $data['percentage'] ?? '50.00',
            'label' => 'الزوج/ة مكتسب عضوية — 50%',
        ];
    }

    public static function calculateChildFees(int $memberId, string $membershipValue): array
    {
        $db = App::getInstance()->db();
        $children = $db->select(
            "SELECT id, full_name_ar, date_of_birth, age_years FROM children WHERE member_id = ? AND is_archived = 0 AND status = 'active'",
            [$memberId]
        );

        if (empty($children)) return ['children' => [], 'total_fee' => '0.00'];

        $results = [];
        $totalFee = '0.00';

        foreach ($children as $child) {
            $age = self::calculateAge($child['date_of_birth']);
            $bracket = self::getAgeBracket($age);
            $percentage = self::getChildPercentage($bracket['rule_code']);
            $fee = bcdiv(bcmul($membershipValue, $percentage, 4), '100', 2);

            $results[] = [
                'id' => (int) $child['id'],
                'name' => $child['full_name_ar'],
                'age' => $age,
                'bracket_label' => $bracket['label'],
                'percentage' => $percentage,
                'fee' => $fee,
            ];
            $totalFee = bcadd($totalFee, $fee, 2);
        }

        return ['children' => $results, 'total_fee' => $totalFee];
    }

    private static function calculateAge(string $dateOfBirth): int
    {
        $birth = new \DateTime($dateOfBirth);
        $now = new \DateTime();
        return (int) $birth->diff($now)->y;
    }

    private static function getAgeBracket(int $age): array
    {
        if ($age < 12) return ['rule_code' => 'DIVORCE_CHILD_UNDER_12', 'label' => 'أقل من 12 سنة'];
        if ($age < 16) return ['rule_code' => 'DIVORCE_CHILD_12_TO_16', 'label' => '12 إلى أقل من 16 سنة'];
        if ($age < 18) return ['rule_code' => 'DIVORCE_CHILD_16_TO_18', 'label' => '16 إلى أقل من 18 سنة'];
        return ['rule_code' => 'DIVORCE_CHILD_OVER_18', 'label' => 'فوق 18 سنة'];
    }

    private static function getChildPercentage(string $ruleCode): string
    {
        $data = RuleEngine::get($ruleCode);
        return $data['percentage'] ?? '0.00';
    }

    /**
     * Get the current membership value from pricing_configs (source of truth at time of request).
     * Falls back to member's stored value if no active pricing config is found.
     */
    public static function getCurrentMembershipValue(array $member): array
    {
        $db = App::getInstance()->db();
        $today = date('Y-m-d');

        $config = $db->selectOne(
            "SELECT price FROM pricing_configs WHERE branch_id = ? AND qualification_id = ? AND membership_type = 'working' AND is_active = 1 AND effective_from <= ? AND (effective_to IS NULL OR effective_to >= ?) ORDER BY effective_from DESC LIMIT 1",
            [(int) $member['branch_id'], (int) $member['qualification_id'], $today, $today]
        );

        if ($config && bccomp($config['price'], '0', 2) > 0) {
            return [
                'value' => $config['price'],
                'source' => 'pricing_configs',
            ];
        }

        return [
            'value' => $member['membership_value'] ?? '0.00',
            'source' => 'member_record',
        ];
    }

    /**
     * Validate eligibility and determine case type.
     */
    public static function calculate(int $memberId, int $spouseId, string $divorceDate): array
    {
        $db = App::getInstance()->db();
        $member = $db->selectOne("SELECT * FROM members WHERE id = ?", [$memberId]);
        $spouse = $db->selectOne("SELECT * FROM spouses WHERE id = ?", [$spouseId]);

        if (!$member || !$spouse) {
            return ['success' => false, 'error' => 'بيانات العضو أو الزوج غير موجودة'];
        }

        // Check 1-year window from divorce date
        $divorceTs = strtotime($divorceDate);
        $windowData = RuleEngine::get('DIVORCE_REQUEST_WINDOW');
        $maxYears = $windowData['max_years'] ?? 1;
        $deadline = strtotime("+{$maxYears} years", $divorceTs);
        if (time() > $deadline) {
            return ['success' => false, 'error' => "انتهت مهلة تقديم الطلب ({$maxYears} سنة من تاريخ الطلاق)"];
        }

        // Use SPOUSE's join_date for the 5-year calculation (not member's created_at)
        $spouseJoinDate = $spouse['join_date'] ?? $spouse['created_at'];

        // Get current membership value from pricing_configs (not the stored member value)
        $valueInfo = self::getCurrentMembershipValue($member);
        $membershipValue = $valueInfo['value'];

        // Check children on this membership
        $childCount = (int) ($db->selectOne(
            "SELECT COUNT(*) as cnt FROM children WHERE member_id = ? AND is_archived = 0",
            [$memberId]
        )['cnt'] ?? 0);
        $hasChildren = $childCount > 0;

        // Check 5-year minimum from spouse's join date (waived if children)
        $minYearsData = RuleEngine::get('DIVORCE_MIN_MEMBERSHIP_YEARS');
        $minYears = $minYearsData['min_years'] ?? 5;
        $waivedIfChildren = $minYearsData['waived_if_children'] ?? true;

        $yearsMembership = (int) ((time() - strtotime($spouseJoinDate)) / (365.25 * 86400));
        if ($yearsMembership < $minYears && !($waivedIfChildren && $hasChildren)) {
            return ['success' => false, 'error' => "الحد الأدنى لسنوات العضوية {$minYears} سنوات من تاريخ انضمام الزوج/ة (يُعفى في حالة وجود أبناء)"];
        }

        // Determine case type based on spouse classification and join dates
        $spouseClassification = $spouse['classification'] ?? '';
        $caseType = 'joined_after';

        if ($spouseClassification === 'working') {
            $caseType = 'both_working';
        } else {
            $memberCreated = substr($member['created_at'] ?? $member['form_date'] ?? '', 0, 10);
            $spouseJoinDateStr = substr($spouseJoinDate, 0, 10);
            if ($memberCreated === $spouseJoinDateStr || $spouseClassification === 'initial_form') {
                $caseType = 'same_form';
            }
        }

        $spouseOrder = (int) ($spouse['spouse_order'] ?? 1);
        $suggested = self::getSuggestedPercentage($spouseOrder, $caseType);

        return [
            'success'                => true,
            'case_type'              => $caseType,
            'membership_value'       => $membershipValue,
            'membership_value_source' => $valueInfo['source'],
            'years_of_membership'    => $yearsMembership,
            'has_children'           => $hasChildren,
            'child_count'            => $childCount,
            'spouse_order'           => $spouseOrder,
            'suggested_percentage'   => $suggested['percentage'],
            'suggested_label'        => $suggested['label'],
        ];
    }
}
