<?php

namespace Modules\ClinicStaffPortal\Console;

use Illuminate\Console\Command;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use Modules\ClinicStaffPortal\Services\StaffPushSender;

/**
 * Push newly-booked appointments to subscribed staff devices (scheduled every
 * 15 min, live env; cache-deduped). Ward-alert and admission pushes were dropped
 * with the VetAdmission inpatient module, absent from the ClinicCore stack.
 *
 *   php artisan staff-portal:push-updates
 *
 */
class PushStaffUpdatesCommand extends Command
{
    protected $signature   = 'staff-portal:push-updates {--lookback=30 : minutes back to scan}';
    protected $description = 'Push newly-booked appointments to subscribed staff devices';

    public function handle(StaffPushSender $sender): int
    {
        $since = Carbon::now()->subMinutes((int) $this->option('lookback'));
        $base  = rtrim(env('STAFF_PWA_URL', url('/staff-app/')), '/');
        $sent  = 0;

        $sent += $this->pushSchedule($sender, $since, $base);

        $this->info("Dispatched {$sent} staff notification(s).");
        return self::SUCCESS;
    }

    /** Newly-booked future appointments â†’ the doctor's device ('schedule'). */
    private function pushSchedule(StaffPushSender $sender, Carbon $since, string $base): int
    {
        if (! class_exists(\Modules\ClinicCore\Entities\ClcAppointment::class)) return 0;

        $rows = \Modules\ClinicCore\Entities\ClcAppointment::with('pet')
            ->where('created_at', '>=', $since)
            ->whereDate('appointment_date', '>=', Carbon::today())
            ->whereNotNull('doctor_id')
            ->whereNotIn('status', ['cancelled', 'no_show'])->get();

        $count = 0;
        foreach ($rows as $appt) {
            $key = "staff_push.appt.{$appt->id}";
            if (Cache::has($key)) continue;
            $userId = $this->doctorUserId($appt->doctor_id);
            if ($userId) {
                $when = Carbon::parse($appt->appointment_date)->format('d M')
                      . ' Â· ' . Carbon::parse($appt->appointment_time)->format('H:i');
                $count += $sender->sendToUser($userId, 'schedule', [
                    'title' => 'ðŸ“… New appointment booked',
                    'body'  => (optional($appt->pet)->patient_name ?? 'A patient') . ' â€” ' . $when,
                    'url'   => $base . '/schedule',
                    'icon'  => $base . '/icon-192.png',
                    'tag'   => 'vc-appt-' . $appt->id,
                ]);
            }
            Cache::put($key, true, now()->addDay());
        }
        return $count;
    }

    /** Map a ClcDoctor id â†’ its linked ERP user id (cached briefly). */
    private function doctorUserId(?int $doctorId): ?int
    {
        if (! $doctorId) return null;
        return Cache::remember("staff_push.doctor_user.{$doctorId}", 300, function () use ($doctorId) {
            $d = \Modules\ClinicCore\Entities\ClcDoctor::find($doctorId);
            return $d?->user_id ? (int) $d->user_id : null;
        });
    }
}
