<?php
declare(strict_types=1);

namespace App\Shared\Services;

use App\Core\App;

final class DebtCheckService
{
    public static function check(int $memberId): array
    {
        $db = App::getInstance()->db();
        $member = $db->selectOne("SELECT id, full_name_ar, membership_number FROM members WHERE id = ?", [$memberId]);
        if (!$member) return ['clear' => true, 'debts' => [], 'total' => '0.00', 'details' => []];

        $memberName = $member['full_name_ar'] ?? 'عضو #' . $memberId;
        $details = [];

        $dependentMap = self::buildDependentMap($memberId);

        // 1. Subscriptions (member + all dependents)
        $subs = $db->select(
            "SELECT id, person_type, person_id, person_name, financial_year, (total_amount - paid_amount + fine_amount + COALESCE(development_fee, 0)) as due
             FROM subscriptions WHERE member_id = ? AND status IN ('pending','overdue') AND (total_amount - paid_amount + fine_amount + COALESCE(development_fee, 0)) > 0",
            [$memberId]
        );
        foreach ($subs as $sub) {
            $personType = $sub['person_type'] ?? 'member';
            $personName = $sub['person_name'] ?? $memberName;
            $personLabel = self::getPersonLabel($personType, $personName);
            $details[] = [
                'member_id' => $memberId,
                'member_name' => $memberName,
                'person_name' => $personName,
                'person_type' => $personType,
                'person_label' => $personLabel,
                'debt_type' => 'اشتراك سنوي',
                'debt_type_code' => 'subscription',
                'period' => $sub['financial_year'] ?? '',
                'amount' => $sub['due'],
                'description' => 'اشتراك سنوي ' . ($sub['financial_year'] ?? '') . ' — ' . $personLabel,
                'payment_url' => '/payments/process/' . $memberId,
            ];
        }

        // 2. Fines
        $fines = $db->select(
            "SELECT id, notes, (amount - paid_amount) as due, created_at FROM fines WHERE member_id = ? AND status IN ('imposed','pending','appeal_upheld') AND (amount - paid_amount) > 0",
            [$memberId]
        );
        foreach ($fines as $fine) {
            $details[] = [
                'member_id' => $memberId,
                'member_name' => $memberName,
                'person_name' => $memberName,
                'person_type' => 'member',
                'person_label' => 'العضو الأساسي (' . $memberName . ')',
                'debt_type' => 'غرامة',
                'debt_type_code' => 'fine',
                'period' => substr($fine['created_at'] ?? '', 0, 10),
                'amount' => $fine['due'],
                'description' => 'غرامة' . (!empty($fine['notes']) ? ' — ' . $fine['notes'] : '') . ' — العضو الأساسي',
                'payment_url' => '/payments/process/' . $memberId,
            ];
        }

        // 3. Installments
        $installments = $db->select(
            "SELECT s.id, s.due_date, (s.amount - s.paid_amount) as due, p.notes as plan_desc
             FROM installment_schedule s JOIN installment_plans p ON p.id = s.installment_plan_id
             WHERE p.member_id = ? AND p.status IN ('active','overdue') AND s.status IN ('pending','overdue') AND (s.amount - s.paid_amount) > 0",
            [$memberId]
        );
        foreach ($installments as $inst) {
            $details[] = [
                'member_id' => $memberId,
                'member_name' => $memberName,
                'person_name' => $memberName,
                'person_type' => 'member',
                'person_label' => 'العضو الأساسي (' . $memberName . ')',
                'debt_type' => 'قسط',
                'debt_type_code' => 'installment',
                'period' => $inst['due_date'] ?? '',
                'amount' => $inst['due'],
                'description' => 'قسط مستحق ' . ($inst['due_date'] ?? '') . (!empty($inst['plan_desc']) ? ' — ' . $inst['plan_desc'] : ''),
                'payment_url' => '/payments/process/' . $memberId,
            ];
        }

        // 4. Pending payment requests
        $requests = $db->select(
            "SELECT id, payment_type, amount, description_ar FROM payment_requests
             WHERE member_id = ? AND status = 'pending' AND is_voided = 0",
            [$memberId]
        );
        foreach ($requests as $req) {
            $typeLabel = self::getPaymentTypeLabel($req['payment_type'] ?? '');
            $details[] = [
                'member_id' => $memberId,
                'member_name' => $memberName,
                'person_name' => $memberName,
                'person_type' => 'member',
                'person_label' => 'العضو الأساسي (' . $memberName . ')',
                'debt_type' => $typeLabel,
                'debt_type_code' => 'payment_request',
                'period' => '',
                'amount' => $req['amount'],
                'description' => ($req['description_ar'] ?? $typeLabel),
                'payment_url' => '/payments/process/' . $memberId,
            ];
        }

        // 5. Unpaid credit sales
        $sales = $db->select(
            "SELECT id, invoice_number, (total_amount - amount_paid) as due, created_at
             FROM sales WHERE member_id = ? AND status = 'completed' AND (total_amount - amount_paid) > 0",
            [$memberId]
        );
        foreach ($sales as $sale) {
            $details[] = [
                'member_id' => $memberId,
                'member_name' => $memberName,
                'person_name' => $memberName,
                'person_type' => 'member',
                'person_label' => 'العضو الأساسي (' . $memberName . ')',
                'debt_type' => 'فاتورة مبيعات',
                'debt_type_code' => 'sale',
                'period' => substr($sale['created_at'] ?? '', 0, 10),
                'amount' => $sale['due'],
                'description' => 'فاتورة #' . ($sale['invoice_number'] ?? $sale['id']),
                'payment_url' => '/payments/process/' . $memberId,
            ];
        }

        // 6. Seasonal memberships
        $seasonals = $db->select(
            "SELECT id, person_type, person_name, fee_amount, status
             FROM seasonal_memberships WHERE member_id = ? AND status IN ('pending','overdue') AND fee_amount > 0",
            [$memberId]
        );
        foreach ($seasonals as $sm) {
            $pType = $sm['person_type'] ?? 'member';
            $pName = $sm['person_name'] ?? $memberName;
            $details[] = [
                'member_id' => $memberId,
                'member_name' => $memberName,
                'person_name' => $pName,
                'person_type' => $pType,
                'person_label' => self::getPersonLabel($pType, $pName),
                'debt_type' => 'رسوم عضوية موسمية',
                'debt_type_code' => 'seasonal',
                'period' => '',
                'amount' => $sm['fee_amount'],
                'description' => 'عضوية موسمية — ' . self::getPersonLabel($pType, $pName),
                'payment_url' => '/payments/process/' . $memberId,
            ];
        }

        $totalDebt = '0.00';
        foreach ($details as $d) {
            $totalDebt = bcadd($totalDebt, (string) $d['amount'], 2);
        }

        return [
            'clear' => empty($details),
            'debts' => $details,
            'total' => $totalDebt,
            'member_name' => $memberName,
            'dependents_checked' => $dependentMap,
        ];
    }

    private static function buildDependentMap(int $memberId): array
    {
        $db = App::getInstance()->db();
        $map = ['spouses' => [], 'children' => [], 'temporary' => []];

        $spouses = $db->select(
            "SELECT id, full_name_ar FROM spouses WHERE member_id = ? AND is_archived = 0",
            [$memberId]
        );
        foreach ($spouses as $s) {
            $map['spouses'][] = ['id' => (int) $s['id'], 'name' => $s['full_name_ar'] ?? ''];
        }

        $children = $db->select(
            "SELECT id, full_name_ar FROM children WHERE member_id = ? AND is_archived = 0",
            [$memberId]
        );
        foreach ($children as $c) {
            $map['children'][] = ['id' => (int) $c['id'], 'name' => $c['full_name_ar'] ?? ''];
        }

        $temps = $db->select(
            "SELECT id, full_name_ar FROM temporary_members WHERE member_id = ? AND is_archived = 0",
            [$memberId]
        );
        foreach ($temps as $t) {
            $map['temporary'][] = ['id' => (int) $t['id'], 'name' => $t['full_name_ar'] ?? ''];
        }

        return $map;
    }

    private static function getPersonLabel(?string $personType, string $personName): string
    {
        return match ($personType) {
            'member' => 'العضو الأساسي (' . $personName . ')',
            'spouse' => 'الزوجة (' . $personName . ')',
            'child' => 'الابن/ة (' . $personName . ')',
            'temporary' => 'العضو المؤقت (' . $personName . ')',
            default => $personName,
        };
    }

    private static function getPaymentTypeLabel(string $type): string
    {
        return match ($type) {
            'subscription' => 'اشتراك سنوي',
            'fine' => 'غرامة',
            'installment' => 'قسط',
            'form_fee' => 'رسوم استمارة',
            'membership_fee' => 'رسوم عضوية',
            'down_payment' => 'مقدم عضوية',
            'waiver_fee' => 'رسوم تنازل',
            'transfer_fee' => 'رسوم تحويل',
            'separation_fee' => 'رسوم فصل',
            'service_fee' => 'رسوم خدمة',
            'admin_fee' => 'رسوم إدارية',
            'renewal_fee' => 'رسوم تجديد',
            'carnet_fee' => 'رسوم كارنيه',
            'guest_fee' => 'رسوم ضيافة',
            default => 'طلب دفع معلق',
        };
    }
}
