<?php
declare(strict_types=1);

namespace App\Modules\Transfers\Services;

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

final class SeparationFeeCalculator
{
    /**
     * Calculate separation/transfer fee based on years since acquisition.
     */
    public static function calculate(int $sourceMemberId, ?int $childId = null, ?string $qualificationCode = null): array
    {
        $db = App::getInstance()->db();
        $member = $db->selectOne("SELECT * FROM members WHERE id = ?", [$sourceMemberId]);
        if (!$member) {
            return ['error' => 'العضو غير موجود', 'success' => false];
        }

        // Determine qualification code
        if ($qualificationCode === null && $member['qualification_id']) {
            $qual = $db->selectOne("SELECT code FROM qualifications WHERE id = ?", [(int) $member['qualification_id']]);
            $qualificationCode = $qual['code'] ?? 'high';
        }

        // Get new membership value at current date
        $branchId = (int) $member['branch_id'];
        $priceInfo = PricingEngine::getMembershipPrice($branchId, $qualificationCode ?? 'high');
        $newMembershipValue = $priceInfo['price'] ?? '0.00';

        // Calculate years since acquisition
        $acquisitionDate = $member['created_at'] ?? $member['form_date'] ?? date('Y-m-d');
        $yearsSince = self::calculateYearsSince($acquisitionDate);

        // Get fee percentage based on years
        $feePercentage = self::getFeePercentageByYear($yearsSince);

        // Calculate separation fee
        $separationFee = bcdiv(bcmul($newMembershipValue, (string) $feePercentage, 4), '100', 2);

        // Form fee
        $formFeeData = RuleEngine::get('FORM_TRANSFER_FEE');
        $formFee = $formFeeData['amount'] ?? '570.00';

        // Annual subscription (basic member subscription)
        $annualSub = ServicePrice::getPrice('SVC_ANNUAL_MEMBER', '492.00');
        $devFeeData = RuleEngine::get('DEVELOPMENT_FEE');
        $devFee = $devFeeData['amount'] ?? '35.00';
        $annualSubscriptionFee = bcadd($annualSub, $devFee, 2);

        $totalFee = bcadd(bcadd($separationFee, $formFee, 2), $annualSubscriptionFee, 2);

        return [
            'success'                => true,
            'source_member_id'       => $sourceMemberId,
            'child_id'               => $childId,
            'qualification_code'     => $qualificationCode,
            'new_membership_value'   => $newMembershipValue,
            'years_since_acquisition'=> $yearsSince,
            'fee_percentage'         => $feePercentage,
            'separation_fee'         => $separationFee,
            'form_fee'               => $formFee,
            'annual_subscription_fee'=> $annualSubscriptionFee,
            'total_fee'              => $totalFee,
            'acquisition_date'       => $acquisitionDate,
        ];
    }

    public static function calculateYearsSince(string $date): int
    {
        $then = new \DateTime(substr($date, 0, 10));
        $now = new \DateTime();
        $diff = $now->diff($then);
        return max(1, $diff->y + ($diff->m > 0 || $diff->d > 0 ? 1 : 0)); // partial year rounds up
    }

    public static function calculateAcquiredMemberChildFee(int $childAge, string $membershipValue): array
    {
        if ($childAge < 12) {
            $ruleCode = 'DIVORCE_CHILD_UNDER_12';
        } elseif ($childAge < 16) {
            $ruleCode = 'DIVORCE_CHILD_12_TO_16';
        } elseif ($childAge < 18) {
            $ruleCode = 'DIVORCE_CHILD_16_TO_18';
        } else {
            $ruleCode = 'DIVORCE_CHILD_OVER_18';
        }

        $data = RuleEngine::get($ruleCode);
        $percentage = $data['percentage'] ?? '30.00';
        $fee = bcdiv(bcmul($membershipValue, $percentage, 4), '100', 2);

        return [
            'age' => $childAge,
            'rule_code' => $ruleCode,
            'percentage' => $percentage,
            'fee' => $fee,
            'membership_value' => $membershipValue,
        ];
    }

    public static function getFeePercentageByYear(int $year): string
    {
        $ruleMap = [
            1 => 'SEPARATION_FEE_YEAR_1',
            2 => 'SEPARATION_FEE_YEAR_2',
            3 => 'SEPARATION_FEE_YEAR_3',
            4 => 'SEPARATION_FEE_YEAR_4',
            5 => 'SEPARATION_FEE_YEAR_5',
        ];

        $ruleCode = $ruleMap[min($year, 5)] ?? 'SEPARATION_FEE_YEAR_6_PLUS';
        if ($year > 5) {
            $ruleCode = 'SEPARATION_FEE_YEAR_6_PLUS';
        }

        $data = RuleEngine::require($ruleCode);
        return $data['percentage'];
    }

    /**
     * Calculate surcharge when new owner has more companions than the original member.
     * Extra spouses/children are charged standard addition fees.
     */
    public static function calculateCompanionSurcharge(
        int $sourceMemberId,
        int $targetSpousesCount,
        int $targetChildrenCount
    ): array {
        $db = App::getInstance()->db();
        $member = $db->selectOne("SELECT * FROM members WHERE id = ?", [$sourceMemberId]);
        if (!$member) {
            return ['surcharge' => '0.00', 'breakdown' => [], 'source_count' => 0, 'target_count' => 0];
        }

        $sourceSpouses = (int) $db->selectOne(
            "SELECT COUNT(*) as cnt FROM spouses WHERE member_id = ? AND is_archived = 0 AND status = 'active'",
            [$sourceMemberId]
        )['cnt'];

        $sourceChildren = (int) $db->selectOne(
            "SELECT COUNT(*) as cnt FROM children WHERE member_id = ? AND is_archived = 0 AND status = 'active'",
            [$sourceMemberId]
        )['cnt'];

        $sourceTotal = $sourceSpouses + $sourceChildren;
        $targetTotal = $targetSpousesCount + $targetChildrenCount;
        $breakdown = [];
        $surcharge = '0.00';

        $membershipValue = $member['membership_value'] ?? '0.00';

        // Extra spouses beyond what source had
        $extraSpouses = max(0, $targetSpousesCount - $sourceSpouses);
        if ($extraSpouses > 0) {
            $spouseBasePct = RuleEngine::getValue('SPOUSE_BASE_MEMBER_FEE', 'percentage') ?? '30.00';
            $perSpouseFee = bcdiv(bcmul($membershipValue, $spouseBasePct, 4), '100', 2);
            $spouseSurcharge = bcmul($perSpouseFee, (string) $extraSpouses, 2);
            $surcharge = bcadd($surcharge, $spouseSurcharge, 2);
            $breakdown[] = [
                'type' => 'extra_spouses',
                'count' => $extraSpouses,
                'per_unit' => $perSpouseFee,
                'percentage' => $spouseBasePct,
                'total' => $spouseSurcharge,
            ];
        }

        // Extra children beyond what source had
        $extraChildren = max(0, $targetChildrenCount - $sourceChildren);
        if ($extraChildren > 0) {
            $childBasePct = RuleEngine::getValue('CHILD_ADDITION_FEE', 'percentage') ?? '10.00';
            $perChildFee = bcdiv(bcmul($membershipValue, $childBasePct, 4), '100', 2);
            $childSurcharge = bcmul($perChildFee, (string) $extraChildren, 2);
            $surcharge = bcadd($surcharge, $childSurcharge, 2);
            $breakdown[] = [
                'type' => 'extra_children',
                'count' => $extraChildren,
                'per_unit' => $perChildFee,
                'percentage' => $childBasePct,
                'total' => $childSurcharge,
            ];
        }

        return [
            'surcharge'    => $surcharge,
            'breakdown'    => $breakdown,
            'source_count' => $sourceTotal,
            'target_count' => $targetTotal,
            'extra_spouses'  => $extraSpouses ?? 0,
            'extra_children' => $extraChildren ?? 0,
        ];
    }
}