<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\PhoneDoLoginRequest;
use App\Http\Requests\Auth\PhoneLoginRequest;
use App\Http\Requests\User\ProfileUpdateRequest;
use App\Models\Token;
use App\Models\User;
use App\Notifications\Login;
use App\Services\Auth\AuthProcessService;
use Carbon\Carbon;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Inertia\Inertia;
use Inertia\Response;

class PhoneLoginController extends Controller
{
    /**
     * Show Login Form
     */
    public function show(Request $request): Response
    {
        return Inertia::render('Auth/Login', [
            'prev' => $request->prev
        ])->title(__('messages.title.login'));
    }

    /**
     * Process Login
     */
    public function process(PhoneLoginRequest $request, AuthProcessService $authProcessService): RedirectResponse
    {
        // find user
        $user = User::where('phone', $request->validated('phone'))->first();

        // check read-only owner
        if ($user != null && $user->phone == "09999999999" && $user->username == "#demo") {
            auth()->loginUsingId($user->id);
            return redirect()->route('admin.dashboard');
        }

        // register user if not exist
        if ($user == null)
            $user = $authProcessService->registerUser($request);

        // process authentication token
        $token = $authProcessService->createToken($request, $user);

        if ($token == 'to_verify')
            return redirect()->route('login.verify', ['phone' => $request->validated('phone'), 'prev' => $request->prev]);

        if ($authProcessService->sendToken($token, $user))
            return redirect()->route('login.verify', ['phone' => $request->validated('phone'), 'prev' => $request->prev]);

        return redirect()->back()->withErrors(['codeError' => __('messages.unknown_error')]);
    }

    /**
     * Verify Authentication Code
     */
    public function verify(PhoneLoginRequest $request, AuthProcessService $authProcessService): Response | RedirectResponse
    {
        // find user
        $user = User::where('phone', $request->validated('phone'))->first();
        if ($user === null)
            return redirect()->route('login');

        // check for exist valid token
        $token = $authProcessService->currentToken($request, $user);
        // redirect to login page if no exist valid token
        if ($token == null)
            return redirect()->route('login');

        return Inertia::render('Auth/Verify', [
            "phone" => $request->phone,
            "remaining" => Carbon::parse($token->created_at)->timestamp + Token::EXPIRATION_TIME,
            "prev" => $request->prev,
        ])->title(__('messages.title.verify_login'));
    }

    /**
     * do login
     */
    public function login(PhoneDoLoginRequest $request, AuthProcessService $authProcessService): Response | RedirectResponse | \Illuminate\Http\Response
    {
        // find user
        $user = User::where('phone', $request->validated('phone'))->first();
        if ($user === null)
            return redirect()->route('login');

        // do login
        $loginStatus = $authProcessService->loginUser($request, $user);

        if ($loginStatus) {
            // notify user login
            $user->notify(new Login());

            if ($user->name === null || $user->name === "")
                return redirect()->route('login.account.information', ['prev' => $request->prev]);

            if ($request->prev != null)
                return redirect($request->prev);

            if ($user->type == "owner" || $user->type == "admin")
                return Inertia::location(route('admin.dashboard'));

            return redirect()->route('index');
        } else {
            return redirect()->back()->withErrors(['codeError' => __('messages.auth_code_wrong')]);
        }
    }

    /**
     * user account information component
     */
    public function accountInformation(Request $request): Response | RedirectResponse
    {
        // auth user
        $user = auth()->user();

        if ($user->name != null || $user->name != "")
            return redirect()->route('index');

        return Inertia::render('Auth/AccountInformation', [
            "name" => $user->name,
            "email" => $user->email,
            "username" => $user->username,
            "prev" => $request->prev,
        ])->title(__('messages.title.complete_account_infromation'));
    }

    /**
     * update user account information
     */
    public function accountInformationUpdate(ProfileUpdateRequest $request): Response | RedirectResponse | \Illuminate\Http\Response
    {
        /**
         * auth user
         * @var App\Models\User $user
         */
        $user = auth()->user();

        // update user profile
        $user->update([
            'name' => $request->validated('name'),
            'email' => $request->exists('email') && $request->email != null ? $request->validated('email') : $user->email,
            'username' => $request->exists('username') && $request->username != null ? $request->validated('username') : $user->username,
        ]);

        if ($request->prev != null)
            return redirect($request->prev);

        if ($user->type == "owner" || $user->type == "admin")
            return Inertia::location(route('admin.dashboard'));

        return Inertia::location(route('index'));
    }

    /**
     * logout
     */
    public function logout(Request $request, AuthProcessService $authProcessService): RedirectResponse | \Illuminate\Http\Response
    {
        // do logout
        Auth::logout();

        // invalidate token and session
        $authProcessService->invalidateCurrentToken($request);

        return Inertia::location(route('index'));
    }
}
