<?php

namespace App\Http\Controllers\Web;

use App\City;
use App\Contact;
use App\Country;
use App\Helpers\ImageHelper;
use App\Http\Controllers\Controller;
use App\Http\Requests\ContactUsRequest;
use App\Http\Requests\LoginRequest;
use App\Http\Requests\NewsletterRequest;
use App\Http\Requests\RegisterRequest;
use App\Http\Requests\UserEditProfileRequest;
use App\Jobs\VerifyEmail;
use App\Newsletter;
use App\Providers\RouteServiceProvider;
use App\User;
use App\Verification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;

class UserController extends Controller
{

    protected $view = 'web.users.';

    /**
     * Display a listing of the resource.
     *
     * @param User $user
     * @return void
     */
    public function index()
    {
        $title = __('users.profile');
        $user = Auth::user();
        $countries = Country::cursor();
        $cities = City::cursor();
        $courses = $user->courses ? $user->courses : [];

        return view($this->view.'profile', compact('title', 'user', 'countries', 'cities', 'courses'));
    }


    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
       //
    }


    /**
     * Display the specified resource.
     *
     * @param  \App\User  $user
     * @return \Illuminate\Http\Response
     */
    public function show(User $user)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\User  $user
     * @return \Illuminate\Http\Response
     */
    public function edit(User $user)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param UserEditProfileRequest $request
     * @param User $user
     * @return \Illuminate\Http\Response
     */
    public function update(UserEditProfileRequest $request, User $user)
    {
        if ($request->password != null){
            $request['password'] = bcrypt($request->password);
        } else {
            unset($request['password']);
        }
        $user->update($request->all());
        return back()->withMessage(__('users.save_success'));
    }

    public function updatePaymentInfo(Request $request)
    {
        $this->validate($request, [
            'bank_name' => 'required',
            'card_holder' => 'required',
            'account_number' => 'required',
            'iban' => 'required',
        ], [], [
            'bank_name' => 'Bank name',
            'card_holder' => 'Card owner name',
            'account_number' => 'Account number',
            'iban' => 'INBAN',
        ]);

        $user = Auth::user();
        $user->update($request->all());

        return back()->withMessage(__('users.save_success'));
    }

    public function login()
    {
        $title = __('main.login');
        if (Auth::check()) {
            return redirect(RouteServiceProvider::HOME);
        }
        session()->put(['referer' => url()->previous()]);
        return view($this->view.'login', compact('title'));
    }

    public function doLogin(LoginRequest $loginRequest)
    {
        $credential = $loginRequest->all(['email', 'password']);
        if (Auth::attempt($credential, true)){
            if (Auth::user()->role == 'admin'){
                Auth::logout();
                return back()->withErrors(__('auth.failed'));
            }
            if (session('referer')){
                return redirect(session('referer'));
            }
            return redirect()->route('home');
        }

        return redirect()->route('user.login')->withErrors( __('auth.failed'));
    }

    public function register()
    {
        $title = __('users.register');
        return view($this->view.'register', compact('title'));
    }

    public function doRegister(RegisterRequest $registerRequest)
    {
        $userRequest['password'] = bcrypt($registerRequest->password);
        if ($registerRequest->has('photo')){
            $photo = ImageHelper::upload($registerRequest->photo);
            $registerRequest['photo'] = 'uploads/images/'.$photo;
        }
        User::create($registerRequest->all());
        return redirect()->route('user.login')->withMessage(__('users.register_successfully'));
    }

    public function forgetPassword()
    {
        $title = strip_tags(__('users.forget_password'));
        return view($this->view.'forget_password_form', compact('title'));
    }

    public function generateToken(Request $request)
    {
        $this->validate($request, ['email' => 'required|email|exists:users,email'], [], ['email' => __('users.email')]);
        $user = User::where('email', $request->email)->where('role', 'user')->withTrashed()->first();

        if (!$user){
            return back()->with('error', __('auth.failed'));
        }

        $registerRoute = preg_match('/register/', Route::getCurrentRoute()->uri);

        if ($registerRoute){
            $request->type = 'register';
        } else {
            $request->type = 'password';
        }

        $code = Str::random(8);
        if (count($user->verifications) > 0){
            $user->verifications->first()->delete();
        }

        Verification::create([
            'user_id' => $user->id,
            'type' => $request->type,
            'code' => $code
        ]);

        $data = [
            'user' => $user->name,
            'email' => $user->email,
            'code' => $code,
        ];

        if ($request->type == 'register'){
            $data['title'] = 'Email Verification';
            $data['details'] = 'Verify Email';

        } else {
            $data['title'] = 'Forget password';
            $data['details'] = 'Reset password';
        }

        VerifyEmail::dispatch($data, 'web.users.verification_email');

        return redirect()->route('user.verificationCodeForm');
    }

    public function verificationCodeForm()
    {
        $title = strip_tags(__('users.verification_email_code'));
        return view($this->view.'verification_code_form', compact('title'));
    }

    public function verifyCodeWasSendToEmail(Request $request)
    {
        $this->validate($request, ['code' => 'required|exists:verifications,code'], [] , ['code' => __('users.code')]);
        session()->put(['code'=> $request->code]);
        return redirect()->route('user.newPasswordForm');
    }

    public function newPasswordForm()
    {
        $title = strip_tags(__('users.reset_password'));
        return view($this->view.'new_password_form', compact('title'));
    }

    public function resetPassword(Request $request)
    {
        $this->validate($request, ['password' => 'required|confirmed'], [] ,['password' => __('users.password')]);

        $code = session('code');
        $code = Verification::where('code', $code)->first();

        $user = $code->user()->withTrashed()->first();

        if($user){
            $password = bcrypt($request->password);
            $user->update(['password' => $password]);
            $code->delete();
            session()->forget('code');
            return  redirect()->route('user.login')->with('message', __('users.reset_password_successfully'));

        }
    }

    public function verification($token)
    {
        $code = Verification::where('code', $token)->first();
        if($code){
            $user = $code->user()->withTrashed()->first();
            $user->restore();
            if ($code->type == 'register'){
                Auth::login($user);
                $code->delete();
                return  redirect()->route('user.management');
            } else {
                return redirect()->route('user.newPasswordForm', $token);
            }
        } else {
            return redirect()->route('user.login')->with('error', 'This code invalid');
        }
    }

    public function newsletters(NewsletterRequest $newsletterRequest)
    {
        $email = Newsletter::where('email' , $newsletterRequest->email)->first();
        if ($email){
            return  response()->json(['errors' => '! Email subscribed already']);
        }
        Newsletter::create($newsletterRequest->all());
        return response()->json(['message' => __('newsletters.success')]);
    }

    public function logout()
    {
        Auth::logout();
        session()->forget('referer');
        return redirect()->route('home');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\User  $user
     * @return \Illuminate\Http\Response
     */
    public function destroy(User $user)
    {
        //
    }
}
