<?php

namespace App\Insurance\Repository;

use App\Insurance\Entity\InsuranceCoverageDefault;
use App\Insurance\Enum\ServiceCategory;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

class InsuranceCoverageDefaultRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, InsuranceCoverageDefault::class);
    }

    /** @return InsuranceCoverageDefault[] */
    public function findByInsurance(int $insuranceId): array
    {
        return $this->findBy(['insuranceId' => $insuranceId]);
    }

    public function findOneFor(int $insuranceId, ServiceCategory $category): ?InsuranceCoverageDefault
    {
        return $this->findOneBy(['insuranceId' => $insuranceId, 'serviceCategory' => $category]);
    }

    /** @return array<string, float> service_category => percent */
    public function percentMapFor(int $insuranceId): array
    {
        $map = [];
        foreach ($this->findByInsurance($insuranceId) as $row) {
            $map[$row->getServiceCategory()->value] = $row->getCoveragePercent();
        }

        return $map;
    }

    /**
     * @param list<int> $insuranceIds
     * @return array<int, array<string, float>> insurance_id => (service_category => percent)
     */
    public function percentMapForMany(array $insuranceIds): array
    {
        if ($insuranceIds === []) {
            return [];
        }

        $rows = $this->createQueryBuilder('d')
            ->select('d.insuranceId AS insurance_id', 'd.serviceCategory AS service_category', 'd.coveragePercent AS coverage_percent')
            ->where('d.insuranceId IN (:ids)')
            ->setParameter('ids', $insuranceIds)
            ->getQuery()
            ->getArrayResult();

        $map = [];
        foreach ($rows as $row) {
            $category = $row['service_category'] instanceof ServiceCategory
                ? $row['service_category']->value
                : (string) $row['service_category'];
            $map[(int) $row['insurance_id']][$category] = (float) $row['coverage_percent'];
        }

        return $map;
    }

    public function save(InsuranceCoverageDefault $entity, bool $flush = true): void
    {
        $this->getEntityManager()->persist($entity);
        if ($flush) {
            $this->getEntityManager()->flush();
        }
    }

    public function flush(): void
    {
        $this->getEntityManager()->flush();
    }

    public function removeByInsurance(int $insuranceId): void
    {
        $this->createQueryBuilder('d')
            ->delete()
            ->where('d.insuranceId = :id')
            ->setParameter('id', $insuranceId)
            ->getQuery()
            ->execute();
    }
}
