<?php

namespace App\Http\Controllers\User;

use App\Helpers\ValidationHelper;
use App\Http\Controllers\Controller;
use App\Mail\ForgetPasswordMail;
use App\Models\SellTarget;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Mockery\Exception;

class UserController extends Controller
{
    private function validator($request, array $columns): \Illuminate\Validation\Validator
    {
        return Validator::make($request->all(), $columns);
    }

    public function index()
    {
        try {
            return successResponseWithData(User::query()->where(['create_by' => Auth::id()])->orderByDesc('id')->get(), 'successfully', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }
    public function create(Request $request): JsonResponse
    {
        $validator = ValidationHelper::validator($request, [
            'profile' => 'image|extensions:jpg,png,jpeg',
            'name' => 'required',
            'email' => 'required|email|unique:users,email',
            'phone' => 'required|unique:users,phone',
            'password' => 'required|min:8|max:32|confirmed',
            'password_confirmation' => 'required|min:8|max:32',
        ]);
        if ($validator->fails()) {
            return validationErrorResponse($validator);
        }

        try {
            return successResponseWithData(User::newUser($request), 'User create successfully', 201);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    public function change_status($user_id): JsonResponse
    {
        try {

            $response = User::change_status($user_id);

            return successResponse($response['message'], $response['status']);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }

    }

    public function update(Request $request): JsonResponse
    {
        $user = Auth::user();
        $validator = ValidationHelper::validator($request, [
            'name' => 'required',
            'email' => 'required|email|unique:users,email,'.$user->id,
            'phone' => 'required|unique:users,phone,'.$user->id,
        ]);
        if ($validator->fails()) {
            return validationErrorResponse($validator);
        }

        try {
            return successResponseWithData(User::updateUser($request), 'User update successfully', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    public function photo_update(Request $request): JsonResponse
    {
        $validator = ValidationHelper::validator($request, [
            'profile' => 'image|extensions:jpg,png,jpeg',
        ]);
        if ($validator->fails()) {
            return validationErrorResponse($validator);
        }

        try {
            return successResponseWithData(User::photoUpdate($request), 'Photo update successfully', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    public function change_password(Request $request): JsonResponse
    {
        $validator = ValidationHelper::validator($request, [
            'current_password' => 'required',
            'password' => 'required|min:8|max:32|confirmed',
            'password_confirmation' => 'required|min:8|max:32',
        ]);
        if ($validator->fails()) {
            return validationErrorResponse($validator);
        }

        try {
            $user = User::query()->find(Auth::id());
            if (Hash::check($request->current_password, $user->password)) {
                $user->password = Hash::make($request->password);
                $user->save();

                return successResponse('Your password is changed', 200);
            } else {
                return successResponse('Invalid Current Password', 400);
            }

        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    public function forget_password(Request $request): JsonResponse
    {
        $validator = ValidationHelper::validator($request, [
            'email' => 'required|email|exists:users,email',
            'reset_url' => 'required|url',
        ]);
        if ($validator->fails()) {
            return validationErrorResponse($validator);
        }

        try {
            $token = Str::random(60);

            DB::table('password_reset_tokens')->insert([
                'email' => $request->email,
                'token' => $token,
                'created_at' => Carbon::now(),
            ]);
            $data = [
                'reset_url' => $request->reset_url,
                'token' => $token,
            ];
            Mail::to($request->email)->send(new ForgetPasswordMail($data));

            return successResponse('Please check your mailbox. We have e-mailed your password reset link!', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    public function update_forget_password(Request $request): JsonResponse
    {
        $validator = ValidationHelper::validator($request, [
            'token' => 'required|exists:password_reset_tokens,token',
            'password' => 'required|min:8|max:32|confirmed',
            'password_confirmation' => 'required|min:8|max:32',
        ]);
        if ($validator->fails()) {
            return validationErrorResponse($validator);
        }

        try {
            $updatePassword = DB::table('password_reset_tokens')
                ->where(['token' => $request->token])
                ->first();

            if (! $updatePassword) {
                return successResponse('Invalid token!', 400);
            }

            User::query()->where('email', $updatePassword->email)
                ->update(['password' => Hash::make($request->password)]);

            DB::table('password_reset_tokens')->where(['email' => $updatePassword->email])->delete();

            return successResponse('Your password has been changed!', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    public static function all_staff(): JsonResponse
    {
        try {
            return successResponseWithData(User::query()->where(['role' => 'staff', 'create_by' => Auth::id()])->orderByDesc('id')->get(), 'successfully', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    public function store_sell_target(Request $request): JsonResponse
    {
        $validator = ValidationHelper::validator($request, [
            'staff_id' => 'required|unique:sell_targets,staff_id',
            'target_type' => 'required',
            'target_amount' => 'required',
        ]);
        if ($validator->fails()) {
            return validationErrorResponse($validator);
        }


        try {
            if (User::query()->find($request->staff_id, ['create_by'])->create_by == Auth::id()) {
                return successResponseWithData(SellTarget::newSellTarget($request), 'Create successfully', 201);
            }

            return successResponse('Invalid staff id', 400);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    public function update_sell_target(Request $request): JsonResponse
    {
        $validator = ValidationHelper::validator($request, [
            'staff_id' => 'required|exists:sell_targets,staff_id',
            'target_type' => 'required',
            'target_amount' => 'required',
        ]);
        if ($validator->fails()) {
            return validationErrorResponse($validator);
        }

        try {
            if (User::query()->find($request->staff_id, ['create_by'])->create_by == Auth::id()) {
                return successResponseWithData(SellTarget::updateSellTarget($request), 'Update successfully', 200);
            }

            return successResponse('Invalid staff id', 400);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }
}
