<?php

use App\Enums\WorkDayType;
use App\Models\WorkCalendar;
use App\Services\WorkCalendarService;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;

uses(TestCase::class, RefreshDatabase::class);

test('it correctly identifies working days and holidays', function () {
    $service = new WorkCalendarService();

    // 2026-04-11 Szombat (Alapesetben nem munkanap)
    $saturday = Carbon::parse('2026-04-11');
    expect($service->isWorkDay($saturday))->toBeFalse();

    // 2026-04-13 Hétfő (Alapesetben munkanap)
    $monday = Carbon::parse('2026-04-13');
    expect($service->isWorkDay($monday))->toBeTrue();

    // Rögzítsünk egy szünnapot a hétfőre
    WorkCalendar::create([
        'date' => '2026-04-13',
        'type' => WorkDayType::Holiday,
        'description' => 'Test Holiday'
    ]);

    expect($service->isWorkDay($monday))->toBeFalse();

    // Rögzítsünk egy munkanapot a szombatra
    WorkCalendar::create([
        'date' => '2026-04-11',
        'type' => WorkDayType::WorkingDay,
        'description' => 'Test Working Saturday'
    ]);

    expect($service->isWorkDay($saturday))->toBeTrue();
});

test('it calculates next working day correctly', function () {
    $service = new WorkCalendarService();

    // 2026-04-10 Péntek
    $friday = Carbon::parse('2026-04-10');

    // Alapesetben a hétvége miatt hétfő lesz a következő munkanap
    expect($service->getNextWorkDay($friday)->toDateString())->toBe('2026-04-13');

    // Ha a szombat munkanap lesz
    WorkCalendar::create([
        'date' => '2026-04-11',
        'type' => WorkDayType::WorkingDay,
        'description' => 'Working Saturday'
    ]);

    expect($service->getNextWorkDay($friday)->toDateString())->toBe('2026-04-11');

    // Ha a hétfő szünnap lesz
    WorkCalendar::create([
        'date' => '2026-04-13',
        'type' => WorkDayType::Holiday,
        'description' => 'Monday Holiday'
    ]);

    // Péntek után szombat munkanap, vasárnap nem, hétfő szünnap -> kedd (04-14)
    expect($service->getNextWorkDay($friday)->toDateString())->toBe('2026-04-11');

    $saturday = Carbon::parse('2026-04-11');
    expect($service->getNextWorkDay($saturday)->toDateString())->toBe('2026-04-14');
});

test('it can sync holidays from API', function () {
    $service = new WorkCalendarService();

    Http::fake([
        'szunetnapok.hu/api/*' => Http::response([
            'response' => 'OK',
            'year' => 2026,
            'days' => [
                [
                    'date' => '2026-01-01',
                    'name' => 'Új Év napja',
                    'type' => 1,
                    'weekday' => 5
                ],
                [
                    'date' => '2026-05-10',
                    'name' => 'Áthelyezett munkanap',
                    'type' => 2,
                    'weekday' => 6
                ]
            ]
        ], 200)
    ]);

    $result = $service->syncFromApi(2026);

    expect($result)->toBeTrue();
    expect(WorkCalendar::count())->toBe(2);

    $holiday = WorkCalendar::where('date', '2026-01-01')->first();
    expect($holiday->type)->toBe(WorkDayType::Holiday);
    expect($holiday->data_source)->toBe(\App\Enums\DataSource::Api);

    $workingDay = WorkCalendar::where('date', '2026-05-10')->first();
    expect($workingDay->type)->toBe(WorkDayType::WorkingDay);
    expect($workingDay->data_source)->toBe(\App\Enums\DataSource::Api);
});

test('it handles API errors during sync', function () {
    $service = new WorkCalendarService();

    Http::fake([
        'szunetnapok.hu/api/*' => Http::response([
            'response' => 'Error',
            'message' => 'Nincs API kulcs megadva'
        ], 200)
    ]);

    $result = $service->syncFromApi(2026);

    expect($result)->toBeFalse();
    expect($service->getError()['api'][0])->toBe('Nincs API kulcs megadva');
});

test('it logs API calls and database entries during sync', function () {
    $service = new WorkCalendarService();

    Http::fake([
        'szunetnapok.hu/api/*' => Http::response([
            'response' => 'OK',
            'days' => [
                [
                    'date' => '2026-01-01',
                    'name' => 'Új Év',
                    'type' => 1
                ]
            ]
        ], 200)
    ]);

    $mock = Log::partialMock();
    $mock->shouldReceive('channel')->with('work_calendar')->andReturnSelf();
    $mock->shouldReceive('info')->atLeast()->once();

    $service->syncFromApi(2026);
});

test('it logs cURL/SSL exceptions during sync', function () {
    $service = new WorkCalendarService();

    Http::fake([
        'szunetnapok.hu/api/*' => function () {
            throw new \Exception('cURL error 60: SSL certificate problem');
        }
    ]);

    $mock = Log::partialMock();
    $mock->shouldReceive('channel')->with('work_calendar')->andReturnSelf();
    $mock->shouldReceive('info')->once(); // Start log
    $mock->shouldReceive('error')->once()->withArgs(function ($message, $context) {
        return str_contains($message, 'cURL/SSL') &&
               str_contains($context['message'], 'SSL certificate problem');
    });

    $result = $service->syncFromApi(2026);

    expect($result)->toBeFalse();
    expect($service->getError()['api'][0])->toContain('Hálózati hiba');
});
