<?php

namespace MintyPHP\Tests\Module\Helpdesk\Service;

use MintyPHP\Module\Helpdesk\Service\HandoverNotificationService;
use MintyPHP\Service\Mail\MailService;
use PHPUnit\Framework\TestCase;

class HandoverNotificationServiceTest extends TestCase
{
    private function createNotificationService(?MailService $mailService = null): HandoverNotificationService
    {
        return new HandoverNotificationService(
            $mailService ?? $this->createMock(MailService::class)
        );
    }

    private function assignedHandover(array $overrides = []): array
    {
        return array_merge([
            'id' => 1,
            'debitor_name' => 'Acme Corp',
            'domain_url' => 'example.com',
            'due_date' => '2026-12-31',
            'assigned_to_email' => 'employee@example.com',
            'assigned_to_label' => 'John Doe',
            'assigned_by_label' => 'Manager',
            'assigned_by_email' => 'manager@example.com',
        ], $overrides);
    }

    // ── notifyAssigned ────────────────────────────────────────────────

    public function testNotifyAssignedSendsEmailToAssignee(): void
    {
        $mailService = $this->createMock(MailService::class);
        $mailService->expects($this->once())
            ->method('sendTemplate')
            ->with(
                'handover_assigned',
                $this->callback(fn (array $vars): bool => $vars['assignee_name'] === 'John Doe'
                    && $vars['assigned_by_name'] === 'Manager'
                    && $vars['debitor_name'] === 'Acme Corp'
                    && $vars['due_date'] === '2026-12-31'
                ),
                'employee@example.com',
                $this->isType('string')
            );

        $service = $this->createNotificationService($mailService);
        $service->notifyAssigned($this->assignedHandover());
    }

    public function testNotifyAssignedSkipsWhenNoEmail(): void
    {
        $mailService = $this->createMock(MailService::class);
        $mailService->expects($this->never())->method('sendTemplate');

        $service = $this->createNotificationService($mailService);
        $service->notifyAssigned($this->assignedHandover(['assigned_to_email' => '']));
    }

    public function testNotifyAssignedSkipsWhenEmailIsNull(): void
    {
        $mailService = $this->createMock(MailService::class);
        $mailService->expects($this->never())->method('sendTemplate');

        $service = $this->createNotificationService($mailService);
        $service->notifyAssigned($this->assignedHandover(['assigned_to_email' => null]));
    }

    public function testNotifyAssignedFallsBackToDashForEmptyDebitor(): void
    {
        $mailService = $this->createMock(MailService::class);
        $mailService->expects($this->once())
            ->method('sendTemplate')
            ->with(
                'handover_assigned',
                $this->callback(fn (array $vars): bool => $vars['debitor_name'] === '—'),
                $this->anything(),
                $this->anything()
            );

        $service = $this->createNotificationService($mailService);
        $service->notifyAssigned($this->assignedHandover(['debitor_name' => '']));
    }

    public function testNotifyAssignedFallsBackToDashForEmptyDueDate(): void
    {
        $mailService = $this->createMock(MailService::class);
        $mailService->expects($this->once())
            ->method('sendTemplate')
            ->with(
                'handover_assigned',
                $this->callback(fn (array $vars): bool => $vars['due_date'] === '—'),
                $this->anything(),
                $this->anything()
            );

        $service = $this->createNotificationService($mailService);
        $service->notifyAssigned($this->assignedHandover(['due_date' => '']));
    }

    // ── notifyReviewRequested ─────────────────────────────────────────

    public function testNotifyReviewRequestedSendsEmailToManager(): void
    {
        $mailService = $this->createMock(MailService::class);
        $mailService->expects($this->once())
            ->method('sendTemplate')
            ->with(
                'handover_review_requested',
                $this->callback(fn (array $vars): bool => $vars['manager_name'] === 'Manager'
                    && $vars['assignee_name'] === 'John Doe'
                    && $vars['debitor_name'] === 'Acme Corp'
                ),
                'manager@example.com',
                $this->isType('string')
            );

        $service = $this->createNotificationService($mailService);
        $service->notifyReviewRequested($this->assignedHandover([
            'assigned_to_label' => 'John Doe',
            'assigned_by_label' => 'Manager',
            'assigned_by_email' => 'manager@example.com',
        ]));
    }

    public function testNotifyReviewRequestedSkipsWhenNoManagerEmail(): void
    {
        $mailService = $this->createMock(MailService::class);
        $mailService->expects($this->never())->method('sendTemplate');

        $service = $this->createNotificationService($mailService);
        $service->notifyReviewRequested($this->assignedHandover(['assigned_by_email' => '']));
    }

    public function testNotifyReviewRequestedFallsBackToDashForEmptyAssigneeName(): void
    {
        $mailService = $this->createMock(MailService::class);
        $mailService->expects($this->once())
            ->method('sendTemplate')
            ->with(
                'handover_review_requested',
                $this->callback(fn (array $vars): bool => $vars['assignee_name'] === '—'),
                $this->anything(),
                $this->anything()
            );

        $service = $this->createNotificationService($mailService);
        $service->notifyReviewRequested($this->assignedHandover(['assigned_to_label' => '']));
    }
}
