<?php
namespace App\Services;

use App\Models\Outlet;
use App\Models\Tenant;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;

class AuthService
{
    public function login(array $data, string $ip)
    {
        $identifier = $data['identifier'];
        $businessCode = $data['business_code'] ?? null;
        $throttleKey = Str::lower($identifier) . '|' . $ip;

        if (RateLimiter::tooManyAttempts($throttleKey, 6)) {
            $seconds = RateLimiter::availableIn($throttleKey);
            return [
                'error' => 'lockout',
                'seconds' => $seconds,
                'until' => now()->addSeconds($seconds)->toIso8601String(),
            ];
        }
        
        $query = User::withoutGlobalScopes();
        
        if ($businessCode) {
            $tenant = Tenant::where('business_code', '=', $businessCode)->first();

            if(!$tenant) {
                return ['error' => 'invalid_business_code'];
            }

            $query->where('tenant_id', '=', $tenant->uuid);
        }

        $loginField = filter_var($identifier, FILTER_VALIDATE_EMAIL) ? 'email' : 'phone_number';
        
        $user = $query->where($loginField, $identifier)->first();

        $storedHash = $user->password;

        if (str_starts_with($storedHash, '$2a$')) {
            $storedHash = str_replace('$2a$', '$2y$', $storedHash);
        }

        if (!$user || !Hash::check($data['password'], $storedHash)) {
            RateLimiter::hit($throttleKey, 3600);
            return ['error' => 'invalid_credentials'];
        }

        if ($user->role === 'owner') {
            $user->load(['tenant.outlets', 'tenant.users']); 
        } else {
            $user->load(['tenant', 'outlet']);
        }

        RateLimiter::clear($throttleKey);
        $user->tokens()->delete(); // logout dari device lain
        
        return [
            'token' => $user->createToken('UserAuthToken')->plainTextToken,
            'user' => $user,
        ];
    }

    public function register(array $data)
    {
        return DB::transaction(function () use ($data) {
            $tenant = Tenant::create([
                'uuid'               => (string) Str::uuid7(),
                'business_name'      => $data['business_name'],
                'business_code'      => $data['business_code'],
                'subscription_level' => 'standart',
            ]);

            $outlet = Outlet::create([
                'uuid'           => (string) Str::uuid7(),
                'tenant_id'      => $tenant->uuid,
                'name'           => $data['business_name'],
                'is_main_outlet' => true,
            ]);

            $user = User::create([
                'uuid'         => (string) Str::uuid7(),
                'tenant_id'    => $tenant->uuid,
                'outlet_id'    => $outlet->uuid,
                'name'         => $data['name'],
                'phone_number' => $data['phone_number'],
                'email'        => $data['email'],
                'password'     => Hash::make($data['password']),
                'role'         => 'owner',
                'is_active'    => true,
                'last_sync'    => Carbon::now()
            ]);

            return [
                'business_code' => $tenant->business_code,
                'user'          => $user,
            ];
        });
    }
}