<?php

namespace App\Http\Controllers\API\Auth;

use App\Http\Controllers\Controller;
use App\Http\Requests\API\Authentication\ResendCodeRequest;
use App\Http\Requests\API\Authentication\SignUpRequest;
use Illuminate\Http\Request;
use App\Http\Requests\Api\Authentication\SocialLoginRequest;
use Laravel\Socialite\Facades\Socialite;
use App\Http\Requests\API\Authentication\UpdateProfileRequest;
use App\Http\Requests\API\Authentication\VerifyRequest;
use App\Http\Traits\ResponseTrait;
use App\Http\Traits\VerificationTrait;
use App\Models\Client;

class AuthController extends Controller
{
    use VerificationTrait, ResponseTrait;
    public function signup(SignUpRequest $request)
    {
        $client = $request->validated();
        $client = Client::create($client);
        $this->sendVerificationCode($client);
        return $this->response(
            message: __('lang.success'),
            data: $client
        );
    }


    public function login()
    {

        $credentials = request(['phone', 'password']);

        if (!$token = auth('client')->attempt($credentials)) {
            return $this->response(
                status: 'failed',
                message: __('auth.failed'),
                code: 422
            );
        }

        $client = auth('client')->user();
        if ($client->status == '0') {
            auth('client')->logout();
            return $this->response(
                status: 'failed',
                message: __('lang.inactive'),
                code: 422
            );
        }

        if ($client->verified_at == null) {
            $this->sendVerificationCode($client);
            auth('client')->logout();
            return $this->response(
                status: 'failed',
                message: __('lang.not_verified'),
                code: 403
            );
        }

        $data['client'] = $client;
        $data['token'] = $token;
        return $this->response(
            data: $data
        );
    }

    public function profile()
    {
        $client  = auth('client')->user();
        return $this->response(
            data: $client,
        );
    }

    public function updateProfile(UpdateProfileRequest $request)
    {
        auth('client')->user()->update($request->validated());
        return $this->response(
            message: __('lang.updated'),
            data: auth('client')->user(),
        );
    }

    public function updateFCMToken(Request $request)
    {
        $client                        = auth('client')->user();
        $client->update(['fcm_token'   => $request->fcm_token ?? NULL]);
        return $this->response(
            message: __('lang.success'),
            data: $client
        );
    }

    public function logout()
    {
        auth('client')->user()->update(['fcm_token' => null]);
        auth('client')->logout();
        return $this->response(
            message: __('messages.logout'),
        );
    }

    public function socialLogin(SocialLoginRequest $request)
    {
        try {
            $providerUser = Socialite::driver($request->validated()['provider'])
                ->userFromToken($request->validated()['token']);
            // return $providerUser->getName();
            if (!$providerUser) {
                return $this->response(
                    status: 'failed',
                    message: __('auth.failed'),
                    code: 422
                );
            }

            $user = Client::where('email', $providerUser->getEmail())->first();
            if (!$user) {
                $user =  Client::create([
                    'name'      => $providerUser->getName(),
                    'email'     => $providerUser->getEmail(),
                    'status'    => '1',
                    'image'     => $providerUser->getAvatar(),
                    'provider'  => $request->validated()['provider'],
                    'verified_at' => now()
                ]);
            } else {
                if ($user->status == '0') {
                    return $this->response(
                        status: 'failed',
                        message: __('lang.inactive'),
                        code: 422
                    );
                }

                if ($user->verified_at == null) {
                    $this->sendVerificationCode($user);
                    return $this->response(
                        status: 'failed',
                        message: __('lang.not_verified'),
                        code: 403
                    );
                }
            }

            $token = auth('client')->login($user);

            return response()->json(
                data: [
                    'user'  => $user,
                    'token' => $token
                ],
            );
        } catch (\Exception $e) {
            return $this->response(
                status: 'failed',
                message: __('lang.warning'),
                code: 422
            );
        }
    }

    public function deleteAccount()
    {
        Client::find(auth('client')->user()->id)->delete();
        return $this->response(
            message: __('lang.deleted'),
        );
    }

    public function resendCode(ResendCodeRequest $request)
    {
        $client = Client::where('email', $request->email)->whereNull('verified_at')->first();
        if ($client)
            $this->sendVerificationCode($client);

        return $this->response(message: __('lang.success'));
    }

    public function verify(VerifyRequest $request)
    {
        $client = Client::whereNull('verified_at')->where('verification_code', $request->code)->where('verify_expire', '>', now())->first();
        if ($client) {
            $client->update([
                'verified_at' => now(),
                'verification_code' => null,
                'verify_expire' => null
            ]);

            $token = auth('client')->login($client);
            $data['client'] = $client;
            $data['token'] = $token;

            return $this->response(message: __('lang.success'), data: $data);
        } else {
            return $this->response(message: __('lang.invalid_code'), code: 422, status: "failed");
        }
    }
}
