<?php

namespace Modules\Client\Http\Controllers;

use App\Functions\ResponseHelper;
use App\Functions\Upload;
use App\Http\Controllers\BasicController;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Modules\Client\Entities\Model as Client;
use Modules\Client\Http\Requests\CheckExistsRequest;
use Modules\Client\Http\Requests\DeviceTokenRequest;
use Modules\Client\Http\Requests\RegisterRequest;
use Modules\Client\Http\Requests\UpdateProfileRequest;
use Modules\Client\Http\Resources\ClientResource;
use Modules\Country\Entities\Country;

class APIController extends BasicController
{
    public function Login(Request $request)
    {
        $rules = [
            'phone' => [Rule::requiredIf(function () {
                return request('email') == null;
            })],
            'phone_code' => [Rule::requiredIf(function () {
                return request('phone');
            })],
            'email' => [Rule::requiredIf(function () {
                return request('phone') == null;
            })],
            'password' => ['required'],
            'device_token' => ['nullable'],
        ];
        $messages = [
            'phone.required' => __('validation.required', ['attribute' => __('fields.phone')]),
            'email.required' => __('validation.required', ['attribute' => __('fields.email')]),
            'password.required' => __('validation.required', ['attribute' => __('fields.password')]),
            'password.min' => __('validation.min.string', ['attribute' => __('fields.password'), 'min' => 8]),
            'password_confirmation.same' => __('validation.same', ['attribute' => __('fields.password_confirmation'), 'other' => __('fields.password')]),
        ];
        $validator = \Validator::make($request->all(), $rules, $messages);
        if ($validator->fails()) {
            return response()->json([
                'statusCode' => 403,
                'msg' => $validator->errors()->first(),
            ], 403);
        }
        $phone_code = str_replace('+', '', $request->phone_code);
        if ($client = Auth('client')->attempt($request->only('phone', 'password') + ['phone_code' => $phone_code, 'deleted_at' => null, 'status' => 1])) {
            $Model = Auth('client')->user();
        } else {
            return ResponseHelper::make(null, __('trans.emailPasswordIncorrect'), false, 404);
        }
        if (! $Model->DeviceTokens()->where(['device_token' => $request->device_token])->exists()) {
            $Model->DeviceTokens()->create([
                'device_token' => $request->device_token,
            ]);
        }
        $response['token'] = $Model->createToken('ClientToken')->plainTextToken;
        $response['client'] = ClientResource::make($Model);

        return ResponseHelper::make($response, __('trans.loginSuccessfully'));
    }

    public function Register(RegisterRequest $request)
    {
        $phone_code = str_contains($request->phone_code, '+') ? $request->phone_code : '+'.$request->phone_code;
        $rules = [
            'name' => 'required|string|max:255',
            // 'email' => 'nullable|email|max:255',
            'phone' => [
                'required',
                Rule::unique('clients')->where(function ($query) use ($phone_code, $request) {
                    return $query->where('phone', $request->phone)
                        ->where('phone_code', $phone_code)
                        ->whereNull('deleted_at');
                }),
            ],
            'password' => 'required|string|min:6',
            // 'password_confirmation' => 'required|string|same:password',
            'phone_code' => 'required|string',
            'device_token' => 'nullable|string',
        ];
        $messages = [
            'name.required' => __('validation.required', ['attribute' => __('fields.name')]),
            'phone_code.required' => __('validation.required', ['attribute' => __('fields.phone_code')]),
            'password.required' => __('validation.required', ['attribute' => __('fields.password')]),
            'password.min' => __('validation.min.string', ['attribute' => __('fields.password'), 'min' => 8]),
            // 'password_confirmation.same' => __('validation.same', ['attribute' => __('fields.password_confirmation'), 'other' => __('fields.password')]),
        ];
        $validator = \Validator::make($request->all(), $rules, $messages);
        if ($validator->fails()) {
            return response()->json([
                'statusCode' => 403,
                'msg' => $validator->errors()->first(),
            ], 403);
        }
        $phone_code = str_replace('+', '', $request->phone_code);
        $Country = Country::where('phone_code', 'LIKE', "%{$phone_code}%")->first();

        $Model = Client::where('phone', $request->phone)->where('phone_code', $phone_code)->withTrashed()->first();
        if ($Model) {
            $Model->name = $request->name;
            $Model->email = $request->email;
            $Model->password = bcrypt($request['password']);
            $Model->status = 1;
            $Model->deleted_at = null;
            $Model->save();
            $Model = Client::where('phone', $request->phone)->where('phone_code', $phone_code)->first();
        } else {
            $Model = Client::create([
                'name' => $request->name,
                'email' => $request->email,
                'phone' => $request->phone,
                'password' => bcrypt($request['password']),
                'phone_code' => $phone_code,
                'country_code' => $Country->country_code,
                'country_id' => $Country->id,
                'status' => 1,
            ]);

            if (setting('loyalty_enabled')) {
                $Model->LoyaltyPoints()->create([
                    'points' => (int) setting('loyalty_register_points'),
                    'source' => 'register',
                ]);
            }
        }

        if (! $Model->DeviceTokens()->where(['device_token' => $request->device_token])->exists()) {
            $Model->DeviceTokens()->create([
                'device_token' => $request->device_token,
            ]);
        }
        $success['token'] = $Model->createToken('ClientToken')->plainTextToken;
        $success['client'] = ClientResource::make($Model);

        return ResponseHelper::make($success, __('trans.addedSuccessfully'));
    }

    public function DeviceToken(DeviceTokenRequest $request)
    {
        $this->CheckAuth();
        if (! $this->Client->DeviceTokens()->where(['device_token' => $request->device_token])->exists()) {
            $this->Client->DeviceTokens()->create([
                'device_token' => $request->device_token,
            ]);
        }
        $response['token'] = request()->bearerToken();
        $response['client'] = ClientResource::make($this->Client);

        return ResponseHelper::make($response, __('trans.addedSuccessfully'));
    }

    public function profile($lang, $id = null)
    {
        if ($id) {
            $Model = Client::where('id', $id)->firstorfail();
            $response['client'] = ClientResource::make($Model);
        } else {
            $this->CheckAuth();
            $response['token'] = request()->bearerToken();
            $response['client'] = ClientResource::make($this->Client->refresh());
        }

        return ResponseHelper::make($response);

    }

    public function UpdateProfile(UpdateProfileRequest $request)
    {
        $this->CheckAuth();
        $Model = $this->Client;
        if (count($request->except(['image', 'device_token']))) {
            $Model->update($request->except(['image', 'device_token', 'del_photo']));
        }
        if ($request->image) {
            $Model->update(['image' => Upload::UploadFile($request->image, 'Clients')]);
        }
        if ($request->password) {
            $Model->update(['password' => bcrypt($request->password)]);
        }

        if ($request->del_photo && $request->del_photo == 'true') {
            $Model->update(['image' => '']);
        }

        $response['token'] = request()->bearerToken();
        $response['client'] = ClientResource::make($Model->refresh());

        return ResponseHelper::make($response, __('trans.updatedSuccessfully'));

    }

    public function UpdateOldPassword(Request $request)
    {
        $this->CheckAuth();
        $user = auth('sanctum')->user();
        if (! \Hash::check($request->old_password, $user->password)) {
            return response()->json([
                'statusCode' => 403,
                'msg' => __('trans.incorrect_old_password'),
            ], 403);
        }
        $rules = [
            'old_password' => 'required',
            'password' => 'required|min:6',
            'password_confirmation' => 'required|same:password',
        ];
        $messages = [
            'old_password.required' => __('validation.required', ['attribute' => __('fields.password')]),
            'password.min' => __('validation.min.string', ['attribute' => __('fields.password'), 'min' => 8]),
            'password_confirmation.same' => __('validation.same', ['attribute' => __('fields.password_confirmation'), 'other' => __('fields.password')]),
        ];
        $validator = \Validator::make($request->all(), $rules, $messages);
        if ($validator->fails()) {
            return response()->json([
                'statusCode' => 403,
                'msg' => $validator->errors()->first(),
            ], 403);
        }

        if ($request->password == $request->old_password) {
            return response()->json([
                'statusCode' => 403,
                'msg' => __('trans.same'),
            ], 403);
        }

        $this->Client->password = bcrypt(request('password'));
        $this->Client->save();
        $response['token'] = request()->bearerToken();
        $response['client'] = ClientResource::make($this->Client);

        return ResponseHelper::make($response, __('trans.updatedSuccessfully'));

    }

    public function UpdatePassword(Request $request)
    {
        $phone_code = str_replace('+', '', $request->phone_code);
        $Model = Client::where('phone', $request->phone)->where('phone_code', $phone_code)->firstorfail();
        if ($request->password) {
            $Model->password = bcrypt($request['password']);
            $Model->save();
        }

        $response['token'] = request()->bearerToken();
        $response['client'] = ClientResource::make($Model);

        return ResponseHelper::make($response, __('trans.updatedSuccessfully'));

    }

    public function UpdateImage(Request $request)
    {
        $this->CheckAuth();
        $Model = $this->Client;
        if (request('image')) {
            $Model->update(['image' => Upload::UploadFile(request('image'), 'Clients')]);
        }

        $response['token'] = request()->bearerToken();
        $response['client'] = ClientResource::make($Model->refresh());

        return ResponseHelper::make($response, __('trans.addedSuccessfully'));

    }

    public function CheckNumber(CheckExistsRequest $request)
    {
        $phone_code = str_replace('+', '', $request->phone_code);
        if ($request->phone) {
            $Model = Client::where('phone', $request->phone)->where('phone_code', $phone_code)->first();
        } elseif ($request->email) {
            $Model = Client::where('email', $request->email)->first();
        }
        $response['exist'] = $Model ? 1 : 0;
        $response['token'] = $Model ? $Model->createToken('ClientToken')->plainTextToken : null;
        $response['client'] = $Model ? ClientResource::make($Model) : null;

        return ResponseHelper::make($response, $Model ? __('trans.already_exist') : __('trans.dont_exist'));
    }

    public function Logout()
    {
        $this->CheckAuth();
        $this->Client->DeviceTokens()->where('device_token', request()->device_token)->delete();
        $this->Client->tokens()->where('token', request()->bearerToken())->delete();

        return ResponseHelper::make(null, __('trans.logoutSuccessfully'));
    }

    public function lang($lang)
    {
        $this->CheckAuth();
        $this->Client->lang = $lang;
        $this->Client->save();

        return ResponseHelper::make(null, __('trans.addedSuccessfully'));
    }

    public function DeleteAccount()
    {
        if (request()->client_id) {
            $Client = Client::where('id', request()->client_id)->first();
            if ($Client) {
                $Client->DeviceTokens()->where('device_token', request()->device_token)->delete();
                $Client->tokens()->delete();
                $Client->delete();
            }
        } else {
            $this->CheckAuth();
            $this->Client->DeviceTokens()->where('device_token', request()->device_token)->delete();
            $this->Client->tokens()->delete();
            $this->Client->delete();
        }

        return ResponseHelper::make(null, __('trans.DeletedSuccessfully'));
    }
}
