<?php

namespace Tests\Feature\Api;

use App\Models\User;
use App\Modules\CRM\Models\Lead;
use App\Modules\Inventory\Models\Product;
use App\Modules\Invoice\Models\Invoice;
use App\Modules\Tenant\Models\Company;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;

class SettingsDrivenBehaviorTest extends TestCase
{
    use RefreshDatabase;

    public function test_invoice_uses_company_prefix_default_tax_and_payment_terms(): void
    {
        [$user, $company] = $this->createCompanyMember(settings: [
            'invoice_prefix' => 'BILL',
            'default_tax_rate' => 10,
            'payment_terms_days' => 15,
        ]);

        Sanctum::actingAs($user);

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->postJson('/api/v1/invoices', [
                'issue_date' => '2026-07-11',
                'items' => [
                    [
                        'description' => 'Consulting',
                        'quantity' => 2,
                        'unit_price' => 1000,
                    ],
                ],
            ])
            ->assertCreated()
            ->assertJsonPath('data.invoice_number', 'BILL-2026-000001')
            ->assertJsonPath('data.due_date', '2026-07-26')
            ->assertJsonPath('data.tax_total', '200.00')
            ->assertJsonPath('data.total', '2200.00');
    }

    public function test_pos_and_purchase_use_company_prefix_and_default_tax(): void
    {
        [$user, $company] = $this->createCompanyMember(settings: [
            'pos_prefix' => 'SALE',
            'purchase_prefix' => 'BUY',
            'default_tax_rate' => 5,
        ]);
        $product = Product::query()->create([
            'company_id' => $company->id,
            'name' => 'Rice 5kg',
            'selling_price' => 100,
            'current_stock' => 10,
        ]);

        Sanctum::actingAs($user);

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->postJson('/api/v1/pos/sales', [
                'sale_date' => '2026-07-11',
                'items' => [
                    [
                        'product_id' => $product->id,
                        'quantity' => 2,
                    ],
                ],
            ])
            ->assertCreated()
            ->assertJsonPath('data.sale_number', 'SALE-2026-000001')
            ->assertJsonPath('data.tax_total', '10.00')
            ->assertJsonPath('data.total', '210.00');

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->postJson('/api/v1/inventory/purchases', [
                'purchase_date' => '2026-07-11',
                'items' => [
                    [
                        'product_id' => $product->id,
                        'quantity' => 3,
                        'unit_cost' => 80,
                    ],
                ],
            ])
            ->assertCreated()
            ->assertJsonPath('data.purchase_number', 'BUY-2026-000001');
    }

    public function test_notification_alerts_respect_company_alert_toggles(): void
    {
        [$user, $company] = $this->createCompanyMember(settings: [
            'low_stock_alerts' => false,
            'invoice_due_alerts' => true,
            'crm_follow_up_alerts' => false,
        ]);

        Product::query()->create([
            'company_id' => $company->id,
            'name' => 'Rice 5kg',
            'current_stock' => 4,
            'low_stock_threshold' => 5,
        ]);
        Invoice::query()->create([
            'company_id' => $company->id,
            'invoice_number' => 'INV-2026-000001',
            'issue_date' => '2026-07-01',
            'due_date' => '2026-07-10',
            'subtotal' => 1000,
            'total' => 1000,
            'paid_total' => 0,
            'due_total' => 1000,
            'status' => 'sent',
        ]);
        Lead::query()->create([
            'company_id' => $company->id,
            'name' => 'Rahim Uddin',
            'next_follow_up_at' => now()->toDateString(),
            'status' => 'open',
        ]);

        Sanctum::actingAs($user);

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->getJson('/api/v1/notifications')
            ->assertOk()
            ->assertJsonPath('data.summary.active_alerts', 1)
            ->assertJsonPath('data.alerts.0.category', 'invoice');
    }

    /**
     * @param array<string, mixed> $settings
     * @return array{0: User, 1: Company}
     */
    private function createCompanyMember(
        string $companyName = 'ABC Grocery',
        string $slug = 'abc-grocery',
        array $settings = []
    ): array {
        $user = User::factory()->create();
        $company = Company::query()->create([
            'name' => $companyName,
            'slug' => $slug,
            'status' => 'active',
            'settings' => $settings,
        ]);

        $company->users()->attach($user->id, [
            'role' => 'owner',
            'joined_at' => now(),
        ]);
        $this->attachActiveSubscription($company, ['invoice', 'pos', 'inventory', 'notification']);

        return [$user, $company];
    }
}
