<?php

namespace Modules\Inventory\Services;

use Modules\Accounts\Enums\AcctReferenceTypeEnum;
use Modules\Accounts\Enums\AcctVoucherTypeEnum;
use Modules\Accounts\Models\AccountVoucher;
use Modules\Core\Enums\PaymentMethodEnum;
use Modules\Inventory\DTO\VoucherLineData;
use Modules\Inventory\Models\PurchaseInvoice;
use Modules\Inventory\Models\PurchasePayment;

class PurchasePaymentPostingService
{
    public function __construct(
        private VoucherService $voucherService
    ) {}

    public function create(PurchaseInvoice $invoice, PurchasePayment $payment): AccountVoucher {
        $supplier = $invoice->supplier;
        $paymentMethod = PaymentMethodEnum::from($payment->payment_method)->getLabel();
        $paymentAmount = (float) $payment->amount;

        $lines = [
            VoucherLineData::fromDebit(
                accountId: $supplier->account_id,
                amount: $paymentAmount,
                description: "Supplier Payment: {$supplier->name} (Invoice: {$invoice->invoice_no})",
            ),
            VoucherLineData::fromCredit(
                accountId: $payment->account_id,
                amount: $paymentAmount,
                description: "{$paymentMethod} Payment (Invoice: {$invoice->invoice_no})",
            )
        ];

        $voucher = $this->voucherService->create(
            voucherData: [
                'fiscal_year_id' => $payment->fiscal_year_id,
                'accounting_period_id' => $payment->accounting_period_id,
                'voucher_date' => $payment->payment_date,
                'voucher_type' => AcctVoucherTypeEnum::PAYMENT->value,
                'reference' => $invoice->invoice_no,
                'reference_type' => AcctReferenceTypeEnum::PURCHASE_PAYMENT->value,
                'reference_id' => $payment->id,
            ],

            lines: $lines
        );

        return $voucher;
    }

    public function createReversal(AccountVoucher $voucher, array $reversalData): AccountVoucher
    {
        $reversalDescription = "Reversal of Voucher {$voucher->voucher_no}";
        $lines = [];

        foreach ($voucher->lines as $line) {
            $lines[] = VoucherLineData::fromReversal(
                line: $line,
                description: $reversalDescription
            );
        }

        $reverseVoucher = $this->voucherService->createReversal(
            voucherData: [
                'fiscal_year_id' => $reversalData['fiscal_year_id'],
                'accounting_period_id' => $reversalData['accounting_period_id'],
                'voucher_date' => $reversalData['reversal_date'],
                'voucher_type' => AcctVoucherTypeEnum::REVERSING->value,
                'reference' => $reversalData['reversal_reason'] ?: $reversalDescription,
                'reference_type' => $voucher->reference_type,
                'reference_id' => $voucher->reference_id,
                'reversed_from' => $voucher->id,
            ],

            lines: $lines
        );

        return $reverseVoucher;
    }
}
