<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\Cart;
use App\Models\User;
use App\Services\API\SmsService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\RateLimiter;
use Symfony\Component\HttpFoundation\Response;



class AuthController extends Controller
{
    public function resend(Request $request)
    {
        $request->validate([
            'phone' => 'required',
        ]);

        $phone = preg_replace("/[^0-9]/", "", $request->phone);

        // Define the same rate limit key to share attempts between auth and resend
        $rateLimitKey = 'verify_attempts_' . $phone;

        // Set the same maximum attempts and decay time
        $maxAttempts = 5;
        $decayMinutes = 1;

        // Check if the phone number has exceeded the rate limit
        if (RateLimiter::tooManyAttempts($rateLimitKey, $maxAttempts)) {
            $seconds = RateLimiter::availableIn($rateLimitKey);
            return response()->json([
                'message' => 'Too many attempts. Please try again in ' . $seconds . ' seconds.'
            ], 429); // 429 Too Many Requests
        }

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

        if ($user) {
            // send SMS with verify code
            $verify_code = SmsService::send($phone);

            $user->update([
                'verify_code' => $verify_code,
            ]);

            // Increase the attempt count
            RateLimiter::hit($rateLimitKey, $decayMinutes * 60);

            return response()->json(['phone' => $phone]);
        }

        // return can't find user message
        return response()->json(['message' => 'User not found']);
    }

    public function auth(Request $request)
    {
        $phone = preg_replace("/[^0-9]/", "", $request->input('phone'));

        // Define the rate limit key based on the phone number.
        $rateLimitKey = 'verify_attempts_' . $phone;

        // Set the maximum attempts and the decay time (e.g., 5 attempts every 1 minute)
        $maxAttempts = 5;
        $decayMinutes = 1;

        // Check if the phone number has exceeded the rate limit
        if (RateLimiter::tooManyAttempts($rateLimitKey, $maxAttempts)) {
            $seconds = RateLimiter::availableIn($rateLimitKey);
            return response()->json([
                'message' => 'Too many attempts. Please try again in ' . $seconds . ' seconds.'
            ], 429); // 429 Too Many Requests
        }

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

        // send SMS with verify code
        $verify_code = SmsService::send($phone);

        if ($user) {
            $user->update([
                'verify_code' => $verify_code,
            ]);
        } else {
            User::create([
                'phone' => $phone,
                'verify_code' => $verify_code,
            ]);
        }

        // Increase the attempt count
        RateLimiter::hit($rateLimitKey, $decayMinutes * 60);

        return response()->json(['phone' => $phone]);
    }

    public function verify(Request $request)
    {
        $request->validate([
            'phone' => 'required',
            'verify_code' => 'required',
        ]);

        $phone = preg_replace("/[^0-9]/", "", $request->phone);

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

        // check if user exists
        if (!$user) {
            return response()->json([
                'message' => 'User not found'
            ], Response::HTTP_NOT_FOUND);
        }

        // check if verify code is correct
        if ($user->verify_code != $request->verify_code) {
            return response([
                'message' => 'Verify code is incorrect'
            ], Response::HTTP_UNAUTHORIZED);
        }

        $token = $user->createToken('token')->plainTextToken;
        $cookie = cookie('jwt', $token, 60 * 24 * 365, null, null, secure: true, httpOnly: true); // 1 year expiration

        // clear verify code
        $user->update([
            'verify_code' => null,
        ]);

        // Update cart, remove token and add user_id
        $this->updateCart($user);

        return response([
            'data' => [
                'id' => $user->id,
                'phone' => $user->phone,
                'access_token' => $token
            ]
        ])->withCookie($cookie);
    }

    public function logout()
    {
        $cookie = Cookie::forget('jwt');

        // logout
        auth()->user()->tokens()->delete();

        return response([
            'message' => 'Success'
        ])->withCookie($cookie);
    }

    private function getLocalToken()
    {
        return request()->header('X-Application-Token');
    }

    private function updateCart($user)
    {
        if ($this->getLocalToken()) {
            // Update carts, remove token and add user_id
            $carts = Cart::where('token', $this->getLocalToken())->get();
            foreach ($carts as $cart) {
                $cart->update([
                    'token' => null,
                    'user_id' => $user->id,
                ]);
            }
        }
    }
}
