<?php

namespace App\Services\Finance;

use App\Models\Invoice;
use App\Models\InvoiceLine;
use App\Models\Student;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use InvalidArgumentException;

class BulkInvoiceService
{
    public function __construct(
        private readonly DocumentNumberService $documentNumbers,
        private readonly InvoiceService $invoiceService,
    ) {}

    /**
     * @param  array<int>  $studentIds
     * @param  array<string, mixed>  $lineTemplate
     * @return Collection<int, Invoice>
     */
    public function generate(
        array $studentIds,
        array $lineTemplate,
        string $issueDate,
        ?string $dueDate = null,
        string $taxAmount = '0.00',
    ): Collection {
        if ($studentIds === []) {
            throw new InvalidArgumentException('Select at least one student for bulk invoicing.');
        }

        $quantity = (string) ($lineTemplate['quantity'] ?? '1');
        $unitPrice = (string) $lineTemplate['unit_price'];
        $lineTotal = bcmul($quantity, $unitPrice, 2);
        $subtotal = $lineTotal;
        $totalAmount = bcadd($subtotal, $taxAmount, 2);

        if (bccomp($totalAmount, '0.00', 2) <= 0) {
            throw new InvalidArgumentException('Bulk invoice total must be greater than zero.');
        }

        return DB::transaction(function () use ($studentIds, $lineTemplate, $issueDate, $dueDate, $taxAmount, $lineTotal, $subtotal, $totalAmount, $quantity, $unitPrice) {
            $invoices = collect();

            foreach ($studentIds as $studentId) {
                $student = Student::query()->findOrFail($studentId);

                $invoice = Invoice::query()->create([
                    'invoice_number' => $this->documentNumbers->next('BULK', Invoice::class, 'invoice_number'),
                    'student_id' => $student->id,
                    'issue_date' => $issueDate,
                    'due_date' => $dueDate,
                    'status' => 'draft',
                    'subtotal' => $subtotal,
                    'tax_amount' => $taxAmount,
                    'total_amount' => $totalAmount,
                    'amount_paid' => 0,
                    'balance_due' => $totalAmount,
                    'notes' => $lineTemplate['description'] ?? 'Bulk fee invoice',
                ]);

                InvoiceLine::query()->create([
                    'invoice_id' => $invoice->id,
                    'description' => $lineTemplate['description'],
                    'quantity' => $quantity,
                    'unit_price' => $unitPrice,
                    'line_total' => $lineTotal,
                    'account_id' => $lineTemplate['account_id'],
                ]);

                $invoices->push($this->invoiceService->issue($invoice->fresh(['lines', 'student'])));
            }

            return $invoices;
        });
    }
}
