<?php
declare(strict_types=1);

use App\Core\Registries\MenuRegistry;
use App\Core\Registries\PermissionRegistry;
use App\Core\EventBus;
use App\Core\App;
use App\Core\Logger;
use App\Modules\Members\Services\MemberNumberGenerator;

MenuRegistry::register('payments', [
    'label_ar'   => 'الخزينة والمدفوعات',
    'label_en'   => 'Treasury & Payments',
    'icon'       => 'wallet',
    'route'      => '/payments',
    'permission' => 'payment.view',
    'parent'     => null,
    'order'      => 500,
    'children'   => [
        ['label_ar' => 'كل المدفوعات',   'label_en' => 'All Payments',  'route' => '/payments',              'permission' => 'payment.view',         'order' => 1],
        ['label_ar' => 'التقرير اليومي',  'label_en' => 'Daily Report',  'route' => '/payments/daily-report', 'permission' => 'payment.view',         'order' => 2],
        ['label_ar' => 'الإيصالات',       'label_en' => 'Receipts',      'route' => '/receipts',              'permission' => 'payment.view',         'order' => 3],
        ['label_ar' => 'إيصالات ملغاة',   'label_en' => 'Voided',        'route' => '/receipts/voided',       'permission' => 'payment.void_receipt', 'order' => 4],
    ],
]);

PermissionRegistry::register('payments', [
    'payment.process_cash'   => ['ar' => 'معالجة دفع نقدي',   'en' => 'Process Cash Payment'],
    'payment.process_check'  => ['ar' => 'معالجة دفع بشيك',   'en' => 'Process Check Payment'],
    'payment.process_visa'   => ['ar' => 'معالجة دفع فيزا',   'en' => 'Process Visa Payment'],
    'payment.view'           => ['ar' => 'عرض المدفوعات',      'en' => 'View Payments'],
    'payment.void_receipt'   => ['ar' => 'إلغاء إيصال',        'en' => 'Void Receipt'],
    'payment.refund'         => ['ar' => 'استرداد',            'en' => 'Refund Payment'],
]);

// When payment.completed fires: activate membership, assign number, transition workflow
EventBus::listen('payment.completed', function (array $data) {
    try {
        $db = App::getInstance()->db();
        $paymentType = $data['payment_type'] ?? '';
        $memberId = (int) ($data['member_id'] ?? 0);

        if ($memberId <= 0) return;

        $member = $db->selectOne("SELECT * FROM members WHERE id = ? AND is_archived = 0", [$memberId]);
        if (!$member) return;

        // Membership fee payment → activate member + assign number
        if (in_array($paymentType, ['membership_fee', 'down_payment'])) {
            if (in_array($member['status'], ['potential', 'payment_pending', 'accepted'])) {
                // Assign membership number if not yet assigned
                if (empty($member['membership_number'])) {
                    try {
                        $number = MemberNumberGenerator::assign($memberId);
                        Logger::info("Membership number {$number} assigned to member #{$memberId} after payment");
                    } catch (\Throwable $e) {
                        Logger::warning("Failed to assign membership number for member #{$memberId}: " . $e->getMessage());
                    }
                }

                // Update member status to active
                $db->update('members', [
                    'status'     => 'active',
                    'updated_at' => date('Y-m-d H:i:s'),
                ], '`id` = ?', [$memberId]);

                // Try workflow transition
                if ($member['workflow_instance_id']) {
                    try {
                        $instance = $db->selectOne(
                            "SELECT * FROM workflow_instances WHERE id = ? AND is_completed = 0",
                            [(int) $member['workflow_instance_id']]
                        );
                        if ($instance && $instance['current_state'] === 'payment_pending') {
                            $db->update('workflow_instances', [
                                'current_state'    => 'active',
                                'state_entered_at' => date('Y-m-d H:i:s'),
                                'is_completed'     => 1,
                                'completed_at'     => date('Y-m-d H:i:s'),
                                'updated_at'       => date('Y-m-d H:i:s'),
                            ], '`id` = ?', [(int) $instance['id']]);

                            $employee = App::getInstance()->currentEmployee();
                            $db->insert('workflow_transition_log', [
                                'workflow_instance_id'     => (int) $instance['id'],
                                'from_state'               => 'payment_pending',
                                'to_state'                 => 'active',
                                'transition_name'          => 'payment_completed',
                                'triggered_by_employee_id' => $employee ? (int) $employee->id : null,
                                'trigger_type'             => 'system',
                                'notes'                    => 'Auto-transitioned by payment completion',
                                'created_at'               => date('Y-m-d H:i:s'),
                            ]);
                        }
                    } catch (\Throwable $e) {
                        Logger::warning("Workflow transition failed for member #{$memberId}: " . $e->getMessage());
                    }
                }

                Logger::info("Member #{$memberId} activated after payment", $data);
            }
        }

    } catch (\Throwable $e) {
        Logger::error("payment.completed handler error: " . $e->getMessage(), $data);
    }
}, 100);

// Enrich member profile with payment data
EventBus::listen('member.profile_data', function (array &$data) {
    try {
        $db = App::getInstance()->db();
        $memberId = (int) ($data['member']->id ?? 0);
        if ($memberId <= 0) return;

        if ($db->tableExists('payments')) {
            $data['payments'] = $db->select(
                "SELECT p.*, r.receipt_number FROM payments p LEFT JOIN receipts r ON r.id = p.receipt_id WHERE p.member_id = ? AND p.is_voided = 0 ORDER BY p.payment_date DESC, p.id DESC LIMIT 50",
                [$memberId]
            );
        }
    } catch (\Throwable $e) {
        // Table may not exist yet
    }
}, 50);