<?php

namespace App\Services;

use App\Models\Tenant;
use Illuminate\Support\Facades\DB;
use InvalidArgumentException;

class FinancialNumberSequenceService
{
    private const MAP = [
        'invoice' => ['table' => 'invoices', 'column' => 'invoice_number', 'prefix' => 'INV'],
        'payment' => ['table' => 'payments', 'column' => 'payment_number', 'prefix' => 'PAY'],
        'receipt' => ['table' => 'receipts', 'column' => 'receipt_number', 'prefix' => 'REC'],
        'refund' => ['table' => 'refunds', 'column' => 'refund_number', 'prefix' => 'RFD'],
        'journal' => ['table' => 'journal_entries', 'column' => 'entry_number', 'prefix' => 'JRN'],
        'renewal' => ['table' => 'renewal_opportunities', 'column' => 'renewal_number', 'prefix' => 'REN'],
    ];

    public function next(Tenant $tenant, string $type): string
    {
        $definition = self::MAP[$type] ?? throw new InvalidArgumentException("Unknown sequence type [{$type}].");
        $year = now()->format('Y');
        $pattern = "{$definition['prefix']}-{$year}-%";

        $lastNumber = DB::table($definition['table'])
            ->where('tenant_id', $tenant->id)
            ->where($definition['column'], 'like', $pattern)
            ->lockForUpdate()
            ->max($definition['column']);

        $next = 1;
        if ($lastNumber) {
            $parts = explode('-', $lastNumber);
            $next = ((int) end($parts)) + 1;
        }

        return sprintf('%s-%s-%06d', $definition['prefix'], $year, $next);
    }
}
