<?php
namespace App\Http\Controllers;

use App\Mail\PasswordResetMessage;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use App\Models\Subscription;
use Illuminate\Support\Facades\Hash;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Laravel\Socialite\Facades\Socialite;
use Illuminate\Support\Str;

class AuthController extends Controller
{
    // Validaciones del login
    public function signin(Request $request) {

        if (empty($request->email) || empty($request->password)) {
            return back()->withErrors(['error' => 'All fields are required'])->withInput();
        }
 
        $request->validate([
            'email' => 'required',
            'password' => 'required',
        ]);

        $campoLogin = filter_var($request->email, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
        
        if (Auth::attempt([$campoLogin => $request->email, 'password' => $request->password])) {
            $user = Auth::user();

            // dd($user->role->name);

            $routes = [
                'Admin' => 'crudUsuarios',
                'Teacher' => 'teacher.dashboard', // TODO: Integración de rol profesor
                'Student' => 'homePage',
                'Revisor' => 'revisorPage' // TODO: Integración de rol revisor
            ];

            if ($user->status === 'active' && isset($routes[$user->role->name])) {
                return redirect()->route($routes[$user->role->name]);
            }
        }
    
        return back()->withErrors(['error' => 'Incorrect credentials'])->withInput();
    }

    // Validaciones del register
    public function signup(Request $request) {

        $errors = [];
    
        if (empty($request->name)) {
            $errors['name'] = 'Name is required';
        } elseif (!preg_match('/^[a-zA-Z]+$/', $request->name)) {
            $errors['name'] = 'Name must contain letters only, without spaces';
        }

        if (empty($request->surname)) {
            $errors['surname'] = 'Surname is required';
        } elseif (!preg_match('/^[a-zA-Z\s]+$/', $request->surname)) {
            $errors['surname'] = 'Surname must contain letters only';
        }

        if (empty($request->username)) {
            $errors['username'] = 'Username is required';
        } elseif (!preg_match('/^[a-zA-Z0-9]+$/', $request->username)) {
            $errors['username'] = 'Username must contain letters and numbers only, without spaces';
        }

        if (empty($request->email)) {
            $errors['email'] = 'Email is required';
        } elseif (!filter_var($request->email, FILTER_VALIDATE_EMAIL)) {
            $errors['email'] = 'Email is not valid';
        }

        if (empty($request->password)) {
            $errors['password'] = 'Password is required';
        } elseif (strlen($request->password) < 8) {
            $errors['password'] = 'Password must have at least 8 characters';
        }

        if (empty($request->password_confirmation)) {
            $errors['password_confirmation'] = 'Repeat password is required';
        } elseif ($request->password !== $request->password_confirmation) {
            $errors['password_confirmation'] = 'Passwords do not match';
        }
        
        if (User::where('username', $request->username)->exists()) {
            $errors['username'] = 'Username already exists';
        }
        
        if (User::where('email', $request->email)->exists()) {
            $errors['email'] = 'Email is already in use';
        }
    
        if (!empty($errors)) {
            return redirect()->route('registerPage')->withInput()->withErrors($errors);
        }

        $now = Carbon::now();

        // NORMALIZAR NOMBRE
        $name = $request->name;
        if (strtoupper($name) === $name || strtolower($name) === $name) {
            $name = ucwords(strtolower($name));
        }

        // NORMALIZAR APELLIDOS
        $surname = $request->surname;
        if (strtoupper($surname) === $surname || strtolower($surname) === $surname) {
            // Poner cada palabra con primera mayúscula
            $surname = ucwords(strtolower($surname));
        }

        // CREAR USUARIO
        $user = User::create([
            'name' => $name,
            'surname' => $surname,
            'username' => $request->username,
            'email' => $request->email,
            'password' => Hash::make($request->password),
            'coins' => 0,
            'status' => 'active',
            'completed_courses' => 0,
            'role_id' => 3,
            'created_at' => $now,
            'updated_at' => $now,
        ]);

        Subscription::create([
            'user_id' => $user->id,
            'subscription_product_id' => 1,
            'price_paid' => 0,
            'subscription_date' => null,
            'receipt_id' => null,
            'created_at' => $now,
            'updated_at' => $now,
        ]);
    
        Auth::login($user);
    
        if ($user->role_id == 3) {
            return redirect()->route('homePage');
        }
    }

    public function send_reset_password_mail(Request $request) {

        $errors = [];

        if (empty($request->email)) {
            $errors['email'] = 'Email is required';
        } elseif (!filter_var($request->email, FILTER_VALIDATE_EMAIL)) {
            $errors['email'] = 'Email is not valid';
        } elseif (!User::where('email', $request->email)->exists()) {
            $errors['email'] = 'Email is not registered';
        }
    
        if (!empty($errors)) {
            return redirect()->route('resetPasswordForm')->withInput()->withErrors($errors);
        }

        $user = User::where('email', $request->email)->first();
        $token = Str::random(64);

        $userEmail = $user->email;
        $userName = $user->name;

        // Guardar el token (puedes actualizar si ya existe)
        DB::table('password_reset_tokens')->updateOrInsert(
            ['email' => $userEmail],
            ['token' => $token, 'created_at' => Carbon::now()]
        );

        Mail::to($userEmail)->send(new PasswordResetMessage($userEmail, $userName, $token));

        return redirect()->route('resetPasswordForm')->with('success', 'A password reset link has been sent to your email');
        
    }

    public function showResetForm($token) {

        $resetToken = DB::table('password_reset_tokens')->where('token', $token)->first();

        if (!$resetToken) {
            // Token inválido
            return redirect()->route('login')->withErrors(['token' => 'Invalid or expired token']);
        }

        // Opcional: comprobar si el token expiró (por ejemplo, después de 60 minutos)
        $tokenCreatedAt = Carbon::parse($resetToken->created_at);
        if ($tokenCreatedAt->addMinutes(60)->isPast()) {
            return redirect()->route('login');
        }

        // Si es válido, mostrar la vista
        return view('pages.auth.resetPasswordForm', ['token' => $token]);
    }

    public function submitNewPassword(Request $request) {

        $errors = [];

        if (empty($request->password)) {
            $errors['password'] = 'Password is required';
        } elseif (strlen($request->password) < 8) {
            $errors['password'] = 'Password must have at least 8 characters';
        }

        if (empty($request->password_confirmation)) {
            $errors['password_confirmation'] = 'Repeat password is required';
        } elseif ($request->password !== $request->password_confirmation) {
            $errors['password_confirmation'] = 'Passwords do not match';
        }

        if (!empty($errors)) {
            return back()->withInput()->withErrors($errors);
        }

        $request->validate([
            'token' => 'required',
            'password' => 'required|confirmed|min:8'
        ]);

        $tokenData = DB::table('password_reset_tokens')->where('token', $request->token)->first();

        if (!$tokenData) {
            return redirect()->route('login');
        }

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

        $user->password = Hash::make($request->password);
        $user->save();

        DB::table('password_reset_tokens')->where('email', $user->email)->delete();

        return redirect()->route('login');

    }


    // Función para cerrar sesión y redirigir al login
    public function logout(Request $request)
    {
        Auth::logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();
    
        return redirect()->route('login');
    }

    public function google_signup() {

        $user = Socialite::driver('google')->user();

        $userExists = User::where('external_id', $user->id)->where('external_auth', 'google')->first();

        $emailExists = User::where('email', $user->email)->exists();

        if ($userExists) {

            Auth::login($userExists);

        } elseif ($emailExists) {

            Auth::login($emailExists);

        } else {

            $now = Carbon::now();
  
            $username = Str::slug($user->name, '_');

            $surname = $user->user['family_name'] ?? $user->given_name;

            $userNew = User::create([
                'name' => $user->user['given_name'],
                'surname' => $surname,
                'username' => $username,
                'email' => $user->email,
                'coins' => 0,
                'status' => 'active',
                'completed_courses' => 0,
                'role_id' => 3,
                'external_id' => $user->id,
                'external_auth' => 'google',
                'created_at' => $now,
                'updated_at' => $now,
            ]);

            Subscription::create([
                'user_id' => $userNew->id,
                'subscription_product_id' => 1,
                'price_paid' => 0,
                'subscription_date' => null,
                'receipt_id' => null,
                'created_at' => $now,
                'updated_at' => $now,
            ]);

            Auth::login($userNew);

        }

        return redirect()->route('homePage');
        
    }
    
}