<?php

namespace App\Insurance\Repository;

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

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

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

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

        return $map;
    }

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

        $rows = $this->createQueryBuilder('c')
            ->select('c.tenantInsuranceId AS tenant_insurance_id', 'c.serviceCategory AS service_category', 'c.coveragePercent AS coverage_percent')
            ->where('c.tenantInsuranceId IN (:ids)')
            ->setParameter('ids', $tenantInsuranceIds)
            ->getQuery()
            ->getArrayResult();

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

        return $map;
    }

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

    public function remove(TenantInsuranceCategoryCoverage $entity, bool $flush = false): void
    {
        $this->getEntityManager()->remove($entity);
        if ($flush) {
            $this->getEntityManager()->flush();
        }
    }

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

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