<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules;
use Illuminate\Validation\ValidationException;
use App\Models\User;
use App\Mail\ResetPasswordOtpMail;
use App\Services\SmsService;
use Carbon\Carbon;
use Inertia\Inertia;
use Inertia\Response;

class NewPasswordController extends Controller
{
    public function create(Request $request): Response
    {
        if (!$request->email) {
            return redirect()->route('password.request');
        }

        return Inertia::render('Auth/ResetPassword', [
            'email' => $request->email,
            'channel' => $request->channel ?? 'email',
            'status' => session('status'),
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $request->validate([
            'email' => 'required|email|exists:users,email',
            'otp' => 'required|numeric|digits:6',
            'password' => ['required', 'confirmed', Rules\Password::defaults()],
        ]);

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

        if (!$record || !Hash::check($request->otp, $record->token)) {
            throw ValidationException::withMessages(['otp' => __('The OTP code provided is invalid or incorrect.')]);
        }

        if (Carbon::parse($record->created_at)->addMinutes(15)->isPast()) {
            DB::table('password_reset_tokens')->where('email', $request->email)->delete();
            throw ValidationException::withMessages(['otp' => __('The OTP code has expired. Please request a new one.')]);
        }

        $user = User::where('email', $request->email)->first();
        
        $user->forceFill([
            'password' => Hash::make($request->password),
            'remember_token' => Str::random(60),
        ])->save();

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

        return redirect()->route('login')->with('status', __('Your password has been reset successfully. You can now log in.'));
    }

    public function resendOtp(Request $request, SmsService $smsService): RedirectResponse
    {
        $request->validate([
            'email' => 'required|email|exists:users,email',
            'channel' => 'required|in:email,sms'
        ]);

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

        // Anti-Spam Check: Ensure they wait at least 1 minute before requesting another OTP
        $existing = DB::table('password_reset_tokens')->where('email', $user->email)->first();
        if ($existing && Carbon::parse($existing->created_at)->addMinute()->isFuture()) {
            return back()->withErrors(['otp' => __('Please wait a minute before requesting another OTP.')]);
        }

        // Generate & Store New OTP
        $otp = sprintf("%06d", mt_rand(100000, 999999));
        DB::table('password_reset_tokens')->updateOrInsert(
            ['email' => $user->email],
            ['token' => Hash::make($otp), 'created_at' => now()]
        );

        // Send OTP
        try {
            if ($channel === 'email') {
                Mail::to($user->email)->send(new ResetPasswordOtpMail($user, $otp));
            } else {
                $smsMessage = __('Your password reset OTP is: :otp. Do not share this. - :app', ['otp' => $otp, 'app' => config('app.name')]);
                $smsService->send($user->phone, $smsMessage);
            }
        } catch (\Exception $e) {
            return back()->withErrors(['otp' => __('Failed to resend OTP. Error: :error', ['error' => $e->getMessage()])]);
        }

        return back()->with('status', __('A new OTP has been sent to your :channel.', ['channel' => $channel === 'email' ? 'email' : 'phone number']));
    }
}