<?php

namespace App\Services\Refunds;

use App\Models\AdditionalCharge;
use App\Models\Invoice;
use App\Services\Discounts\DiscountInvoiceService;

class RefundInvoiceAdjustmentService
{
    public function __construct(private DiscountInvoiceService $invoiceService)
    {
    }

    public function applyBookChargeAndUpdateInvoice(
        Invoice $invoice,
        int $parentId,
        array $refundDetails,
        string $semester,
        ?int $actorId
    ): array {
        $bookChargeTitle = 'Book Fee (Non-Refundable)';
        $bookChargeDesc = 'Book fee retained for withdrawals before the refund deadline.';

        $bookPrice = (float) ($refundDetails['book_price'] ?? 0.0);
        $eligible = !empty($refundDetails['eligible']);

        $bookChargeDelta = 0.0;
        $bookChargeAction = 'none';
        $bookChargeId = null;

        $existingCharge = AdditionalCharge::query()
            ->where('invoice_id', (int) $invoice->id)
            ->where('parent_id', (int) $parentId)
            ->where('school_year', (string) $invoice->school_year)
            ->where('title', $bookChargeTitle)
            ->orderByDesc('id')
            ->first();

        if ($eligible && $bookPrice > 0) {
            if ($existingCharge) {
                $oldAmount = (float) ($existingCharge->amount ?? 0.0);
                $bookChargeId = (int) $existingCharge->id;
                if (abs($oldAmount - $bookPrice) > 0.00001 || ($existingCharge->status ?? '') !== 'applied') {
                    $existingCharge->update([
                        'charge_type' => 'add',
                        'title' => $bookChargeTitle,
                        'description' => $bookChargeDesc,
                        'amount' => $bookPrice,
                        'status' => 'applied',
                    ]);
                    $bookChargeDelta = round($bookPrice - $oldAmount, 2);
                    $bookChargeAction = 'updated';
                }
            } else {
                $bookChargeId = AdditionalCharge::query()->insertGetId([
                    'parent_id' => (int) $parentId,
                    'invoice_id' => (int) $invoice->id,
                    'school_year' => (string) $invoice->school_year,
                    'semester' => $semester,
                    'charge_type' => 'add',
                    'title' => $bookChargeTitle,
                    'description' => $bookChargeDesc,
                    'amount' => $bookPrice,
                    'status' => 'applied',
                    'created_by' => $actorId,
                    'created_at' => utc_now(),
                    'updated_at' => utc_now(),
                ]);

                if ($bookChargeId) {
                    $bookChargeDelta = round($bookPrice, 2);
                    $bookChargeAction = 'inserted';
                }
            }
        } elseif ($existingCharge) {
            $oldAmount = (float) ($existingCharge->amount ?? 0.0);
            $bookChargeId = (int) $existingCharge->id;
            $existingCharge->delete();
            $bookChargeDelta = round(-$oldAmount, 2);
            $bookChargeAction = 'deleted';
        }

        $this->invoiceService->recalculateInvoice((int) $invoice->id, (string) $invoice->school_year);

        return [
            'book_charge_action' => $bookChargeAction,
            'book_charge_delta' => $bookChargeDelta,
            'book_charge_id' => $bookChargeId,
        ];
    }
}
