<?php
declare(strict_types=1);

namespace App\Modules\Accounting\Services;

use App\Core\App;
use App\Core\EventBus;
use App\Core\Logger;
use App\Modules\Inventory\Services\CreditLimitService;

final class StatementIntegrationService
{
    public static function registerListeners(): void
    {
        EventBus::listen('sale.completed', [self::class, 'onSaleCompleted'], 40);
        EventBus::listen('sale.refunded', [self::class, 'onSaleRefunded'], 40);
        EventBus::listen('payment.completed', [self::class, 'onPaymentCompleted'], 40);
        EventBus::listen('procurement.invoice_approved', [self::class, 'onVendorInvoiceApproved'], 40);
        EventBus::listen('procurement.payment_completed', [self::class, 'onVendorPaymentCompleted'], 40);
        EventBus::listen('procurement.rtv_completed', [self::class, 'onReturnToVendor'], 40);
        EventBus::listen('fine.imposed', [self::class, 'onFineImposed'], 40);
        EventBus::listen('subscription.paid', [self::class, 'onSubscriptionPaid'], 40);
    }

    public static function onSaleCompleted(array $data): void
    {
        try {
            $memberId = (int) ($data['member_id'] ?? 0);
            if ($memberId <= 0) return;

            $amount = (string) ($data['total_amount'] ?? '0');
            $saleNumber = $data['sale_number'] ?? '';

            AccountStatementService::recordCustomerTransaction([
                'member_id' => $memberId,
                'transaction_date' => date('Y-m-d'),
                'document_type' => 'sale',
                'document_id' => $data['sale_id'] ?? null,
                'document_number' => $saleNumber,
                'description' => 'فاتورة مبيعات: ' . $saleNumber,
                'debit' => $amount,
            ]);

            CreditLimitService::updateCustomerBalance($memberId, $amount, 'increase');
        } catch (\Throwable $e) {
            Logger::error('StatementIntegration sale.completed failed: ' . $e->getMessage());
        }
    }

    public static function onSaleRefunded(array $data): void
    {
        try {
            $memberId = (int) ($data['member_id'] ?? 0);
            if ($memberId <= 0) return;

            $amount = (string) ($data['refund_amount'] ?? '0');
            $refundNumber = $data['refund_number'] ?? '';

            AccountStatementService::recordCustomerTransaction([
                'member_id' => $memberId,
                'transaction_date' => date('Y-m-d'),
                'document_type' => 'refund',
                'document_id' => $data['refund_id'] ?? null,
                'document_number' => $refundNumber,
                'description' => 'مرتجع مبيعات: ' . $refundNumber,
                'credit' => $amount,
            ]);

            CreditLimitService::updateCustomerBalance($memberId, $amount, 'decrease');
        } catch (\Throwable $e) {
            Logger::error('StatementIntegration sale.refunded failed: ' . $e->getMessage());
        }
    }

    public static function onPaymentCompleted(array $data): void
    {
        try {
            $memberId = (int) ($data['member_id'] ?? 0);
            if ($memberId <= 0) return;

            $amount = (string) ($data['amount'] ?? '0');
            $receiptNumber = $data['receipt_number'] ?? '';

            AccountStatementService::recordCustomerTransaction([
                'member_id' => $memberId,
                'transaction_date' => date('Y-m-d'),
                'document_type' => 'payment',
                'document_id' => $data['payment_id'] ?? null,
                'document_number' => $receiptNumber,
                'description' => 'سداد: ' . $receiptNumber,
                'credit' => $amount,
            ]);

            CreditLimitService::updateCustomerBalance($memberId, $amount, 'decrease');
        } catch (\Throwable $e) {
            Logger::error('StatementIntegration payment.completed failed: ' . $e->getMessage());
        }
    }

    public static function onVendorInvoiceApproved(array $data): void
    {
        try {
            $supplierId = (int) ($data['supplier_id'] ?? 0);
            if ($supplierId <= 0) return;

            $amount = (string) ($data['total_amount'] ?? '0');
            $invoiceNumber = $data['invoice_number'] ?? '';

            AccountStatementService::recordSupplierTransaction([
                'supplier_id' => $supplierId,
                'transaction_date' => date('Y-m-d'),
                'document_type' => 'invoice',
                'document_id' => $data['invoice_id'] ?? null,
                'document_number' => $invoiceNumber,
                'description' => 'فاتورة مورد: ' . $invoiceNumber,
                'credit' => $amount,
            ]);

            CreditLimitService::updateSupplierBalance($supplierId, $amount, 'increase');
        } catch (\Throwable $e) {
            Logger::error('StatementIntegration vendor_invoice_approved failed: ' . $e->getMessage());
        }
    }

    public static function onVendorPaymentCompleted(array $data): void
    {
        try {
            $supplierId = (int) ($data['supplier_id'] ?? 0);
            if ($supplierId <= 0) return;

            $amount = (string) ($data['amount'] ?? '0');
            $paymentNumber = $data['payment_number'] ?? '';

            AccountStatementService::recordSupplierTransaction([
                'supplier_id' => $supplierId,
                'transaction_date' => date('Y-m-d'),
                'document_type' => 'payment',
                'document_id' => $data['payment_id'] ?? null,
                'document_number' => $paymentNumber,
                'description' => 'سداد مورد: ' . $paymentNumber,
                'debit' => $amount,
            ]);

            CreditLimitService::updateSupplierBalance($supplierId, $amount, 'decrease');
        } catch (\Throwable $e) {
            Logger::error('StatementIntegration vendor_payment_completed failed: ' . $e->getMessage());
        }
    }

    public static function onReturnToVendor(array $data): void
    {
        try {
            $supplierId = (int) ($data['supplier_id'] ?? 0);
            if ($supplierId <= 0) return;

            $amount = (string) ($data['total_amount'] ?? '0');
            $rtvNumber = $data['rtv_number'] ?? '';

            AccountStatementService::recordSupplierTransaction([
                'supplier_id' => $supplierId,
                'transaction_date' => date('Y-m-d'),
                'document_type' => 'return',
                'document_id' => $data['rtv_id'] ?? null,
                'document_number' => $rtvNumber,
                'description' => 'مرتجع مورد: ' . $rtvNumber,
                'debit' => $amount,
            ]);

            CreditLimitService::updateSupplierBalance($supplierId, $amount, 'decrease');
        } catch (\Throwable $e) {
            Logger::error('StatementIntegration rtv_completed failed: ' . $e->getMessage());
        }
    }

    public static function onFineImposed(array $data): void
    {
        try {
            $memberId = (int) ($data['member_id'] ?? 0);
            if ($memberId <= 0) return;

            $amount = (string) ($data['amount'] ?? '0');

            AccountStatementService::recordCustomerTransaction([
                'member_id' => $memberId,
                'transaction_date' => date('Y-m-d'),
                'document_type' => 'fine',
                'document_id' => $data['fine_id'] ?? null,
                'description' => 'غرامة: ' . ($data['reason'] ?? ''),
                'debit' => $amount,
            ]);

            CreditLimitService::updateCustomerBalance($memberId, $amount, 'increase');
        } catch (\Throwable $e) {
            Logger::error('StatementIntegration fine.imposed failed: ' . $e->getMessage());
        }
    }

    public static function onSubscriptionPaid(array $data): void
    {
        try {
            $memberId = (int) ($data['member_id'] ?? 0);
            if ($memberId <= 0) return;

            $amount = (string) ($data['amount'] ?? '0');

            AccountStatementService::recordCustomerTransaction([
                'member_id' => $memberId,
                'transaction_date' => date('Y-m-d'),
                'document_type' => 'subscription',
                'document_id' => $data['subscription_id'] ?? null,
                'description' => 'اشتراك: ' . ($data['description'] ?? ''),
                'debit' => $amount,
            ]);
        } catch (\Throwable $e) {
            Logger::error('StatementIntegration subscription.paid failed: ' . $e->getMessage());
        }
    }
}
