<?php
namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\UserModel;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
use Tymon\JWTAuth\Facades\JWTAuth;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'username'     => 'required|string|max:255|unique:tbl_user',
            'password'     => 'required|string|min:8',
            'nama_lengkap' => 'required|string|max:255',
            'email'        => 'required|string|email|max:255|unique:tbl_user',
            'no_hp'        => 'nullable|string',
            'level_id'     => 'required|integer|exists:tbl_user_level,id',
            'status'       => 'required|boolean',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        $user = UserModel::create([
            'username'     => $request->username,
            'password'     => Hash::make($request->password),
            'nama_lengkap' => $request->nama_lengkap,
            'email'        => $request->email,
            'no_hp'        => $request->no_hp,
            'level_id'     => $request->level_id,
            'status'       => $request->status,
        ]);

        $token         = JWTAuth::fromUser($user);
        $refresh_token = $this->createRefreshToken();

        return response()->json(compact('user', 'token', 'refresh_token'), 201);
    }

    public function login(Request $request)
    {
        $credentials = $request->only('username', 'password');

        // Cari berdasarkan username atau nip
        $user = UserModel::where(function ($query) use ($credentials) {
            $query->where('username', $credentials['username'])
                ->orWhere('nip', $credentials['username']);
        })->first();

        if (! $user) {
            return response()->json(['error' => 'Username/NIP tidak ditemukan'], 400);
        }

        if ('N' === $user->status) {
            return response()->json(['error' => 'Akun tidak aktif. Silakan hubungi administrator.'], 400);
        }

        if (! Hash::check($credentials['password'], $user->password)) {
            return response()->json(['error' => 'Password salah'], 400);
        }

        // Sesuaikan payload untuk JWTAuth agar bisa pakai username/nip
        $payload = [
            'username' => $user->username,
            'password' => $credentials['password'],
        ];

        try {
            if (! $token = JWTAuth::attempt($payload)) {
                return response()->json(['error' => 'invalid_credentials'], 400);
            }
        } catch (JWTException $e) {
            return response()->json(['error' => 'could_not_create_token'], 500);
        }

        $user = auth()->user()->load(['userLevel', 'office']);

        // Update last_login ke waktu saat ini
        $user->last_login = Carbon::now('Asia/Jakarta');
        $user->save();

        $refresh_token = $this->createRefreshToken();

        return response()->json(compact('token', 'refresh_token', 'user'));
    }

    public function getUser()
    {
        try {
            if (! $user = JWTAuth::parseToken()->authenticate()) {
                return response()->json(['user_not_found'], 404);
            }

            $user->load('role');
        } catch (TokenExpiredException $e) {
            Log::error('Token expired', ['exception' => $e]);
            return response()->json(['token_expired'], 401);
        } catch (TokenInvalidException $e) {
            Log::error('Token invalid', ['exception' => $e]);
            return response()->json(['token_invalid'], 401);
        } catch (JWTException $e) {
            Log::error('Token absent', ['exception' => $e]);
            return response()->json(['token_absent'], 500);
        }

        return response()->json(compact('user'));
    }

    public function logout(Request $request)
    {
        try {
            $token = JWTAuth::getToken();
            if (! $token) {
                return response()->json(['error' => 'Token not provided'], 400);
            }

            if (! JWTAuth::check()) {
                return response()->json(['error' => 'Token is invalid'], 400);
            }

            JWTAuth::invalidate($token);
            return response()->json(['message' => 'User successfully logged out.']);
        } catch (JWTException $e) {
            Log::error('Logout error', ['exception' => $e->getMessage()]);
            return response()->json(['error' => 'Could not log out the user.', 'details' => $e->getMessage()], 500);
        }
    }

    public function refreshToken(Request $request)
    {
        try {
            $refreshToken = $request->input('refresh_token');
            if (! $refreshToken) {
                return response()->json(['error' => 'Refresh token not provided'], 400);
            }

            $token = JWTAuth::refresh(JWTAuth::getToken());
            return $this->respondWithToken($token);
        } catch (JWTException $e) {
            return response()->json(['error' => $e->getMessage()], 401);
        }
    }

    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token'  => $token,
            'token_type'    => 'bearer',
            'expires_in'    => config('jwt.ttl') * 60 * 60 * 24,
            'refresh_token' => $this->createRefreshToken(),
        ]);
    }

    protected function createRefreshToken()
    {
        return Str::random(224);
    }
}