<?php
declare(strict_types=1);

namespace App\Modules\Accounting\Services;

use App\Core\App;
use App\Core\EventBus;

final class CrossEntitySettlementService
{
    public static function create(array $data): array
    {
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        $settlementNumber = 'SET-' . date('Ymd') . '-' . str_pad((string) random_int(1, 9999), 4, '0', STR_PAD_LEFT);

        $db->beginTransaction();
        try {
            $settlementId = $db->insert('cross_entity_settlements', [
                'settlement_number' => $settlementNumber,
                'settlement_date' => $data['settlement_date'] ?? date('Y-m-d'),
                'from_entity_type' => $data['from_entity_type'],
                'from_entity_id' => (int) $data['from_entity_id'],
                'from_entity_name' => $data['from_entity_name'],
                'to_entity_type' => $data['to_entity_type'],
                'to_entity_id' => (int) $data['to_entity_id'],
                'to_entity_name' => $data['to_entity_name'],
                'amount' => $data['amount'],
                'purpose' => $data['purpose'] ?? 'payment',
                'description' => $data['description'] ?? null,
                'status' => 'draft',
                'created_by' => $employee ? (int) $employee->id : null,
            ]);

            $db->commit();
            return ['success' => true, 'settlement_id' => $settlementId, 'settlement_number' => $settlementNumber];
        } catch (\Throwable $e) {
            $db->rollBack();
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    public static function approve(int $settlementId): array
    {
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        $settlement = $db->selectOne("SELECT * FROM cross_entity_settlements WHERE id = ?", [$settlementId]);
        if (!$settlement) {
            return ['success' => false, 'error' => 'التسوية غير موجودة'];
        }
        if ($settlement['status'] !== 'draft') {
            return ['success' => false, 'error' => 'التسوية ليست في حالة مسودة'];
        }

        $db->beginTransaction();
        try {
            $db->update('cross_entity_settlements', [
                'status' => 'approved',
                'approved_by' => $employee ? (int) $employee->id : null,
                'approved_at' => date('Y-m-d H:i:s'),
            ], 'id = ?', [$settlementId]);

            self::postSettlementToAccounts($settlement);

            $db->update('cross_entity_settlements', ['status' => 'posted'], 'id = ?', [$settlementId]);

            $db->commit();

            EventBus::dispatch('settlement.posted', [
                'settlement_id' => $settlementId,
                'amount' => $settlement['amount'],
            ]);

            return ['success' => true];
        } catch (\Throwable $e) {
            $db->rollBack();
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    private static function postSettlementToAccounts(array $settlement): void
    {
        $amount = (string) $settlement['amount'];
        $date = $settlement['settlement_date'];

        if ($settlement['from_entity_type'] === 'customer') {
            AccountStatementService::recordCustomerTransaction([
                'member_id' => (int) $settlement['from_entity_id'],
                'transaction_date' => $date,
                'document_type' => 'adjustment',
                'document_number' => $settlement['settlement_number'],
                'description' => 'تسوية لصالح: ' . $settlement['to_entity_name'],
                'credit' => $amount,
            ]);
        } elseif ($settlement['from_entity_type'] === 'supplier') {
            AccountStatementService::recordSupplierTransaction([
                'supplier_id' => (int) $settlement['from_entity_id'],
                'transaction_date' => $date,
                'document_type' => 'adjustment',
                'document_number' => $settlement['settlement_number'],
                'description' => 'تسوية لصالح: ' . $settlement['to_entity_name'],
                'debit' => $amount,
            ]);
        }

        if ($settlement['to_entity_type'] === 'customer') {
            AccountStatementService::recordCustomerTransaction([
                'member_id' => (int) $settlement['to_entity_id'],
                'transaction_date' => $date,
                'document_type' => 'adjustment',
                'document_number' => $settlement['settlement_number'],
                'description' => 'تسوية من: ' . $settlement['from_entity_name'],
                'debit' => $amount,
            ]);
        } elseif ($settlement['to_entity_type'] === 'supplier') {
            AccountStatementService::recordSupplierTransaction([
                'supplier_id' => (int) $settlement['to_entity_id'],
                'transaction_date' => $date,
                'document_type' => 'adjustment',
                'document_number' => $settlement['settlement_number'],
                'description' => 'تسوية من: ' . $settlement['from_entity_name'],
                'credit' => $amount,
            ]);
        }
    }
}
