<?php
declare(strict_types=1);

namespace App\Modules\Accounting\Services;

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

final class LetterOfGuaranteeService
{
    private const VALID_TRANSITIONS = [
        'draft' => ['active'],
        'active' => ['extended', 'released', 'called'],
        'extended' => ['released', 'called'],
        'called' => ['settled'],
    ];

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

        return $db->insert('letters_of_guarantee', [
            'guarantee_number' => $data['guarantee_number'],
            'type' => $data['type'] ?? 'bid',
            'beneficiary_name' => $data['beneficiary_name'],
            'issuing_bank' => $data['issuing_bank'],
            'amount' => $data['amount'],
            'currency_code' => $data['currency_code'] ?? 'EGP',
            'issue_date' => $data['issue_date'] ?? date('Y-m-d'),
            'expiry_date' => $data['expiry_date'],
            'purpose' => $data['purpose'] ?? null,
            'bank_account_id' => $data['bank_account_id'] ?? null,
            'margin_amount' => $data['margin_amount'] ?? '0.00',
            'commission_rate' => $data['commission_rate'] ?? '0.00',
            'status' => 'draft',
            'notes' => $data['notes'] ?? null,
            'created_by' => $employee ? (int) $employee->id : null,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ]);
    }

    public static function transition(int $guaranteeId, string $newStatus): array
    {
        $db = App::getInstance()->db();

        $guarantee = $db->selectOne("SELECT * FROM letters_of_guarantee WHERE id = ?", [$guaranteeId]);
        if (!$guarantee) {
            return ['success' => false, 'error' => 'خطاب الضمان غير موجود'];
        }

        $current = $guarantee['status'];
        $allowed = self::VALID_TRANSITIONS[$current] ?? [];

        if (!in_array($newStatus, $allowed, true)) {
            return ['success' => false, 'error' => "لا يمكن الانتقال من {$current} إلى {$newStatus}"];
        }

        $updateData = [
            'status' => $newStatus,
            'updated_at' => date('Y-m-d H:i:s'),
        ];

        if ($newStatus === 'released') {
            $updateData['released_date'] = date('Y-m-d');
        }

        $db->update('letters_of_guarantee', $updateData, 'id = ?', [$guaranteeId]);

        EventBus::dispatch('accounting.guarantee.status_changed', [
            'guarantee_id' => $guaranteeId,
            'from_status' => $current,
            'to_status' => $newStatus,
            'amount' => (string) $guarantee['amount'],
        ]);

        return ['success' => true];
    }

    public static function getExpiringWithinDays(int $days = 30): array
    {
        $db = App::getInstance()->db();
        $futureDate = date('Y-m-d', strtotime("+{$days} days"));

        return $db->select(
            "SELECT * FROM letters_of_guarantee
             WHERE status IN ('active', 'extended')
             AND expiry_date <= ?
             ORDER BY expiry_date ASC",
            [$futureDate]
        );
    }
}
