<?php

declare(strict_types=1);

namespace Tests\Feature;

use App\Models\User;
use App\Models\Market\Store;
use App\Models\Market\PosSession;
use App\Enums\UserTypes;
use App\Enums\UserActions;
use Tests\TestCase;
use Hypervel\Support\Facades\Auth;
use Hypervel\Foundation\Testing\RefreshDatabase;
use Hyperf\Stringable\Str;

class PosAccessTest extends TestCase
{
    use RefreshDatabase;

    protected function createUser(UserTypes $type, User $parent = null)
    {
        return User::create([
            'name' => 'Test ' . $type->value,
            'fullname' => 'Test User ' . $type->value,
            'username' => 'test_' . str_replace(' ', '_', $type->value) . '_' . Str::random(5),
            'mobile_number' => '09' . mt_rand(100000000, 999999999),
            'email' => Str::random(10) . '@example.com',
            'password' => password_hash('123123', PASSWORD_DEFAULT),
            'acct_type' => $type,
            'parentuid' => $parent ? $parent->id : null,
            'hashkey' => Str::random(100),
            'active' => true,
        ]);
    }

    protected function createStore(User $owner, User $manager = null)
    {
        return Store::create([
            'name' => 'Test Store ' . Str::random(5),
            'owner_id' => $owner->id,
            'manager_id' => $manager ? $manager->id : $owner->id,
            'hashkey' => Str::random(100),
            'is_active' => true,
            'status' => 'active',
        ]);
    }

    public function test_pos_access_hierarchy()
    {
        // 1. Setup Hierarchy
        $owner = $this->createUser(UserTypes::STORE_OWNER);
        $store = $this->createStore($owner);
        
        $manager = $this->createUser(UserTypes::STORE_MANAGER, $owner);
        $store->manager_id = $manager->id;
        $store->save();

        $terminal = $this->createUser(UserTypes::POS_TERMINAL, $manager);

        // Another store hierarchy
        $otherOwner = $this->createUser(UserTypes::STORE_OWNER);
        $otherStore = $this->createStore($otherOwner);

        // 2. Test Authorized Access
        
        // Owner access
        Auth::login($owner);
        $response = $this->post('/api/pos/start', ['store_hash' => $store->hashkey]);
        $response->assertStatus(200);

        // Manager access
        Auth::login($manager);
        $response = $this->post('/api/pos/start', ['store_hash' => $store->hashkey]);
        $response->assertStatus(200);

        // Terminal access (child of manager)
        Auth::login($terminal);
        $response = $this->post('/api/pos/start', ['store_hash' => $store->hashkey]);
        $response->assertStatus(200);

        // 3. Test Unauthorized Access
        
        // Terminal accessing another store
        $response = $this->post('/api/pos/start', ['store_hash' => $otherStore->hashkey]);
        $response->assertStatus(403);
        $this->assertEquals('You are not authorized to start a POS session for this store.', $response->json('message'));

        // Manager accessing another store
        Auth::login($manager);
        $response = $this->post('/api/pos/start', ['store_hash' => $otherStore->hashkey]);
        $response->assertStatus(403);

        // 4. Test Other Endpoints
        Auth::login($terminal);
        
        // getPosSessions
        $response = $this->post('/api/pos/sessions/list', ['store_hash' => $store->hashkey]);
        $response->assertStatus(200);

        $response = $this->post('/api/pos/sessions/list', ['store_hash' => $otherStore->hashkey]);
        $response->assertStatus(403);

        // getTodayStats
        $response = $this->post('/api/pos/stats', ['store_hash' => $store->hashkey]);
        $response->assertStatus(200);

        $response = $this->post('/api/pos/stats', ['store_hash' => $otherStore->hashkey]);
        $response->assertStatus(403);

        // getCustomers
        $response = $this->post('/api/pos/get-customers', ['store_hash' => $store->hashkey]);
        $response->assertStatus(200);

        $response = $this->post('/api/pos/get-customers', ['store_hash' => $otherStore->hashkey]);
        $response->assertStatus(403);
    }
}
