<?php
declare(strict_types=1);

namespace App\Modules\Spouses\Services;

use App\Core\App;
use App\Modules\Spouses\Models\Spouse;
use App\Modules\Rules\Services\RuleEngine;
use App\Modules\Members\Services\FormFeeService;

/**
 * Spouse Fee Calculator — all percentages/amounts read from RuleEngine.
 *
 * RULES (editable via /rules admin):
 *   1st Spouse (initial form, not foreign):    FREE (INITIAL_FREE_SPOUSES_COUNT)
 *   1st Spouse (late, basic member):           SPOUSE_BASE_MEMBER_FEE %
 *   1st Spouse (late, acquired member):        SPOUSE_ACQUIRED_MEMBER_FEE %
 *   Foreign Spouse:                            SPOUSE_FOREIGN_FEE %
 *   2nd Spouse:  SPOUSE_2ND_FEE  (percentage + annual_flat × years)
 *   3rd Spouse:  SPOUSE_3RD_FEE  (percentage + annual_flat × years)
 *   4th+ Spouse: SPOUSE_4TH_FEE  (percentage + annual_flat × years)
 *   Late addition form fee:                    FORM_ADDITION_FEE (shared via FormFeeService)
 */
final class SpouseFeeCalculator
{
    public static function calculate(int $memberId, array $spouseData): array
    {
        $db = App::getInstance()->db();

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

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

        if (bccomp($membershipValue, '0.01', 2) < 0) {
            return self::error('يجب تحديد قيمة العضوية أولاً (ملء الاستمارة واختيار المؤهل)');
        }

        $existingCount = Spouse::countActiveForMember($memberId);
        $spouseOrder = $existingCount + 1;

        $isInitialCreation = FormFeeService::isOnInitialForm($member);
        $isFreeSlot = FormFeeService::isSpouseFreeSlot($memberId, $spouseOrder);

        $formFee = FormFeeService::getFormFee($memberId, $member);

        $isAcquiredMember = self::isAcquiredMember($memberId);

        $nationality = trim($spouseData['nationality'] ?? 'مصري');
        $isForeign = ($nationality !== 'مصري' && $nationality !== '' && $nationality !== 'Egyptian');

        $marriageDate = $spouseData['marriage_date'] ?? null;
        $memberCreatedDate = substr($member['created_at'] ?? date('Y-m-d'), 0, 10);

        $percentage = '0.00';
        $percentageFee = '0.00';
        $annualPerYear = '0.00';
        $yearCount = 0;
        $yearlyTotal = '0.00';
        $ruleApplied = '';

        switch (true) {
            case ($spouseOrder === 1):
                if ($isFreeSlot && !$isForeign) {
                    $percentage = '0.00';
                    if ($isInitialCreation) {
                        $ruleApplied = 'الزوجة الأولى — مشمولة في الاستمارة الأولى (بدون رسوم)';
                    } else {
                        $ruleApplied = 'الزوجة الأولى — مشمولة (رسوم الاستمارة فقط ' . money($formFee) . ')';
                    }
                } elseif ($isForeign) {
                    $data = RuleEngine::get('SPOUSE_FOREIGN_FEE');
                    $percentage = $data['percentage'] ?? '15.00';
                    $ruleApplied = 'زوج/ة أجنبي — ' . $percentage . '% من قيمة العضوية';
                } elseif ($isAcquiredMember) {
                    $data = RuleEngine::get('SPOUSE_ACQUIRED_MEMBER_FEE');
                    $percentage = $data['percentage'] ?? '50.00';
                    $ruleApplied = 'إضافة زوج/ة لعضو مكتسب العضوية (فصل/طلاق/وفاة/تنازل) — ' . $percentage . '% من قيمة العضوية';
                } else {
                    $data = RuleEngine::get('SPOUSE_BASE_MEMBER_FEE');
                    $percentage = $data['percentage'] ?? '15.00';
                    $ruleApplied = 'إضافة زوج/ة لعضو أساس العضوية (إضافة لاحقة) — ' . $percentage . '% من قيمة العضوية';
                }
                $percentageFee = bcdiv(bcmul($membershipValue, $percentage, 4), '100', 2);
                break;

            case ($spouseOrder === 2):
                $data = RuleEngine::get('SPOUSE_2ND_FEE');
                $percentage = $data['percentage'] ?? '10.00';
                $annualPerYear = $data['annual_flat'] ?? '150.00';
                $ruleApplied = 'الزوجة الثانية — ' . $percentage . '% من قيمة العضوية + ' . $annualPerYear . ' ج.م عن كل سنة';
                $percentageFee = bcdiv(bcmul($membershipValue, $percentage, 4), '100', 2);
                $yearCount = self::calculateYears($marriageDate, $memberCreatedDate);
                $yearlyTotal = bcmul($annualPerYear, (string) $yearCount, 2);
                break;

            case ($spouseOrder === 3):
                $data = RuleEngine::get('SPOUSE_3RD_FEE');
                $percentage = $data['percentage'] ?? '20.00';
                $annualPerYear = $data['annual_flat'] ?? '200.00';
                $ruleApplied = 'الزوجة الثالثة — ' . $percentage . '% من قيمة العضوية + ' . $annualPerYear . ' ج.م عن كل سنة';
                $percentageFee = bcdiv(bcmul($membershipValue, $percentage, 4), '100', 2);
                $yearCount = self::calculateYears($marriageDate, $memberCreatedDate);
                $yearlyTotal = bcmul($annualPerYear, (string) $yearCount, 2);
                break;

            case ($spouseOrder >= 4):
                $data = RuleEngine::get('SPOUSE_4TH_FEE');
                $percentage = $data['percentage'] ?? '30.00';
                $annualPerYear = $data['annual_flat'] ?? '300.00';
                $ruleApplied = 'الزوجة الرابعة — ' . $percentage . '% من قيمة العضوية + ' . $annualPerYear . ' ج.م عن كل سنة';
                $percentageFee = bcdiv(bcmul($membershipValue, $percentage, 4), '100', 2);
                $yearCount = self::calculateYears($marriageDate, $memberCreatedDate);
                $yearlyTotal = bcmul($annualPerYear, (string) $yearCount, 2);
                break;
        }

        $additionFee = bcadd($percentageFee, $yearlyTotal, 2);
        $totalFee = bcadd($additionFee, $formFee, 2);

        if ($spouseOrder >= 2 && bccomp($additionFee, '0.01', 2) < 0) {
            return self::error(
                'خطأ في حساب الرسوم — الزوجة رقم ' . $spouseOrder .
                ' يجب أن تكون برسوم. قيمة العضوية: ' . money($membershipValue)
            );
        }

        return [
            'spouse_order'      => $spouseOrder,
            'membership_value'  => $membershipValue,
            'is_initial'        => $isInitialCreation,
            'is_late_addition'  => !$isInitialCreation,
            'is_acquired'       => $isAcquiredMember,
            'is_foreign'        => $isForeign,
            'percentage'        => $percentage,
            'percentage_fee'    => $percentageFee,
            'annual_per_year'   => $annualPerYear,
            'year_count'        => $yearCount,
            'yearly_total'      => $yearlyTotal,
            'addition_fee'      => $additionFee,
            'form_fee'          => $formFee,
            'total_fee'         => $totalFee,
            'rule_applied'      => $ruleApplied,
            'error'             => null,
            'breakdown'         => self::buildBreakdown(
                $spouseOrder, $membershipValue, $percentage, $percentageFee,
                $annualPerYear, $yearCount, $yearlyTotal,
                $formFee, $totalFee, $ruleApplied, $isFreeSlot && !$isForeign
            ),
        ];
    }

    private static function calculateYears(?string $marriageDate, string $memberCreatedDate): int
    {
        if (!$marriageDate) {
            return 1;
        }

        $marriageTs = strtotime($marriageDate);
        $memberTs = strtotime($memberCreatedDate);

        if (!$marriageTs || !$memberTs) {
            return 1;
        }

        $startTs = max($marriageTs, $memberTs);
        $start = new \DateTime(date('Y-m-d', $startTs));
        $now = new \DateTime();

        if ($now <= $start) {
            return 1;
        }

        $diff = $now->diff($start);
        $years = $diff->y;

        if ($diff->m > 0 || $diff->d > 0) {
            $years++;
        }

        return max(1, $years);
    }

    private static function isAcquiredMember(int $memberId): bool
    {
        $db = App::getInstance()->db();

        $tables = [
            ['transfer_requests', 'target_member_id'],
            ['divorce_cases', 'spouse_new_member_id'],
            ['death_cases', 'transferred_to_member_id'],
            ['waiver_requests', 'target_member_id'],
        ];

        foreach ($tables as [$table, $column]) {
            try {
                if (!$db->tableExists($table)) continue;
                $row = $db->selectOne(
                    "SELECT id FROM `{$table}` WHERE `{$column}` = ? AND status = 'completed' LIMIT 1",
                    [$memberId]
                );
                if ($row) return true;
            } catch (\Throwable $e) {
                continue;
            }
        }

        return false;
    }

    private static function buildBreakdown(
        int $order, string $membershipValue, string $pct, string $pctFee,
        string $annual, int $years, string $yearlyTotal,
        string $formFee, string $totalFee, string $rule, bool $isFirstFree
    ): array {
        $lines = [];
        $lines[] = '📋 القاعدة المطبقة: ' . $rule;
        $lines[] = '💰 قيمة العضوية: ' . money($membershipValue);

        if ($isFirstFree && bccomp($formFee, '0', 2) <= 0) {
            $lines[] = '✅ الزوجة الأولى مشمولة في الاستمارة — بدون رسوم إضافية';
        } elseif ($isFirstFree && bccomp($formFee, '0', 2) > 0) {
            $lines[] = '✅ الزوجة الأولى مشمولة (بدون رسوم عضوية)';
            $lines[] = '📝 رسوم استمارة إضافة: ' . money($formFee);
        } else {
            if (bccomp($pctFee, '0', 2) > 0) {
                $lines[] = "📊 نسبة {$pct}% × " . money($membershipValue) . ' = ' . money($pctFee);
            }
            if (bccomp($annual, '0', 2) > 0 && $years > 0) {
                $lines[] = "📅 رسوم سنوية: {$annual} ج.م × {$years} سنة = " . money($yearlyTotal);
                $lines[] = '   (من تاريخ الزواج أو اكتساب العضوية — أيهما لاحق — كسر السنة سنة كاملة)';
            }
            if (bccomp($formFee, '0', 2) > 0) {
                $lines[] = '📝 رسوم استمارة إضافة: ' . money($formFee);
            }
        }

        $lines[] = '═══════════════════════════';
        $lines[] = '💵 الإجمالي المطلوب: ' . money($totalFee);

        return $lines;
    }

    private static function error(string $message): array
    {
        return [
            'spouse_order'     => 0,
            'membership_value' => '0.00',
            'percentage'       => '0.00',
            'percentage_fee'   => '0.00',
            'annual_per_year'  => '0.00',
            'year_count'       => 0,
            'yearly_total'     => '0.00',
            'addition_fee'     => '0.00',
            'form_fee'         => '0.00',
            'total_fee'        => '0.00',
            'rule_applied'     => '',
            'error'            => $message,
            'breakdown'        => ['❌ ' . $message],
        ];
    }
}
