<?php

app_require('classes/slack.php');

use classes\slack;

final class SlackCustomerRegistrationWebhookFake extends slack
{
    public array $messages = [];

    public function __construct(
        private readonly string $webhook,
        private readonly string $sendResult = 'Message sent successfully. Response: ok',
        private readonly ?string $internalDepartmentGoalProgressWebhook = null
    ) {
        // Skip parent config loading for unit isolation.
    }

    protected function get_customer_registration_webhook_url(): string
    {
        return $this->webhook;
    }

    public function get_internal_department_goal_progress_webhook_url(): string
    {
        return $this->internalDepartmentGoalProgressWebhook ?? $this->webhook;
    }

    public function send_webhook_message(string $message, string $webhook): string
    {
        $this->messages[] = [
            'message' => $message,
            'webhook' => $webhook,
        ];

        return $this->sendResult;
    }
}

it('does not send customer registration test notifications without a saved webhook', function (): void {
    $slack = new SlackCustomerRegistrationWebhookFake('');

    $result = $slack->test_customer_registration_webhook();

    expect($result)
        ->toBe([
            'configured' => false,
            'sent' => false,
            'message' => 'Slack customer registration webhook URL is not configured.',
        ])
        ->and($slack->messages)->toBe([])
        ->and($slack->get_log())->toBe([]);
});

it('sends customer registration test notifications to the saved webhook', function (): void {
    $slack = new SlackCustomerRegistrationWebhookFake('https://hooks.slack.test/services/secret-token');

    $result = $slack->test_customer_registration_webhook();

    expect($result)
        ->toBe([
            'configured' => true,
            'sent' => true,
            'message' => 'Slack test message sent successfully.',
        ])
        ->and($slack->messages)->toHaveCount(1)
        ->and($slack->messages[0]['webhook'])->toBe('https://hooks.slack.test/services/secret-token')
        ->and($slack->messages[0]['message'])->toContain('Truck Wash Slack test')
        ->and($slack->messages[0]['message'])->toContain('Customer registration notifications are configured correctly.')
        ->and(json_encode($slack->get_log(), JSON_UNESCAPED_SLASHES))->toContain('sent successfully')
        ->and(json_encode($slack->get_log(), JSON_UNESCAPED_SLASHES))->not->toContain('secret-token');
});

it('reports customer registration test notification failures without exposing the webhook', function (): void {
    $slack = new SlackCustomerRegistrationWebhookFake(
        'https://hooks.slack.test/services/secret-token',
        'Failed to send message: cURL error for https://hooks.slack.test/services/secret-token'
    );

    $result = $slack->test_customer_registration_webhook();

    expect($result)
        ->toBe([
            'configured' => true,
            'sent' => false,
            'message' => 'Slack test message failed.',
        ])
        ->and($slack->messages)->toHaveCount(1)
        ->and(json_encode($result, JSON_UNESCAPED_SLASHES))->not->toContain('secret-token')
        ->and(json_encode($slack->get_log(), JSON_UNESCAPED_SLASHES))->toContain('failed')
        ->and(json_encode($slack->get_log(), JSON_UNESCAPED_SLASHES))->not->toContain('secret-token');
});

it('does not send internal department goal progress test notifications without a saved webhook', function (): void {
    $slack = new SlackCustomerRegistrationWebhookFake(
        'https://hooks.slack.test/services/customer-registration',
        internalDepartmentGoalProgressWebhook: ''
    );

    $result = $slack->test_internal_department_goal_progress_webhook();

    expect($result)
        ->toBe([
            'configured' => false,
            'sent' => false,
            'message' => 'Slack internal department goal progress webhook URL is not configured.',
        ])
        ->and($slack->messages)->toBe([]);
});

it('sends internal department goal progress test notifications to the saved webhook', function (): void {
    $slack = new SlackCustomerRegistrationWebhookFake(
        'https://hooks.slack.test/services/customer-registration',
        internalDepartmentGoalProgressWebhook: 'https://hooks.slack.test/services/internal-goals-secret'
    );

    $result = $slack->test_internal_department_goal_progress_webhook();

    expect($result)
        ->toBe([
            'configured' => true,
            'sent' => true,
            'message' => 'Slack test message sent successfully.',
        ])
        ->and($slack->messages)->toHaveCount(1)
        ->and($slack->messages[0]['webhook'])->toBe('https://hooks.slack.test/services/internal-goals-secret')
        ->and($slack->messages[0]['message'])->toContain('Truck Wash Slack test')
        ->and($slack->messages[0]['message'])->toContain('Internal department goal progress notifications are configured correctly.')
        ->and(json_encode($slack->get_log(), JSON_UNESCAPED_SLASHES))->toContain('sent successfully')
        ->and(json_encode($slack->get_log(), JSON_UNESCAPED_SLASHES))->not->toContain('internal-goals-secret');
});

it('reports internal department goal progress test notification failures without exposing the webhook', function (): void {
    $slack = new SlackCustomerRegistrationWebhookFake(
        'https://hooks.slack.test/services/customer-registration',
        'Failed to send message: cURL error for https://hooks.slack.test/services/internal-goals-secret',
        'https://hooks.slack.test/services/internal-goals-secret'
    );

    $result = $slack->test_internal_department_goal_progress_webhook();

    expect($result)
        ->toBe([
            'configured' => true,
            'sent' => false,
            'message' => 'Slack test message failed.',
        ])
        ->and($slack->messages)->toHaveCount(1)
        ->and(json_encode($result, JSON_UNESCAPED_SLASHES))->not->toContain('internal-goals-secret')
        ->and(json_encode($slack->get_log(), JSON_UNESCAPED_SLASHES))->toContain('failed')
        ->and(json_encode($slack->get_log(), JSON_UNESCAPED_SLASHES))->not->toContain('internal-goals-secret');
});
