<?php

namespace Tests\Feature;

use App\Models\MessageTemplate;
use App\Models\Setting;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Hash;
use Tests\Feature\Concerns\BuildsFeatureData;
use Tests\TestCase;

class AdminTemplatesSettingsAndMessagingFeatureTest extends TestCase
{
    use BuildsFeatureData;
    use DatabaseTransactions;

    private function loginAsAdmin(?string $plainPassword = null): \App\Models\User
    {
        $password = $plainPassword ? Hash::make($plainPassword) : Hash::make('password123');
        $admin = $this->createAdminUser([
            'password' => $password,
        ]);

        $this->actingAs($admin);

        return $admin;
    }

    public function test_admin_can_view_update_and_reset_message_template(): void
    {
        $this->loginAsAdmin();

        $template = MessageTemplate::where('type', 'applied')->first();
        if (!$template) {
            $template = $this->createMessageTemplate([
                'type' => 'applied',
                'label' => 'Lamaran Diterima',
            ]);
        }

        $this->get(route('admin.message-templates.index'))->assertOk();
        $this->get(route('admin.message-templates.edit', $template))->assertOk();

        $updateResponse = $this->put(route('admin.message-templates.update', $template), [
            'email_subject' => 'Subjek Template Uji',
            'email_body' => 'Isi email template uji',
            'wa_body' => 'Isi wa template uji',
        ]);

        $updateResponse->assertRedirect(route('admin.message-templates.index'));

        $template->refresh();
        $this->assertSame('Subjek Template Uji', $template->email_subject);

        $resetResponse = $this->post(route('admin.message-templates.reset', $template));
        $resetResponse->assertRedirect(route('admin.message-templates.index'));

        $template->refresh();
        $this->assertNotSame('Subjek Template Uji', $template->email_subject);
    }

    public function test_admin_can_view_and_update_settings(): void
    {
        $this->loginAsAdmin();

        $this->get(route('admin.settings'))->assertOk();

        $response = $this->post(route('admin.settings.update'), [
            'site_name' => 'Bursa Kerja Test',
            'site_description' => 'Platform lowongan kerja untuk pengujian.',
            'countdown_seconds' => '8',
            'stage_advance_days' => '3',
            'final_auto_decision' => 'rejected',
            'auto_advance' => '1',
        ]);

        $response->assertStatus(302);
        $this->assertSame('Bursa Kerja Test', Setting::get('site_name'));
        $this->assertSame('3', Setting::get('stage_advance_days'));
        $this->assertSame('1', Setting::get('auto_advance'));
    }

    public function test_admin_can_change_password_and_is_logged_out_afterward(): void
    {
        $admin = $this->loginAsAdmin('old-password-123');

        $response = $this->post(route('admin.settings.change-password'), [
            'current_password' => 'old-password-123',
            'new_password' => 'new-password-123',
            'new_password_confirmation' => 'new-password-123',
        ]);

        $response->assertRedirect(route('admin.login'));
        $this->assertGuest();

        $admin->refresh();
        $this->assertTrue(Hash::check('new-password-123', $admin->password));
    }

    public function test_admin_send_message_endpoints_return_json_responses(): void
    {
        $this->loginAsAdmin();

        $this->get(route('admin.send-message.index'))->assertOk();

        $emailResponse = $this->postJson(route('admin.send-message.email'), [
            'email' => 'target@example.com',
            'subject' => 'Subjek Uji',
            'message' => 'Isi pesan uji',
        ]);
        $emailResponse->assertOk()->assertJsonStructure(['success', 'message']);

        $waResponse = $this->postJson(route('admin.send-message.whatsapp'), [
            'phone' => '081234567890',
            'message' => 'Pesan WA uji',
        ]);
        $waResponse->assertOk()->assertJsonStructure(['success', 'message']);

        $smtpResponse = $this->postJson(route('admin.send-message.test-smtp'));
        $smtpResponse->assertOk()->assertJsonStructure(['success', 'message']);

        $fonnteResponse = $this->postJson(route('admin.send-message.test-fonnte'));
        $fonnteResponse->assertOk()->assertJsonStructure(['success', 'message']);
    }

    public function test_admin_broadcast_routes_return_expected_json(): void
    {
        $this->loginAsAdmin();

        $this->createApplicant(['email' => 'broadcast.one@example.com']);
        $this->createApplicant(['email' => 'broadcast.two@example.com']);

        $emailBroadcastResponse = $this->postJson(route('admin.send-message.broadcast-email'), [
            'subject' => 'Info {site_name}',
            'message' => 'Halo {applicant_name}',
        ]);
        $emailBroadcastResponse->assertOk()->assertJsonStructure(['success', 'message']);

        $waBroadcastResponse = $this->postJson(route('admin.send-message.broadcast-whatsapp'), [
            'message' => 'Pesan broadcast WA',
        ]);
        $waBroadcastResponse->assertOk()->assertJsonStructure(['success', 'message']);
    }

    public function test_legacy_test_notification_routes_are_accessible(): void
    {
        $this->loginAsAdmin();

        $this->get(route('admin.test.index'))->assertOk();

        $emailResponse = $this->postJson(route('admin.test.email'), [
            'email' => 'legacy@example.com',
            'subject' => 'Legacy Email',
            'message' => 'Isi legacy email',
        ]);
        $emailResponse->assertOk()->assertJsonStructure(['success', 'message']);

        $waResponse = $this->postJson(route('admin.test.whatsapp'), [
            'phone' => '081234567890',
            'message' => 'Isi legacy WA',
        ]);
        $waResponse->assertOk()->assertJsonStructure(['success', 'message']);

        $smtpResponse = $this->postJson(route('admin.test.smtp'));
        $smtpResponse->assertOk()->assertJsonStructure(['success', 'message']);

        $fonnteResponse = $this->postJson(route('admin.test.fonnte'));
        $fonnteResponse->assertOk()->assertJsonStructure(['success', 'message']);
    }
}
