<?php
declare(strict_types=1);

namespace App\Modules\Members\Services;

use App\Core\App;

/**
 * Calculates the TOTAL bill for a member including all additions.
 * Used during initial creation to show accumulated charges before payment.
 */
final class BillingService
{
    public static function getMemberBill(int $memberId): array
    {
        $db = App::getInstance()->db();
        $member = $db->selectOne("SELECT * FROM members WHERE id = ? AND is_archived = 0", [$memberId]);
        if (!$member) return [];

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

        // ── 1. Form Fee (505) ──
        $formFeePaid = false;
        try {
            $ff = $db->selectOne(
                "SELECT id FROM payments WHERE member_id = ? AND payment_type = 'form_fee' AND is_voided = 0 LIMIT 1",
                [$memberId]
            );
            $formFeePaid = ($ff !== null);
        } catch (\Throwable $e) {}

        $items[] = [
            'type'        => 'form_fee',
            'label'       => 'رسوم استمارة عضوية (500 استمارة + 5 طابع شهداء)',
            'amount'      => '505.00',
            'paid'        => $formFeePaid,
            'included'    => false,
            'category'    => 'required',
        ];

        // ── 2. Membership Value ──
        $membershipPaid = false;
        try {
            $mp = $db->selectOne(
                "SELECT id FROM payments WHERE member_id = ? AND payment_type IN ('membership_fee','down_payment') AND is_voided = 0 LIMIT 1",
                [$memberId]
            );
            $membershipPaid = ($mp !== null);
        } catch (\Throwable $e) {}

        $qualName = '—';
        if ($member['qualification_id']) {
            $q = $db->selectOne("SELECT name_ar FROM qualifications WHERE id = ?", [(int) $member['qualification_id']]);
            $qualName = $q['name_ar'] ?? '—';
        }

        $items[] = [
            'type'        => 'membership_fee',
            'label'       => 'قيمة العضوية (' . $qualName . ')',
            'amount'      => $membershipValue,
            'paid'        => $membershipPaid,
            'included'    => false,
            'category'    => 'required',
        ];

        // ── 3. Spouses ──
        $spouses = [];
        try {
            $spouses = $db->select(
                "SELECT * FROM spouses WHERE member_id = ? AND is_archived = 0 ORDER BY spouse_order",
                [$memberId]
            );
        } catch (\Throwable $e) {}

        foreach ($spouses as $s) {
            $order = (int) $s['spouse_order'];
            $fee = $s['addition_fee'] ?? '0.00';
            $isFirstFree = ($order === 1 && bccomp($fee, '0', 2) <= 0);

            $items[] = [
                'type'        => 'spouse_fee',
                'label'       => 'زوجة #' . $order . ' — ' . $s['full_name_ar'],
                'amount'      => $isFirstFree ? '0.00' : $fee,
                'paid'        => false,
                'included'    => $isFirstFree,
                'included_note' => $isFirstFree ? 'مشمولة في قيمة العضوية' : null,
                'entity_type' => 'spouses',
                'entity_id'   => (int) $s['id'],
                'category'    => 'addition',
            ];
        }

        // ── 4. Children ──
        $children = [];
        try {
            $children = $db->select(
                "SELECT * FROM children WHERE member_id = ? AND is_archived = 0 ORDER BY child_order",
                [$memberId]
            );
        } catch (\Throwable $e) {}

        foreach ($children as $c) {
            $order = (int) $c['child_order'];
            $fee = $c['addition_fee'] ?? '0.00';
            $classification = $c['classification'] ?? 'included';
            $isIncluded = ($classification === 'included' && bccomp($fee, '0', 2) <= 0);

            $classLabel = match ($classification) {
                'included'           => 'مشمول (بدون رسوم)',
                'dependent_with_fee' => 'تابع (برسوم)',
                'temporary'          => 'مؤقت',
                default              => $classification,
            };

            $items[] = [
                'type'          => 'child_fee',
                'label'         => ($c['gender'] === 'male' ? 'ابن' : 'ابنة') . ' #' . $order . ' — ' . $c['full_name_ar'] . ' (' . (int) ($c['age_years'] ?? 0) . ' سنة)',
                'amount'        => $fee,
                'paid'          => false,
                'included'      => $isIncluded,
                'included_note' => $isIncluded ? 'مشمول — ' . $classLabel : $classLabel,
                'entity_type'   => 'children',
                'entity_id'     => (int) $c['id'],
                'category'      => 'addition',
            ];
        }

        // ── 5. Temporary Members ──
        try {
            $temps = $db->select(
                "SELECT * FROM temporary_members WHERE member_id = ? AND is_archived = 0 ORDER BY id",
                [$memberId]
            );
            foreach ($temps as $t) {
                $items[] = [
                    'type'        => 'temp_fee',
                    'label'       => 'عضو مؤقت — ' . $t['full_name_ar'] . ' (' . $t['category'] . ')',
                    'amount'      => $t['addition_fee'] ?? '0.00',
                    'paid'        => false,
                    'included'    => false,
                    'entity_type' => 'temporary_members',
                    'entity_id'   => (int) $t['id'],
                    'category'    => 'addition',
                ];
            }
        } catch (\Throwable $e) {}

        // ── Check what's already paid ──
        try {
            $paidAdditions = $db->select(
                "SELECT related_entity_type, related_entity_id FROM payments 
                 WHERE member_id = ? AND payment_type = 'addition_fee' AND is_voided = 0",
                [$memberId]
            );
            foreach ($paidAdditions as $pa) {
                foreach ($items as &$item) {
                    if (($item['entity_type'] ?? '') === $pa['related_entity_type'] 
                        && ($item['entity_id'] ?? 0) == $pa['related_entity_id']) {
                        $item['paid'] = true;
                    }
                }
                unset($item);
            }
        } catch (\Throwable $e) {}

        // ── Calculate totals ──
        $totalRequired = '0.00';
        $totalPaid = '0.00';
        $totalPending = '0.00';
        $totalIncluded = '0.00';

        foreach ($items as $item) {
            if ($item['included']) {
                $totalIncluded = bcadd($totalIncluded, $item['amount'], 2);
                continue;
            }
            $totalRequired = bcadd($totalRequired, $item['amount'], 2);
            if ($item['paid']) {
                $totalPaid = bcadd($totalPaid, $item['amount'], 2);
            } else {
                $totalPending = bcadd($totalPending, $item['amount'], 2);
            }
        }

        return [
            'items'           => $items,
            'membership_value' => $membershipValue,
            'total_required'  => $totalRequired,
            'total_paid'      => $totalPaid,
            'total_pending'   => $totalPending,
            'total_included'  => $totalIncluded,
            'form_fee_paid'   => $formFeePaid,
            'membership_paid' => $membershipPaid,
            'all_paid'        => (bccomp($totalPending, '0', 2) <= 0),
        ];
    }
}