<?php

namespace App\Pricing\Service;

use App\Appointment\Entity\Appointment;
use App\Pricing\Entity\PriceSnapshot;
use App\Pricing\Repository\PriceSnapshotRepository;
use App\Pricing\ValueObject\PriceQuote;
use Doctrine\ORM\EntityManagerInterface;

/**
 * ثبت فاکتور تفکیک‌شده روی نوبت.
 *
 * idempotent است: نوبتی که از قبل snapshot دارد، دومی نمی‌گیرد. کلید یکتای
 * `appointment_id` هم همین را در سطح دیتابیس تضمین می‌کند — دو فاکتور برای یک نوبت
 * یعنی دو حقیقت.
 */
final class PriceSnapshotService
{
    public function __construct(
        private readonly PriceSnapshotRepository $snapshots,
        private readonly EntityManagerInterface  $em,
    ) {}

    public function record(Appointment $appointment, PriceQuote $quote, ?int $now = null): PriceSnapshot
    {
        $existing = $this->snapshots->findForAppointment($appointment);

        if ($existing !== null) {
            return $existing;
        }

        $snapshot = new PriceSnapshot(
            $appointment,
            $appointment->getEntityType(),
            $appointment->getEntityId(),
            $quote->baseRials,
            $quote->itemsRials,
            $quote->discountRials,
            $quote->insuranceBaseRials,
            $quote->insuranceSupplementaryRials,
            $quote->taxRials,
            $quote->finalRials,
            $quote->depositRials,
            $quote->breakdown(),
            $now,
        );

        $this->em->persist($snapshot);
        $this->em->flush();

        return $snapshot;
    }

    /**
     * نوبتِ بدون سرویس (ویزیت سادهٔ حالت اسلاتی) هم باید فاکتور داشته باشد؛ خالی
     * گذاشتنش یعنی گزارش مالی یک ردیف کم دارد.
     */
    public function recordFlatVisit(Appointment $appointment, int $priceRials, ?int $now = null): PriceSnapshot
    {
        return $this->record(
            $appointment,
            new PriceQuote(
                baseRials: $priceRials,
                itemsRials: 0,
                discountRials: 0,
                insuranceBaseRials: 0,
                insuranceSupplementaryRials: 0,
                taxRials: 0,
                finalRials: $priceRials,
                depositRials: 0,
                sources: ['visit' => 'appointment_visit_price'],
            ),
            $now,
        );
    }
}
