<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\MobileVerification;
use App\Models\User;
use App\Services\PayamMatni;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class OtpLoginController extends Controller
{
    public function __construct()
    {
        $this->middleware('guest');
    }

    public function showMobileForm()
    {
        return view('auth.otp-login');
    }

    public function sendCode(Request $request)
    {
        $request->validate([
            'mobile' => ['required', 'string', 'regex:/^09[0-9]{9}$/'],
        ], [
            'mobile.required' => 'شماره موبایل الزامی است.',
            'mobile.regex'    => 'شماره موبایل باید با ۰۹ شروع شده و ۱۱ رقم باشد.',
        ]);

        $mobile = $request->mobile;

        if (!User::where('mobile', $mobile)->exists()) {
            return back()->withErrors(['mobile' => 'این شماره موبایل در سیستم ثبت نشده است.'])->withInput();
        }

        $now          = now();
        $verification = MobileVerification::where('mobile', $mobile)->first();

        if ($verification) {
            if ($verification->last_sent_at && ($now->timestamp - $verification->last_sent_at->timestamp) < 90) {
                $cooldown = 90 - ($now->timestamp - $verification->last_sent_at->timestamp);
                return redirect()->route('otp.verify.form')->with('otp_mobile', $mobile)
                    ->withErrors(['resend' => "۱ دقیقه و نیم صبر کنید ({$cooldown} ثانیه باقی مانده)."]);
            }

            $windowStart = $verification->first_sent_at;
            if ($windowStart && $now->diffInMinutes($windowStart) < 60 && $verification->sent_count >= 5) {
                return redirect()->route('otp.verify.form')->with('otp_mobile', $mobile)
                    ->withErrors(['resend' => 'حداکثر ۵ بار در ساعت می‌توانید کد دریافت کنید.']);
            }

            if (!$windowStart || $now->diffInMinutes($windowStart) >= 60) {
                $verification->first_sent_at = $now;
                $verification->sent_count    = 0;
            }
        } else {
            $verification = new MobileVerification(['mobile' => $mobile, 'sent_count' => 0, 'first_sent_at' => $now]);
        }

        $code = str_pad(random_int(10000, 99999), 5, '0', STR_PAD_LEFT);

        $verification->code         = $code;
        $verification->expires_at   = $now->addMinutes(5);
        $verification->last_sent_at = $now;
        $verification->sent_count   += 1;
        $verification->save();

        PayamMatni::sendOtp($mobile, $code);

        return redirect()->route('otp.verify.form')->with('otp_mobile', $mobile);
    }

    public function showCodeForm(Request $request)
    {
        $mobile = session('otp_mobile');

        if (!$mobile) {
            return redirect()->route('otp.login');
        }

        $verification = MobileVerification::where('mobile', $mobile)->first();
        $lastSentAt   = $verification?->last_sent_at;
        $sentCount    = $verification?->sent_count ?? 0;
        $firstSentAt  = $verification?->first_sent_at;

        $cooldown = 0;
        if ($lastSentAt) {
            $elapsed  = max(0, now()->timestamp - $lastSentAt->timestamp);
            $cooldown = max(0, 90 - $elapsed);
        }

        $hourlyUsed = 0;
        if ($firstSentAt && now()->diffInMinutes($firstSentAt) < 60) {
            $hourlyUsed = $sentCount;
        }

        return view('auth.otp-verify-login', compact('mobile', 'cooldown', 'hourlyUsed'));
    }

    public function verifyCode(Request $request)
    {
        $request->validate(['code' => 'required|digits:5']);

        $mobile = session('otp_mobile');

        if (!$mobile) {
            return redirect()->route('otp.login');
        }

        $verification = MobileVerification::where('mobile', $mobile)->first();

        if (!$verification || now()->isAfter($verification->expires_at)) {
            return back()->withErrors(['code' => 'کد تأیید منقضی شده است. لطفاً کد جدیدی درخواست دهید.']);
        }

        if ($request->code !== $verification->code) {
            return back()->withErrors(['code' => 'کد وارد شده اشتباه است.']);
        }

        $user = User::where('mobile', $mobile)->first();
        $verification->delete();

        $request->session()->forget('otp_mobile');

        Auth::login($user, true);

        return redirect('/');
    }

    public function resend(Request $request)
    {
        $mobile = session('otp_mobile');

        if (!$mobile) {
            return redirect()->route('otp.login');
        }

        $now          = now();
        $verification = MobileVerification::where('mobile', $mobile)->first();

        if ($verification) {
            if ($verification->last_sent_at && ($now->timestamp - $verification->last_sent_at->timestamp) < 90) {
                return back()->withErrors(['resend' => '۱ دقیقه و نیم صبر کنید.']);
            }

            $windowStart = $verification->first_sent_at;
            if ($windowStart && $now->diffInMinutes($windowStart) < 60 && $verification->sent_count >= 5) {
                return back()->withErrors(['resend' => 'حداکثر ۵ بار در ساعت می‌توانید کد دریافت کنید.']);
            }

            if (!$windowStart || $now->diffInMinutes($windowStart) >= 60) {
                $verification->first_sent_at = $now;
                $verification->sent_count    = 0;
            }
        } else {
            $verification = new MobileVerification(['mobile' => $mobile, 'sent_count' => 0, 'first_sent_at' => $now]);
        }

        $code = str_pad(random_int(10000, 99999), 5, '0', STR_PAD_LEFT);

        $verification->code         = $code;
        $verification->expires_at   = $now->addMinutes(5);
        $verification->last_sent_at = $now;
        $verification->sent_count   += 1;
        $verification->save();

        PayamMatni::sendOtp($mobile, $code);

        return back()->with(['resent' => true, 'otp_mobile' => $mobile]);
    }
}
