<?php

namespace App\Secretary\Repository;

use App\Auth\Entity\User;
use App\Secretary\Entity\SecretaryEarning;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

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

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

    /** مجموع سهم یک منشی در یک بازه؛ بدون بازه = کل. */
    public function sumFor(User $secretary, ?int $from = null, ?int $to = null): int
    {
        $qb = $this->createQueryBuilder('e')
            ->select('COALESCE(SUM(e.shareRials), 0)')
            ->where('e.secretary = :user')
            ->setParameter('user', $secretary);

        if ($from !== null) {
            $qb->andWhere('e.createdAt >= :from')->setParameter('from', $from);
        }
        if ($to !== null) {
            $qb->andWhere('e.createdAt <= :to')->setParameter('to', $to);
        }

        return (int) $qb->getQuery()->getSingleScalarResult();
    }

    public function countFor(User $secretary): int
    {
        return (int) $this->createQueryBuilder('e')
            ->select('COUNT(e.id)')
            ->where('e.secretary = :user')
            ->setParameter('user', $secretary)
            ->getQuery()
            ->getSingleScalarResult();
    }

    /**
     * گزارش سطر-به-سطر برای پنل منشی: هر ردیف با تفکیک مالیِ همان پرداخت و نوبت.
     *
     * @return array{items: list<array<string, mixed>>, total: int}
     */
    public function reportFor(User $secretary, int $page, int $limit, ?int $from = null, ?int $to = null): array
    {
        $qb = $this->createQueryBuilder('e')
            ->select(
                'e.uuid, e.sharePercent, e.shareRials, e.createdAt,
                 b.grossRials, b.smsFeeRials, b.taxRials, b.netAfterTaxRials,
                 a.uuid AS appointment_uuid, doc.name AS doctor_name'
            )
            ->join('e.breakdown', 'b')
            ->join('b.payment', 'p')
            ->leftJoin('p.appointment', 'a')
            ->leftJoin('a.doctor', 'doc')
            ->where('e.secretary = :user')
            ->setParameter('user', $secretary)
            ->orderBy('e.createdAt', 'DESC');

        if ($from !== null) {
            $qb->andWhere('e.createdAt >= :from')->setParameter('from', $from);
        }
        if ($to !== null) {
            $qb->andWhere('e.createdAt <= :to')->setParameter('to', $to);
        }

        $total = (int) (clone $qb)->select('COUNT(e.id)')->resetDQLPart('orderBy')
            ->getQuery()->getSingleScalarResult();

        $rows = $qb->setFirstResult(($page - 1) * $limit)->setMaxResults($limit)
            ->getQuery()->getArrayResult();

        $items = array_map(static fn(array $r) => [
            'uuid'                => $r['uuid'],
            'appointment_uuid'    => $r['appointment_uuid'] ?? null,
            'doctor_name'         => $r['doctor_name'] ?? null,
            'gross_rials'         => (int) $r['grossRials'],
            'sms_fee_rials'       => (int) $r['smsFeeRials'],
            'tax_rials'           => (int) $r['taxRials'],
            'net_after_tax_rials' => (int) $r['netAfterTaxRials'],
            'share_percent'       => (float) $r['sharePercent'],
            'share_rials'         => (int) $r['shareRials'],
            'created_at'          => (int) $r['createdAt'],
        ], $rows);

        return ['items' => $items, 'total' => $total];
    }
}
