<?php

namespace Tests\Feature;

use App\Models\Category;
use App\Models\Transaction;
use App\Models\User;
use App\Services\TransactionFlushService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon;
use Tests\TestCase;

class TransactionFlushServiceTest extends TestCase
{
    use RefreshDatabase;

    public function test_except_current_month_flush_keeps_current_month_transactions(): void
    {
        Carbon::setTestNow('2026-03-08 12:00:00');
        [$user, $category] = $this->seedBase();

        Transaction::query()->create([
            'user_id' => $user->id,
            'category_id' => $category->id,
            'internal_reference' => 'FLUSH-CUR-001',
            'amount_charged' => 200,
            'vendor_cost' => 180,
            'profit' => 20,
            'status' => 'success',
            'created_at' => Carbon::parse('2026-03-04 10:00:00'),
            'updated_at' => Carbon::parse('2026-03-04 10:00:00'),
        ]);

        Transaction::query()->create([
            'user_id' => $user->id,
            'category_id' => $category->id,
            'internal_reference' => 'FLUSH-OLD-001',
            'amount_charged' => 300,
            'vendor_cost' => 250,
            'profit' => 50,
            'status' => 'success',
            'created_at' => Carbon::parse('2026-02-10 10:00:00'),
            'updated_at' => Carbon::parse('2026-02-10 10:00:00'),
        ]);

        Transaction::query()->create([
            'user_id' => $user->id,
            'category_id' => $category->id,
            'internal_reference' => 'FLUSH-OLD-002',
            'amount_charged' => 150,
            'vendor_cost' => 140,
            'profit' => 10,
            'status' => 'failed',
            'created_at' => Carbon::parse('2025-12-31 23:00:00'),
            'updated_at' => Carbon::parse('2025-12-31 23:00:00'),
        ]);

        /** @var TransactionFlushService $service */
        $service = $this->app->make(TransactionFlushService::class);

        $preview = $service->preview([
            'flush_mode' => 'except_current_month',
        ]);

        $this->assertSame(2, (int) ($preview['total_transactions'] ?? 0));

        $result = $service->flush([
            'flush_mode' => 'except_current_month',
        ]);

        $this->assertSame(2, (int) ($result['deleted_transactions'] ?? 0));
        $this->assertSame(1, Transaction::query()->count());
        $this->assertDatabaseHas('transactions', [
            'internal_reference' => 'FLUSH-CUR-001',
        ]);

        Carbon::setTestNow();
    }

    public function test_date_range_flush_deletes_only_transactions_inside_range(): void
    {
        Carbon::setTestNow('2026-03-08 12:00:00');
        [$user, $category] = $this->seedBase();

        Transaction::query()->create([
            'user_id' => $user->id,
            'category_id' => $category->id,
            'internal_reference' => 'RANGE-KEEP-001',
            'amount_charged' => 100,
            'vendor_cost' => 90,
            'profit' => 10,
            'status' => 'success',
            'created_at' => Carbon::parse('2026-01-10 10:00:00'),
            'updated_at' => Carbon::parse('2026-01-10 10:00:00'),
        ]);

        Transaction::query()->create([
            'user_id' => $user->id,
            'category_id' => $category->id,
            'internal_reference' => 'RANGE-DELETE-001',
            'amount_charged' => 220,
            'vendor_cost' => 200,
            'profit' => 20,
            'status' => 'success',
            'created_at' => Carbon::parse('2026-02-18 10:00:00'),
            'updated_at' => Carbon::parse('2026-02-18 10:00:00'),
        ]);

        Transaction::query()->create([
            'user_id' => $user->id,
            'category_id' => $category->id,
            'internal_reference' => 'RANGE-KEEP-002',
            'amount_charged' => 330,
            'vendor_cost' => 280,
            'profit' => 50,
            'status' => 'pending',
            'created_at' => Carbon::parse('2026-03-07 10:00:00'),
            'updated_at' => Carbon::parse('2026-03-07 10:00:00'),
        ]);

        /** @var TransactionFlushService $service */
        $service = $this->app->make(TransactionFlushService::class);

        $result = $service->flush([
            'flush_mode' => 'date_range',
            'flush_start_date' => '2026-02-01',
            'flush_end_date' => '2026-02-28',
        ]);

        $this->assertSame(1, (int) ($result['deleted_transactions'] ?? 0));
        $this->assertSame(2, Transaction::query()->count());
        $this->assertDatabaseMissing('transactions', [
            'internal_reference' => 'RANGE-DELETE-001',
        ]);
        $this->assertDatabaseHas('transactions', [
            'internal_reference' => 'RANGE-KEEP-001',
        ]);
        $this->assertDatabaseHas('transactions', [
            'internal_reference' => 'RANGE-KEEP-002',
        ]);

        Carbon::setTestNow();
    }

    /**
     * @return array{0:User,1:Category}
     */
    protected function seedBase(): array
    {
        $user = User::factory()->create();
        $category = Category::query()->create([
            'name' => 'Data SME',
            'slug' => 'data_sme',
        ]);

        return [$user, $category];
    }
}
