<?php
declare(strict_types=1);

namespace App\Modules\Spouses\Services;

use App\Core\App;
use App\Modules\Spouses\Models\Spouse;
use App\Modules\ServiceCatalog\Models\ServicePrice;

/**
 * Spouse Fee Calculator
 *
 * RULES FROM CLUB REGULATIONS:
 * ═══════════════════════════════════════════════════════════════
 * 1st Spouse (same form / initial creation):  FREE (included in membership value)
 * 1st Spouse (added later, أساسي basis):     15% of membership value + 570 form
 * 1st Spouse (added later, مكتسب acquired):  50% of membership value + 570 form  
 * Foreign Spouse (1st):                       15% of membership value
 * 2nd Spouse:  10% of membership value + 150 EGP × years
 * 3rd Spouse:  20% of membership value + 200 EGP × years
 * 4th Spouse:  30% of membership value + 300 EGP × years
 * Years = from marriage date or membership acquisition, whichever LATER
 * Partial year = full year (كسر السنة سنة كاملة)
 * Late addition = +570 EGP form fee
 * ═══════════════════════════════════════════════════════════════
 */
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';

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

        // ── Determine spouse order ──
        $existingCount = Spouse::countActiveForMember($memberId);
        $spouseOrder = $existingCount + 1;

        // ── Is this during initial creation or later? ──
        // "initial" = member status is still potential AND no membership_fee/down_payment paid yet
        $isInitialCreation = in_array($member['status'] ?? '', ['potential', 'under_review']);
        
        // Even during initial creation, only the FIRST spouse is free
        // 2nd/3rd/4th ALWAYS have fees
        $isFirstSpouseDuringCreation = ($spouseOrder === 1 && $isInitialCreation);

        // Late addition = member is already active/accepted = must pay form fee
        $isLateAddition = !in_array($member['status'] ?? '', ['potential', 'under_review']);
        $formFee = $isLateAddition ? ServicePrice::getPrice('SVC_ADDITION_FORM', '570.00') : '0.00';

        // ── Is the member acquired (مكتسب)? ──
        $isAcquiredMember = self::isAcquiredMember($memberId);

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

        // ── Marriage date for per-year calculation ──
        $marriageDate = $spouseData['marriage_date'] ?? null;
        $memberCreatedDate = substr($member['created_at'] ?? date('Y-m-d'), 0, 10);

        // ── Calculate based on spouse order ──
        $percentage = '0.00';
        $percentageFee = '0.00';
        $annualPerYear = '0.00';
        $yearCount = 0;
        $yearlyTotal = '0.00';
        $ruleApplied = '';

        switch (true) {
            // ═══ 1ST SPOUSE ═══
            case ($spouseOrder === 1):
                if ($isFirstSpouseDuringCreation && !$isForeign) {
                    // Included in base price — truly free
                    $percentage = '0.00';
                    $ruleApplied = 'الزوجة الأولى — مشمولة في قيمة العضوية الأساسية (بدون رسوم إضافية)';
                } elseif ($isForeign) {
                    $percentage = '15.00';
                    $ruleApplied = 'زوج/ة أجنبي — 15% من قيمة العضوية';
                } elseif ($isAcquiredMember) {
                    $percentage = '50.00';
                    $ruleApplied = 'إضافة زوج/ة لعضو مكتسب العضوية (فصل/طلاق/وفاة/تنازل) — 50% من قيمة العضوية';
                } else {
                    $percentage = '15.00';
                    $ruleApplied = 'إضافة زوج/ة لعضو أساس العضوية (إضافة لاحقة) — 15% من قيمة العضوية';
                }
                $percentageFee = bcdiv(bcmul($membershipValue, $percentage, 4), '100', 2);
                break;

            // ═══ 2ND SPOUSE ═══
            case ($spouseOrder === 2):
                $percentage = '10.00';
                $annualPerYear = '150.00';
                $ruleApplied = 'الزوجة الثانية — 10% من قيمة العضوية + 150 ج.م عن كل سنة';
                $percentageFee = bcdiv(bcmul($membershipValue, $percentage, 4), '100', 2);
                $yearCount = self::calculateYears($marriageDate, $memberCreatedDate);
                $yearlyTotal = bcmul($annualPerYear, (string) $yearCount, 2);
                break;

            // ═══ 3RD SPOUSE ═══
            case ($spouseOrder === 3):
                $percentage = '20.00';
                $annualPerYear = '200.00';
                $ruleApplied = 'الزوجة الثالثة — 20% من قيمة العضوية + 200 ج.م عن كل سنة';
                $percentageFee = bcdiv(bcmul($membershipValue, $percentage, 4), '100', 2);
                $yearCount = self::calculateYears($marriageDate, $memberCreatedDate);
                $yearlyTotal = bcmul($annualPerYear, (string) $yearCount, 2);
                break;

            // ═══ 4TH SPOUSE ═══
            case ($spouseOrder >= 4):
                $percentage = '30.00';
                $annualPerYear = '300.00';
                $ruleApplied = 'الزوجة الرابعة — 30% من قيمة العضوية + 300 ج.م عن كل سنة';
                $percentageFee = bcdiv(bcmul($membershipValue, $percentage, 4), '100', 2);
                $yearCount = self::calculateYears($marriageDate, $memberCreatedDate);
                $yearlyTotal = bcmul($annualPerYear, (string) $yearCount, 2);
                break;
        }

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

        // ── SANITY CHECK: 2nd+ spouse must NEVER be free ──
        if ($spouseOrder >= 2 && bccomp($additionFee, '0.01', 2) < 0) {
            // This should never happen if membership_value > 0
            return self::error(
                'خطأ في حساب الرسوم — الزوجة رقم ' . $spouseOrder . 
                ' يجب أن تكون برسوم. قيمة العضوية: ' . money($membershipValue)
            );
        }

        return [
            'spouse_order'      => $spouseOrder,
            'membership_value'  => $membershipValue,
            'is_initial'        => $isInitialCreation,
            'is_late_addition'  => $isLateAddition,
            '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, $isFirstSpouseDuringCreation
            ),
        ];
    }

    /**
     * Years from marriage date or membership acquisition (whichever later).
     * Partial year = full year.
     */
    private static function calculateYears(?string $marriageDate, string $memberCreatedDate): int
    {
        if (!$marriageDate) {
            return 1;
        }

        $marriageTs = strtotime($marriageDate);
        $memberTs = strtotime($memberCreatedDate);
        
        if (!$marriageTs || !$memberTs) {
            return 1;
        }

        // Use whichever is LATER
        $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);
    }

    /**
     * Check if member got membership through transfer/separation/divorce/death/waiver.
     */
    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;
    }

    /**
     * Build detailed Arabic breakdown.
     */
    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) {
            $lines[] = '✅ الزوجة الأولى مشمولة في قيمة العضوية — بدون رسوم إضافية';
        } 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;
    }

    /**
     * Return error result.
     */
    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],
        ];
    }
}