<?php
namespace App\Http\Controllers;
use App\Models\{User,OtpChallenge,SmsTemplate};
use App\Services\SmsGateway;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\{Auth,Hash,RateLimiter,DB};
use Illuminate\Validation\ValidationException;
class AuthController {
 private function mobile(Request $r):string {$m=mobile_normalize($r->input('mobile',''));if(!preg_match('/^09\d{9}$/',$m))throw ValidationException::withMessages(['mobile'=>'شماره همراه را درست وارد کنید.']);return $m;}
 public function login(Request $r){$m=$this->mobile($r);$key='login:'.hash('sha256',$m.'|'.$r->ip());if(RateLimiter::tooManyAttempts($key,5))throw ValidationException::withMessages(['mobile'=>'کمی صبر کنید و دوباره تلاش کنید.']);RateLimiter::hit($key,300);
  if(!Auth::attempt(['mobile'=>$m,'password'=>$r->input('password'),'active'=>true]))throw ValidationException::withMessages(['mobile'=>'شماره یا رمز درست نیست، یا حساب هنوز تأیید نشده است.']);
  if(!Auth::user()->verified_at){Auth::logout();throw ValidationException::withMessages(['mobile'=>'ابتدا شماره همراه را با کد ورود تأیید کنید.']);}
  RateLimiter::clear($key);$r->session()->regenerate();return redirect()->intended('/');
 }
 public function register(Request $r){$m=$this->mobile($r);$v=$r->validate(['name'=>'required|string|max:100','password'=>'required|min:12|confirmed','kind'=>'required|in:customer,staff']);if(User::where('mobile',$m)->exists())throw ValidationException::withMessages(['mobile'=>'این شماره قبلاً عضو شده است. از بخش ورود استفاده کنید.']);
  $r->session()->put('registration',['name'=>$v['name'],'mobile'=>$m,'password'=>Hash::make($v['password']),'role'=>$v['kind']==='staff'?'mentor':'customer','active'=>$v['kind']!=='staff']);return $this->sendOtp($r);
 }
 public function sendOtp(Request $r){$m=$this->mobile($r);$key='otp:'.$m;$ip='otp-ip:'.$r->ip();if(RateLimiter::tooManyAttempts($key,1)||RateLimiter::tooManyAttempts($ip,10))throw ValidationException::withMessages(['mobile'=>'برای درخواست کد جدید کمی صبر کنید.']);RateLimiter::hit($key,60);RateLimiter::hit($ip,3600);$code=(string)random_int(100000,999999);
  OtpChallenge::updateOrCreate(['mobile'=>$m],['code_hash'=>Hash::make($code),'attempts'=>0,'consumed_at'=>null,'expires_at'=>now()->addSeconds(config('club.otp_ttl'))]);
  try{app(SmsGateway::class)->send(SmsTemplate::where('event','otp')->firstOrFail(),$m,['otp'=>$code,'minutes'=>'۳']);}catch(\Throwable $e){throw ValidationException::withMessages(['mobile'=>'ارسال کد ممکن نشد؛ لطفاً از رمز ثابت استفاده کنید یا با پشتیبانی ارتباط بگیرید.']);}
  $r->session()->put('otp_mobile',$m);return redirect('/verify')->with('success','کد برای شما ارسال شد. خوشحالیم که همراه مایید.');
 }
 public function verify(Request $r){$code=en_num($r->input('code',''));$mobile=$r->session()->get('otp_mobile');abort_unless($mobile,422);
  $ok=DB::transaction(function()use($mobile,$code){$o=OtpChallenge::where('mobile',$mobile)->lockForUpdate()->first();if(!$o||$o->consumed_at||$o->expires_at->isPast()||$o->attempts>=config('club.otp_attempts'))return false;$o->increment('attempts');if(!Hash::check($code,$o->code_hash))return false;$o->update(['consumed_at'=>now()]);return true;});
  if(!$ok)throw ValidationException::withMessages(['code'=>'کد درست نیست یا اعتبار آن تمام شده است.']);
  $u=User::where('mobile',$mobile)->first();if(!$u){$data=$r->session()->pull('registration');abort_unless($data&&$data['mobile']===$mobile,422,'ابتدا ثبت‌نام کنید.');$u=User::create($data+['verified_at'=>now()]);}else{$u->update(['verified_at'=>now()]);}
  $r->session()->forget('otp_mobile');if(!$u->active)return redirect('/login')->with('success','شماره تأیید شد؛ عضویت کاری شما منتظر تأیید مدیر است.');Auth::login($u);$r->session()->regenerate();$r->session()->put('recent_otp',now()->timestamp);return redirect('/');
 }
 public function logout(Request $r){Auth::logout();$r->session()->invalidate();$r->session()->regenerateToken();return redirect('/login');}
}
