<?php

namespace App\Tests\Dashboard;

use App\Appointment\Entity\Appointment;
use App\Auth\Entity\User;
use App\Clinic\Entity\Clinic;
use App\ClinicService\Entity\ServiceItem;
use App\ClinicService\Entity\ServiceSection;
use App\Doctor\Entity\Doctor;
use App\Tests\ApiTestCase;

/**
 * GET /api/v1/dashboard/{doctor,clinic} — `today_appointments` rows must carry
 * the extended fields (patient_mobile, doctor_name, service_name, slot_end)
 * added for the ported «لیست نوبت‌های جدید» dashboard table.
 *
 * NOTE: db_test is never reset, so patient mobiles use the ApiTestCase random
 * generator (never hardcoded) to avoid unique-constraint clashes across runs.
 */
class DashboardTodayAppointmentsTest extends ApiTestCase
{
    private function todayAppointment(Doctor $doctor, User $patient): Appointment
    {
        // now() is guaranteed within [today midnight, tomorrow midnight-1]
        $start = time();
        $appt  = $this->newAppointment($doctor, $patient, $start, $start + 1_800);
        $this->em->persist($appt);
        $this->em->flush();

        return $appt;
    }

    public function testDoctorTodayAppointmentsExposeExtendedFields(): void
    {
        $owner  = $this->createUser(['ROLE_DOCTOR']);
        $doctor = new Doctor($owner, 'حمیدی');
        $patient = $this->createUser(['ROLE_USER']);

        $section = new ServiceSection('doctor', 1, 'عمومی');
        $item    = new ServiceItem($section, 'ویزیت عمومی');
        $this->em->persist($doctor);
        $this->em->persist($section);
        $this->em->persist($item);
        $this->em->flush();

        $appt = $this->todayAppointment($doctor, $patient);
        $appt->setServiceItem($item);
        $this->em->flush();

        $res = $this->authJson('GET', '/api/v1/dashboard/doctor', $owner);
        self::assertSame(200, $this->responseCode());

        $rows = $res['data']['today_appointments'];
        self::assertNotEmpty($rows, 'today_appointments should contain the booked slot');
        $row = $rows[0];

        self::assertSame($patient->getMobileNumber(), $row['patient_mobile']);
        self::assertSame('حمیدی', $row['doctor_name']);
        self::assertSame('ویزیت عمومی', $row['service_name']);
        self::assertSame($appt->getSlotStart(), $row['slot_start']);
        self::assertSame($appt->getSlotEnd(), $row['slot_end']);
        self::assertArrayHasKey('status', $row);
    }

    public function testServiceNameNullWhenNoServiceItem(): void
    {
        $owner  = $this->createUser(['ROLE_DOCTOR']);
        $doctor = new Doctor($owner, 'حمیدی');
        $this->em->persist($doctor);
        $this->em->flush();

        $patient = $this->createUser(['ROLE_USER']);
        $this->todayAppointment($doctor, $patient);

        $res = $this->authJson('GET', '/api/v1/dashboard/doctor', $owner);
        self::assertSame(200, $this->responseCode());
        $row = $res['data']['today_appointments'][0];

        self::assertNull($row['service_name'], 'service_name is null when no service item is booked');
        self::assertSame($patient->getMobileNumber(), $row['patient_mobile']);
    }

    public function testClinicTodayAppointmentsExposeExtendedFields(): void
    {
        $clinicOwner = $this->createUser(['ROLE_CLINIC']);
        $clinic      = new Clinic($clinicOwner);
        $clinic->setName('کلینیک نمونه');

        $docOwner = $this->createUser(['ROLE_DOCTOR']);
        $doctor   = new Doctor($docOwner, 'حمیدی');
        $clinic->getDoctors()->add($doctor);

        $section = new ServiceSection('doctor', 1, 'عمومی');
        $item    = new ServiceItem($section, 'ویزیت عمومی');
        $patient = $this->createUser(['ROLE_USER']);

        $this->em->persist($doctor);
        $this->em->persist($clinic);
        $this->em->persist($section);
        $this->em->persist($item);
        $this->em->flush();

        $appt = $this->todayAppointment($doctor, $patient);
        $appt->setServiceItem($item);
        $this->em->flush();

        $res = $this->authJson('GET', '/api/v1/dashboard/clinic', $clinicOwner);
        self::assertSame(200, $this->responseCode());

        $rows = $res['data']['today_appointments'];
        self::assertNotEmpty($rows);
        $row = $rows[0];

        self::assertSame($patient->getMobileNumber(), $row['patient_mobile']);
        self::assertSame('حمیدی', $row['doctor_name']);
        self::assertSame('ویزیت عمومی', $row['service_name']);
        self::assertSame($appt->getSlotEnd(), $row['slot_end']);
    }

    public function testDoctorNotFoundReturns404(): void
    {
        // ROLE_DOCTOR user without a Doctor entity
        $user = $this->createUser(['ROLE_DOCTOR']);

        $res = $this->authJson('GET', '/api/v1/dashboard/doctor', $user);
        self::assertSame(404, $this->responseCode());
        self::assertFalse($res['success']);
    }
}
