<?php

namespace Tests\Feature\Api;

use App\Models\Branch;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Tests\TestCase;

abstract class ApiTestCase extends TestCase
{
    use RefreshDatabase;

    protected ?User $user = null;
    protected ?Branch $branch = null;
    protected string $token = '';

    protected function setUp(): void
    {
        parent::setUp();

        // Seed permissions and roles
        $this->seedPermissionsAndRoles();
    }

    protected function seedPermissionsAndRoles(): void
    {
        // Create permissions - matching PermissionSeeder exactly
        $modules = [
            'branches' => ['view', 'create', 'update', 'delete'],
            'users' => ['view', 'create', 'update', 'delete'],
            'roles' => ['view', 'create', 'update', 'delete', 'assign'],
            'permissions' => ['view', 'assign'],
            'categories' => ['view', 'create', 'update', 'delete'],
            'products' => ['view', 'create', 'update', 'delete'],
            'option-sets' => ['view', 'create', 'update', 'delete'],
            'inner-option-sets' => ['view', 'create', 'update', 'delete'],
            'recipes' => ['view', 'create', 'update', 'delete'],
            'ingredients' => ['view', 'create', 'update', 'delete'],
            'stock' => ['view', 'create', 'update', 'adjust'],
            'orders' => ['view', 'create', 'update', 'delete', 'cancel'],
            'customers' => ['view', 'create', 'update', 'delete'],
            'pos' => ['access', 'create-order', 'apply-discount'],
            'expenses' => ['view', 'create', 'update', 'delete'],
            'expense-categories' => ['view', 'create', 'update', 'delete'],
            'cash-flows' => ['view', 'create'],
            'analytics' => ['view-sales', 'view-orders', 'view-expenses', 'view-profitability', 'view-dashboard'],
        ];

        foreach ($modules as $module => $actions) {
            foreach ($actions as $action) {
                Permission::firstOrCreate(
                    ['name' => "{$module}.{$action}", 'guard_name' => 'sanctum']
                );
            }
        }

        // Create Super Admin role with all permissions
        $superAdmin = Role::firstOrCreate(
            ['name' => 'super-admin', 'guard_name' => 'sanctum']
        );
        $superAdmin->syncPermissions(Permission::all());

        // Create other common roles
        Role::firstOrCreate(['name' => 'pos-operator', 'guard_name' => 'sanctum']);
        Role::firstOrCreate(['name' => 'branch-admin', 'guard_name' => 'sanctum']);
        Role::firstOrCreate(['name' => 'manager', 'guard_name' => 'sanctum']);
        Role::firstOrCreate(['name' => 'kitchen-staff', 'guard_name' => 'sanctum']);
    }

    protected function createBranch(array $attributes = []): Branch
    {
        return Branch::create(array_merge([
            'name' => 'Test Branch',
            'code' => 'TB' . uniqid(),
            'address' => '123 Test Street',
            'phone' => '1234567890',
            'email' => 'branch' . uniqid() . '@test.com',
            'is_active' => true,
            'settings' => [
                'stock_restriction_enabled' => true,
                'allow_negative_stock' => false,
            ],
        ], $attributes));
    }

    protected function createUser(array $attributes = [], ?Branch $branch = null): User
    {
        $branch = $branch ?? $this->branch ?? $this->createBranch();

        return User::create(array_merge([
            'name' => 'Test User',
            'email' => 'test' . uniqid() . '@example.com',
            'password' => bcrypt('password123'),
            'branch_id' => $branch->id,
        ], $attributes));
    }

    protected function createAuthenticatedUser(array $attributes = [], ?Branch $branch = null): User
    {
        $this->branch = $branch ?? $this->createBranch();
        $this->user = $this->createUser($attributes, $this->branch);
        $this->user->assignRole('super-admin');

        $this->token = $this->user->createToken('test-token')->plainTextToken;

        // Set the authenticated user for subsequent requests
        $this->actingAs($this->user, 'sanctum');

        return $this->user;
    }

    protected function apiHeaders(): array
    {
        return [
            'Accept' => 'application/json',
            'Content-Type' => 'application/json',
        ];
    }

    protected function authHeaders(): array
    {
        return array_merge($this->apiHeaders(), [
            'Authorization' => 'Bearer ' . $this->token,
        ]);
    }

    protected function assertSuccessResponse($response, int $status = 200, bool $expectData = true): void
    {
        $response->assertStatus($status);
        if ($expectData) {
            $response->assertJsonStructure(['success', 'message', 'data']);
        } else {
            $response->assertJsonStructure(['success', 'message']);
        }
        $response->assertJson(['success' => true]);
    }

    protected function assertErrorResponse($response, int $status = 400): void
    {
        $response->assertStatus($status);
        $response->assertJson(['success' => false]);
    }
}
