<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;

class AuthController extends Controller
{
    /**
     * Register a new user
     */
    public function register(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:8|confirmed',
            'phone' => 'nullable|string|max:20',
        ]);

        try {
            $user = null;
            $token = null;
            DB::transaction(function () use ($request, &$user, &$token) {
                $user = User::create([
                    'name' => $request->name,
                    'email' => $request->email,
                    'password' => Hash::make($request->password),
                    'phone' => $request->phone,
                    'is_admin' => false,
                ]);

                // Generate JWT token
                $token = JWTAuth::fromUser($user);
            });

            return response()->json([
                'user' => $user,
                'token' => $token,
            ], 201);
        } catch (\Exception $e) {
            return response()->json([
                'message' => 'Registration failed. Please try again.',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Login user
     */
    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required',
        ]);

        $credentials = $request->only('email', 'password');

        try {
            if (!$token = JWTAuth::attempt($credentials)) {
                throw ValidationException::withMessages([
                    'email' => ['The provided credentials are incorrect.'],
                ]);
            }
        } catch (JWTException $e) {
            throw ValidationException::withMessages([
                'email' => ['Could not create token.'],
            ]);
        }

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

        return response()->json([
            'user' => $user,
            'token' => $token,
        ]);
    }

    /**
     * Logout user
     */
    public function logout(Request $request)
    {
        try {
            JWTAuth::invalidate(JWTAuth::getToken());

            return response()->json([
                'message' => 'Logged out successfully',
            ]);
        } catch (JWTException $e) {
            return response()->json([
                'message' => 'Failed to logout',
            ], 500);
        }
    }

    /**
     * Get authenticated user
     */
    public function user(Request $request)
    {
        return response()->json(auth()->user());
    }

    /**
     * Update user profile
     */
    public function updateProfile(Request $request)
    {
        $request->validate([
            'name' => 'sometimes|required|string|max:255',
            'email' => 'sometimes|required|string|email|max:255|unique:users,email,' . $request->user()->id,
        ]);

        $user = $request->user();

        // Check if email is being changed and enforce 30-day cooldown
        if ($request->has('email') && $request->email !== $user->email) {
            if ($user->email_changed_at) {
                $daysSinceLastChange = now()->diffInDays($user->email_changed_at);
                if ($daysSinceLastChange < 30) {
                    $remainingDays = 30 - $daysSinceLastChange;
                    return response()->json([
                        'message' => "Email can only be changed once every 30 days. You can change it again in {$remainingDays} days.",
                        'remaining_days' => $remainingDays
                    ], 429); // Too Many Requests
                }
            }
            // Update email_changed_at timestamp when email is changed
            $user->email_changed_at = now();
        }

        $user->update($request->only(['name', 'email']));

        return response()->json($user);
    }

    /**
     * Refresh authentication session
     */
    public function refresh(Request $request)
    {
        try {
            $token = JWTAuth::getToken();
            $newToken = JWTAuth::refresh($token);

            return response()->json([
                'user' => $request->user(),
                'token' => $newToken,
            ]);
        } catch (JWTException $e) {
            return response()->json([
                'error' => 'Could not refresh token',
            ], 500);
        }
    }
}
