<?php

namespace App\Services\Care;

use App\Models\CareQueueTicket;
use App\Models\CareServicePoint;
use App\Models\CareVoiceAnnouncement;

class CareVoiceAnnouncementService
{
    public function announceCalled(CareQueueTicket $ticket, CareServicePoint $point, ?string $locale = null): CareVoiceAnnouncement
    {
        $ticket->loadMissing(['organization', 'serviceQueue']);
        $locale ??= 'en';
        $message = $this->buildMessage($ticket, $point, $locale);

        return CareVoiceAnnouncement::create([
            'owner_ref' => $ticket->owner_ref,
            'organization_id' => $ticket->organization_id,
            'branch_id' => $ticket->serviceQueue->branch_id,
            'ticket_id' => $ticket->id,
            'locale' => $locale,
            'message' => $message,
            'voice' => 'female',
            'volume' => 80,
            'repeat_count' => 1,
            'status' => 'pending',
        ]);
    }

    protected function buildMessage(CareQueueTicket $ticket, CareServicePoint $point, string $locale): string
    {
        $destination = $point->displayDestination();
        $staff = trim((string) ($point->staff_display_name ?? ''));
        $queueName = trim((string) ($ticket->serviceQueue?->name ?? ''));
        $templates = config('care.announcement_templates', []);

        if ($staff !== '') {
            $richDestination = $queueName !== '' && ! str_contains(strtolower($destination), strtolower($queueName))
                ? trim($queueName.' '.$destination)
                : $destination;
            $template = $templates['with_staff'] ?? ':ticket, :staff, :destination.';

            return rtrim(str_replace(
                [':ticket', ':staff', ':destination', ':counter'],
                [$ticket->ticket_number, $staff, $richDestination, $richDestination],
                $template,
            ), '.').'.';
        }

        $template = $templates[$locale]
            ?? $templates['en']
            ?? 'Ticket :ticket, please proceed to :destination.';

        return str_replace(
            [':ticket', ':destination', ':counter'],
            [$ticket->ticket_number, $destination, $destination],
            $template,
        );
    }

    /**
     * @param  list<int>|null  $queueIds
     * @return list<array<string, mixed>>
     */
    public function pendingForBranch(int $branchId, ?array $queueIds = null, int $limit = 10): array
    {
        return CareVoiceAnnouncement::query()
            ->where('branch_id', $branchId)
            ->where('status', 'pending')
            ->when($queueIds, function ($query, array $queueIds) {
                $query->whereHas('ticket', fn ($ticket) => $ticket->whereIn('service_queue_id', $queueIds));
            })
            ->orderBy('id')
            ->limit($limit)
            ->get()
            ->map(fn (CareVoiceAnnouncement $a) => [
                'id' => $a->id,
                'message' => $a->message,
                'locale' => $a->locale,
                'voice' => $a->voice,
                'volume' => $a->volume,
                'repeat_count' => $a->repeat_count,
            ])
            ->all();
    }

    public function markPlayed(CareVoiceAnnouncement $announcement): void
    {
        $announcement->update(['status' => 'played', 'played_at' => now()]);
    }
}
