<?php

namespace App\Http\Controllers\Api\v2;

use App\Components\Functions;
use App\Events\AuthLoginLog;
use App\Jobs\CreateDelayNotificationPhone;
use App\Jobs\RemindCreateRoom;
use App\Jobs\RemindRenterSearchHostel;
use App\Jobs\SendMailWhenNewOwner;
use App\Listeners\AuthLogoutLog;
use App\Models\CouponTransaction;
use App\Models\Hostel;
use App\Models\HostelImage;
use App\Models\HostelPostCrawl;
use App\Models\LeadUserTake;
use App\Models\Notification;
use App\Models\Package;
use App\Models\Token;
use App\Models\UserPackage;
use App\Models_v2\Bookmark;
use App\Models_v2\FindSession;
use App\Notifications\RemindOwnerSearchHostel;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenBlacklistedException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Facades\JWTAuth;

class AccountController extends BaseController
{
    //
    /**
     * @api {post} v2/account/login-with-phone Đăng nhập bằng SĐT
     * @apiName /login-with-phone
     * @apiGroup Account
     * @apiParam {String} phone
     * @apiParam {String=1,2,6} type 1 là chủ trọ, 2 là người thuê, 6 là nhân viên
     * @apiParam {String} token
     * @apiParam {String} country_phone_code
     * @apiParam {String="IOS,ANDROID"} token_type Loại token
     *
     * @apiDescription Api Đăng nhập bằng SĐT
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function loginWithPhone(Request $request)
    {
        $phone = $request->input('phone');
        $type = $request->input('type');
        $tokenDevice = $request->input('token');
        $tokenType = $request->input('token_type');
        $countryPhoneCode = $request->input('country_phone_code');


        if (empty($phone)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống SĐT'
            ]);
        }

        if (empty($type)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống loại người dùng'
            ]);
        }

        $user = User::query()
            ->where('phone', $phone)
            ->when(!empty($countryPhoneCode), function ($q) use ($countryPhoneCode) {
                $q->where('country_phone_code', $countryPhoneCode);
            })
            ->where('type', $type)
            ->first();

        if (!$user) {
            return response([
                'status' => 0,
                'message' => 'Thông tin đăng nhập không hợp lệ'
            ]);
        }

        $token = \Tymon\JWTAuth\Facades\JWTAuth::fromUser($user);

        if (!empty($tokenDevice) && !empty($tokenType)) {
            Token::query()
                ->where('type', $tokenType)
                ->where('token', $tokenDevice)
                ->delete();

            Token::create([
                'user_id' => $user->id,
                'type' => $tokenType,
                'token' => $tokenDevice,
            ]);
        }

        event(new AuthLoginLog($user));

        $numberInteracts = $user->number_interacts;
        $balance = $user->balance;
        $owner = $this->user;
        if ($user->type == User::STAFF) {
            $owner = $user->owner;
            $numberInteracts = optional($owner)->number_interacts;
            $balance = optional($owner)->balance;
        }
        $packageFindHostel = Functions::getPackageFindHostel($user);
        $userRefer = $user->refer;
        $referArr = null;
        if ($userRefer) {
            $referArr = [
                'id' => $userRefer->id,
                'name' => $userRefer->name_text,
                'phone' => $userRefer->phone,
                'image' => $userRefer->image,
                'email' => $userRefer->email,
            ];
        }

        if (empty($user->aff_link)) {
            $user->aff_link = Functions::generateDynamicLinkAff($user);
            $user->save();
        }

        return response([
            'status' => 1,
            'message' => 'Đăng nhập thành công',
            'data' => [
                'user' => [
                    'id' => $user->id,
                    'name' => $user->name_text,
                    'phone' => $user->phone,
                    'email' => $user->email,
                    'avatar' => $user->image,
                    'gender' => $user->gender,
                    'type' => $user->type,
                    'balance' => $balance,
                    'number_interacts' => $numberInteracts,
                    'package_find_hostel' => $packageFindHostel,
                    'country_phone_code' => $user->country_phone_code,
                    'refer_code' => $user->refer_code,
                    'user_refer' => $referArr,
                    'aff_link' => $user->aff_link
                ],
                'token' => $token
            ]
        ]);
    }

    /**
     * @api {get} v2/account/current-account-list Lấy danh sách tk bằng SĐT
     * @apiName /current-account-list
     * @apiGroup Account
     * @apiParam {String} phone
     * @apiParam {String} facebook_id
     * @apiParam {String} zalo_id
     * @apiParam {String} apple_id
     *
     * @apiDescription Api Lấy danh sách tk bằng SĐT
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getCurrentAccountList(Request $request)
    {
        $phone = $request->input('phone');
        $zaloId = $request->input('zalo_id');
        $facebookId = $request->input('facebook_id');
        $appleId = $request->input('apple_id');
        $countryPhoneCode = $request->input('country_phone_code');

        if (empty($phone) && empty($zaloId) && empty($facebookId) && empty($appleId)) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }
        $accounts = User::query()
            ->when(!empty($phone), function ($q) use ($phone) {
                $q->where('phone', $phone);
            })
            ->when(!empty($countryPhoneCode), function ($q) use ($countryPhoneCode) {

                $q->where(function ($q) use ($countryPhoneCode) {
                    $q->orWhere('country_phone_code', $countryPhoneCode);
                    $q->orWhere('country_phone_code', '+' . $countryPhoneCode);
                });
            })
            ->when(!empty($zaloId), function ($q) use ($zaloId) {
                $q->where('zalo_id', $zaloId);
            })
            ->when(!empty($facebookId), function ($q) use ($facebookId) {
                $q->where('facebook_id', $facebookId);
            })
            ->when(!empty($appleId), function ($q) use ($appleId) {
                $q->where('apple_id', $appleId);
            })
            ->whereIn('type', [
                User::OWNER,
                User::STAFF,
                User::RENTER
            ])
            ->get()
            ->map(function ($account) {
                return [
                    'id' => $account->id,
                    'type' => $account->type,
                    'name' => $account->name_text,
                    'avatar' => $account->image,
                    'phone' => $account->phone,
                    'country_phone_code' => $account->country_phone_code
                ];
            });

        return response([
            'status' => 1,
            'data' => $accounts
        ]);

    }

    /**
     * @api {post} v2/account/register Đăng ký tài khoản
     * @apiName /register
     * @apiGroup Account
     * @apiParam {String} [email]
     * @apiParam {String} phone
     * @apiParam {String} password
     * @apiParam {String} [country_phone_code]
     * @apiParam {String} [facebook_id]
     * @apiParam {String} [zalo_id]
     *  * @apiParam {String} [apple_id]
     * @apiParam {String} type
     * @apiParam {String} name
     * @apiParam {String} [gender]
     * @apiParam {String} [birthday] Dạng d/m/Y
     * @apiParam {File} [avatar]
     *
     *
     * @apiDescription Api đăng ký tài khoản
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function register(Request $request)
    {
        $email = $request->input('email');
        $phone = $request->input('phone');
        $type = $request->input('type');
        $name = $request->input('name');
        $gender = $request->input('gender');
        $birthday = $request->input('birthday');
        $image = $request->file('avatar');
        $countryPhoneCode = $request->input('country_phone_code');
        $facebookId = $request->input('facebook_id');
        $zaloId = $request->input('zalo_id');
        $appleId = $request->input('apple_id');
        $tokenDevice = $request->input('token');
        $tokenType = $request->input('token_type');
        $from = $request->input('from', 0);
        $branchApp = $request->input('branch_app', User::BRANCH_FIND);
        $referCode = $request->input('refer_code');
        $password = $request->input('password');

        if (empty($type)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống loại người dùng'
            ]);
        }


        if (empty($name)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống tên'
            ]);
        }

        if (empty($phone)) {
            return response([
                'status' => 0,
                'message' => 'Không được bỏ trống SĐT'
            ]);
        }


        if (!empty($email)) {
            $checkEmail = User::query()
                ->where('type', $type)
                ->where('email', $email)
                ->first();

            if ($checkEmail) {
                return response([
                    'status' => 0,
                    'message' => 'Email đã tồn tại'
                ]);
            }
        }

        $checkPhone = User::query()
            ->when(!empty($countryPhoneCode), function ($q) use ($countryPhoneCode) {
                $q->where('country_phone_code', $countryPhoneCode);
            })
            ->where('phone', $phone)
            ->where('type', $type)
            ->first();
        if ($checkPhone) {

            return response([
                'status' => 0,
                'message' => 'SĐT đã tồn tại'
            ]);
        }

        if ($request->file('avatar') && $request->file('avatar')->isValid()) {
            $image = Functions::uploadImage($request->file('avatar'));
        }

        if (!empty($birthday)) {
            try {
                $birthday = Carbon::createFromFormat('d/m/Y', $birthday)->format('d/m/Y');
            } catch (\Exception $ex) {
                $birthday = null;
            }
        }

        $referId = null;
        if (!empty($referCode)) {
            $referUser = User::query()
                ->where('refer_code', $referCode)
                ->first();
            if ($referUser) {
                $referId = $referUser->id;
            }
        }

        try {
            \DB::beginTransaction();

            $user = User::create([
                'name' => $name,
                'email' => $email,
                'phone' => $phone,
                'password' => !empty($password) ? \Hash::make($password) : \Hash::make('123456'),
                'type' => $type,
                'image' => $image,
                'birthday' => $birthday,
                'gender' => $gender,
                'country_phone_code' => $countryPhoneCode,
                'facebook_id' => $facebookId,
                'zalo_id' => $zaloId,
                'apple_id' => $appleId,
                'branch_app' => $branchApp,
                'from' => $from,
                'refer_id' => $referId
            ]);


            if ($type == User::OWNER) {

                $content = 'Chúc mừng ' . $user->name .
                    ' đã đăng ký thành công làm chủ trọ trên hệ thống itro. Hãy tạo nhà trọ và thêm ngay người trọ để quản lý từ bây giờ';
            } else if ($type == User::RENTER) {
                $content = 'Chúc mừng ' . $user->name .
                    ' đã đăng ký thành công làm người trọ trên hệ thống itro. Hãy bắt đầu tìm kiếm nhà trọ theo tiêu chí của bạn hoặc giúp chúng tôi kết nối với nhà trọ của bạn ngay bây giờ';
            }

            $payload = json_encode([
                'id' => 0,
                'type' => config('constants.REGISTER_SUCCESS')
            ]);

            Notification::create([
                'to_user' => $user->id,
                'title' => 'Thông báo từ itro.vn',
                'user_id' => $user->id,
                'content' => $content,
                'payload' => $payload
            ]);

            $user->code = \Vinkla\Hashids\Facades\Hashids::encode('123456789' . $user->id);
            $user->save();

            //dang ky goi cuoc

            if ($user->type == User::OWNER) {
                $user->assignRole('owner');

//                $user->assignRole('owner');
//                $permissions = Permission::all()->pluck('name')->toArray();
//                $user->syncPermissions($permissions);

                $packageId = 4;
//                $packageId = $request->input('package_id', 1);
                $package = Package::find($packageId);
                if (!$package) {
                    $package = Package::query()->first();
                }

                UserPackage::create([
                    'user_id' => $user->id,
                    'package_id' => $package->id,
                    'number_hostels' => $package->number_hostels,
                    'number_rooms' => $package->number_rooms,
                    'number_staffs' => $package->number_staffs,
                    'price_per_month' => $package->price_per_month,
                    'start_date' => $user->created_at->toDateString(),
                    'end_date' => $user->created_at->addDays(10)->toDateString(),
                ]);

                if (!empty($promotionCode)) {
                    $resRedeem = Functions::redeemCoupon($promotionCode, $user->id);
                    if ($resRedeem['status'] == 0) {
                        return response($resRedeem);
                    }
                }

                $checkAgency = CouponTransaction::query()->where('phone', $phone)
                    ->whereNull('owner_id')
                    ->first();

                if ($checkAgency) {
                    $partnerId = $checkAgency->partner_id;
                    \DB::table('partner_owners')
                        ->insert([
                            'partner_id' => $partnerId,
                            'owner_id' => $user->id
                        ]);

                    $checkAgency->owner_id = $user->id;
                    $checkAgency->owner_name = $user->name_text;
                    $checkAgency->save();
                }
            }


            \DB::commit();

            $verifyPhoneJob = (new CreateDelayNotificationPhone($user->id))->delay(Carbon::now()->addMinute(30));

            dispatch($verifyPhoneJob);

            $remindJob = (new RemindCreateRoom($user->id))->delay(Carbon::now()->addDay(3));

            dispatch($remindJob);

            if ($user->type == User::OWNER) {
                $this->dispatch(new SendMailWhenNewOwner($user));
                $regions = $request->input('regions');

                if (is_array($regions)) {
                    foreach ($regions as $region) {
                        \DB::table('owner_regions')->insert([
                            'user_id' => $user->id,
                            'province_id' => $region
                        ]);
                    }
                    $regionNames = null;
                    if ($user->regions->count() > 0) {
                        $regionNames = implode(', ', $user->regions->pluck('name')->toArray());
                    }

                    \DB::connection('crm')->table('tblleads')
                        ->where('phonenumber', $user->phone)
                        ->update([
                            'city' => $regionNames
                        ]);
                }
            }

            if ($user->type == User::RENTER) {
                $delayMinutes = config('constants.REMIND_RENTER_SEARCH_HOURS');
                foreach ($delayMinutes as $delayMinute) {
                    $when = Carbon::now()->addMinute(intval($delayMinute));
                    dispatch((new RemindRenterSearchHostel($user->id))->delay($when));
                }
            }

            if ($user->type == User::OWNER) {
                $delayMinutes = config('constants.REMIND_OWNER_SEARCH_HOURS');
                foreach ($delayMinutes as $delayMinute) {
                    $when = Carbon::now()->addMinute(intval($delayMinute));
                    dispatch((new \App\Jobs\RemindOwnerSearchHostel($user->id))->delay($when));
                }
            }


            if (!empty($tokenDevice) && !empty($tokenType)) {
                Token::query()
                    ->where('type', $tokenType)
                    ->where('token', $tokenDevice)
                    ->delete();

                Token::create([
                    'user_id' => $user->id,
                    'type' => $tokenType,
                    'token' => $tokenDevice,
                ]);
            }
        } catch (\Exception $ex) {
            \DB::rollBack();

            \Log::info($ex->getMessage() . '|' . $ex->getLine());

            return response([
                'status' => 0,
                'message' => 'Có lỗi xảy ra vui lòng thử lại sau'
            ]);
        }

        $token = \Tymon\JWTAuth\Facades\JWTAuth::fromUser($user);

        return response([
            'status' => 1,
            'message' => 'Đăng ký thành công',
            'data' => [
                'user' => [
                    'id' => $user->id,
                    'name' => $user->name_text,
                    'phone' => $user->phone,
                    'email' => $user->email,
                    'avatar' => $user->image,
                    'gender' => $user->gender,
                    'type' => $user->type,
                    'number_interacts' => $user->number_interacts,
                ],
                'token' => $token
            ]
        ]);

    }

    /**
     * @api {post} v2/account/update Cập nhật
     * @apiName /update
     * @apiGroup Account
     * @apiParam {String} id
     * @apiParam {String} [email]
     * @apiParam {String} phone
     * @apiParam {String} [country_phone_code]
     * @apiParam {String} [facebook_id]
     * @apiParam {String} [zalo_id]
     * @apiParam {String} type
     * @apiParam {String} name
     * @apiParam {String} [gender]
     * @apiParam {String} [birthday] Dạng d/m/Y
     * @apiParam {File} [avatar]
     *
     *
     * @apiDescription Api cập nhật
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function update(Request $request)
    {
        $id = $request->input('id');
        $data = $request->all();
        $email = $request->input('email');
        $phone = $request->input('phone');
        $type = $request->input('type');
        $birthday = $request->input('birthday');
        $image = $request->file('avatar');
        $countryPhoneCode = $request->input('country_phone_code');

        $user = User::find($id);
        if (!$user) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }


        if (!empty($email)) {
            $checkEmail = User::query()
                ->where('email', $email)
                ->where('type', $type)
                ->where('id', '<>', $id)->first();

            if ($checkEmail) {
                return response([
                    'status' => 0,
                    'message' => 'Email đã tồn tại'
                ]);
            }
        }

        $checkPhone = User::query()
            ->when(!empty($countryPhoneCode), function ($q) use ($countryPhoneCode) {
                $q->where('country_phone_code', $countryPhoneCode);
            })
            ->where('id', '<>', $id)
            ->where('phone', $phone)
            ->where('type', $type)->first();
        if ($checkPhone) {

            return response([
                'status' => 0,
                'message' => 'SĐT đã tồn tại'
            ]);
        }

        if ($request->file('avatar') && $request->file('avatar')->isValid()) {
            $image = Functions::uploadImage($request->file('avatar'));
            $data['image'] = $image;
        }

        if (!empty($birthday)) {
            try {
                $birthday = Carbon::createFromFormat('d/m/Y', $birthday)->format('d/m/Y');
            } catch (\Exception $ex) {
                $birthday = null;
            }
            $data['birthday'] = $birthday;
        }


        try {
            $user->update($data);
        } catch (\Exception $ex) {
            return response([
                'status' => 0,
                'message' => 'Có lỗi xảy ra vui lòng thử lại sau'
            ]);
        }
        $newToken = JWTAuth::parseToken()->refresh();
        $referArr = null;
        $userRefer = $user->refer;
        if ($userRefer) {
            $referArr = [
                'id' => $userRefer->id,
                'name' => $userRefer->name_text,
                'phone' => $userRefer->phone,
                'image' => $userRefer->image,
                'email' => $userRefer->email,
            ];
        }

        return response([
            'status' => 1,
            'message' => 'Cập nhật thành công',
            'data' => [
                'user' => [
                    'id' => $user->id,
                    'name' => $user->name_text,
                    'phone' => $user->phone,
                    'email' => $user->email,
                    'avatar' => $user->image,
                    'gender' => $user->gender,
                    'type' => $user->type,
                    'refer_code' => $user->refer_code,
                    'user_refer' => $userRefer
                ],
                'token' => $newToken
            ]
        ]);

    }

    /**
     * @api {post} v2/account/refresh-token Refresh token
     * @apiName /refresh-token
     * @apiGroup Account
     *
     *
     * @apiDescription Api Refresh token
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function refreshToken()
    {
        try {
            $newToken = JWTAuth::parseToken()->refresh();
            $user = JWTAuth::toUser($newToken);
            $numberInteracts = $user->number_interacts;
            $balance = $user->balance;
            if ($user->type == User::STAFF) {
                $owner = $user->owner;
                $numberInteracts = optional($owner)->number_interacts;
                $balance = optional($owner)->balance;
            }

            if (empty($user->aff_link)) {
                $user->aff_link = Functions::generateDynamicLinkAff($user);
                $user->save();
            }


            $packageFindHostel = Functions::getPackageFindHostel($user);

            $referArr = null;
            $userRefer = $user->refer;
            if ($userRefer) {
                $referArr = [
                    'id' => $userRefer->id,
                    'name' => $userRefer->name_text,
                    'phone' => $userRefer->phone,
                    'image' => $userRefer->image,
                    'email' => $userRefer->email,
                ];
            }

            return response([
                'status' => 1,
                'message' => 'Success',
                'data' => [
                    'user' => [
                        'id' => $user->id,
                        'name' => $user->name_text,
                        'phone' => $user->phone,
                        'email' => $user->email,
                        'avatar' => $user->image,
                        'gender' => $user->gender,
                        'type' => $user->type,
                        'balance' => $balance,
                        'number_interacts' => $numberInteracts,
                        'package_find_hostel' => $packageFindHostel,
                        'country_phone_code' => $user->country_phone_code,
                        'refer_code' => $user->refer_code,
                        'user_refer' => $referArr,
                        'aff_link' => $user->aff_link
                    ],
                    'token' => $newToken
                ]
            ], 200);
        } catch (TokenBlacklistedException $ex) {

            return response([
                'status' => 0,
                'message' => 'Token very old old old',
                'data' => [
                    'token' => ''
                ]
            ], 400);
        } catch (TokenExpiredException $ex) {
            return response([
                'status' => 0,
                'message' => 'Cannot refresh this token, please login again',
                'data' => [
                    'token' => ''
                ]
            ], 401);
        } catch (JWTException $ex) {
            return response([
                'status' => 0,
                'message' => 'Cannot refresh this token, please login again',
                'data' => [
                    'token' => ''
                ]
            ], 401);
        }

    }

    /**
     * @api {get} v2/account/find-session Danh sách find session
     * @apiName /find-session
     * @apiGroup Account
     * @apiParam {Number} limit
     * @apiParam {Number} offset
     * @apiParam {Number} status 0 là đang tìm, 1 là đã thấy, 2 là ko thấy, 3 là hủy.
     *
     * @apiDescription Api Danh sách find session
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */

    public function getFindSession(Request $request)
    {
        $userId = $this->user->id;
        $status = $request->input('status');
        //$userId = 20093;
        $limit = $request->input('limit', 10);
        $offset = $request->input('offset', 0);

        $items = FindSession::query()
            ->where('user_id', $userId)
            ->with([
                'conversations',
                'hostelType'
            ])
            ->when(!empty($status), function ($q) use ($status) {
                $q->where('status', $status);
            }, function ($q) {
                $q->where('status', FindSession::SEARCHING);
            })
            ->limit($limit)
            ->offset($offset)
            ->orderBy('id', 'desc')
            ->get()
            ->map(function ($item) {
                //	id, province, district, min_price, max_price, status
                $properties = $item->properties;
                $districtArr = [];
//                dump($item->id);
//                dump($properties['district_id']);
                if (isset($properties['district_id'])) {
                    foreach ($properties['district_id'] as $districtId) {
                        $districtArr[] = [
                            'districtid' => $districtId,
                            'name' => optional(Functions::getDistrictName($districtId))->name
                        ];
                    }
                }
                $hostelType = null;
                if ($item->hostelType) {
                    $hostelType = [
                        'id' => $item->hostelType->id,
                        'name' => $item->hostelType->name
                    ];
                }

                $typeRent = null;
                if (isset($properties['type_rent'])) {
                    $typeRent = $properties['type_rent'];
                } else if (isset($properties['type'])) {
                    $typeRent = $properties['type'];
                }

                return [
                    'id' => $item->id,
                    'province' => [
                        'provinceid' => isset($properties['province_id']) ? $properties['province_id'] : null,
                        'name' => isset($properties['province_id']) ? Functions::getProvinceName($properties['province_id'])->name : null,
                    ],
                    'district' => $districtArr,
                    'min_price' => isset($properties['min_price']) ? $properties['min_price'] : null,
                    'max_price' => isset($properties['max_price']) ? $properties['max_price'] : null,
                    'status' => $item->status,
                    'created_at' => $item->created_at->format('d/m/Y H:i'),
                    'num_of_conversation' => $item->conversations->count(),
                    'type' => $typeRent,
                    'note' => $item->note,
                    'hostel_type' => $hostelType
                ];
            });

        return response([
            'status' => 1,
            'data' => $items
        ]);

    }

    /**
     * @api {post} v2/account/create-bookmark Đánh dấu yêu thích
     * @apiName /create-bookmark
     * @apiGroup Account
     * @apiParam {String} hostel_id
     * @apiParam {String} find_session_id
     *
     *
     * @apiDescription Api Đánh dấu yêu thích
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function createBookmark(Request $request)
    {
        $hostelId = $request->input('hostel_id');
        $findSessionId = $request->input('find_session_id');

        $bookmark = Bookmark::query()->where('hostel_id', $hostelId)
            ->where('user_id', $this->user->id)
            ->where('find_session_id', $findSessionId)
            ->first();
        if ($bookmark) {
            $bookmark->delete();
        } else {

            Bookmark::create([
                'hostel_id' => $hostelId,
                'find_session_id' => $findSessionId,
                'user_id' => $this->user->id
            ]);
        }

        return response([
            'status' => 1
        ]);
    }

    /**
     * @api {post} v2/account/remove-bookmark Xóa yêu thích
     * @apiName /remove-bookmark
     * @apiGroup Account
     * @apiParam {String} hostel_id
     * @apiParam {String} find_session_id
     *
     *
     * @apiDescription Api Xóa yêu thích
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function removeBookmark(Request $request)
    {
        $hostelId = $request->input('hostel_id');
        $findSessionId = $request->input('find_session_id');

        Bookmark::query()
            ->where('hostel_id', $hostelId)
            ->where('user_id', $this->user->id)
            ->where('find_session_id', $findSessionId)
            ->delete();

        return response([
            'status' => 1
        ]);
    }

    /**
     * @api {get} v2/account/bookmark Danh sách đánh dấu
     * @apiName /bookmark
     * @apiGroup Account
     * @apiParam {Number} limit
     * @apiParam {Number} offset
     *
     *
     * @apiDescription Api Danh sách đánh dấu
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getBookmark(Request $request)
    {
        $limit = $request->input('limit', 10);
        $offset = $request->input('offset', 0);

        $items = Bookmark::query()
            ->where('user_id', $this->user->id)
            ->with([
                'hostel'
            ])
            ->has('hostel')
            ->limit($limit)
            ->offset($offset)
            ->get()
            ->map(function ($item) {
                $hostel = $item->hostel;

                return [
                    "id" => $item->hostel->id,
                    "name" => $item->hostel->name,
                    "image" => $item->hostel->image,
                    "address" => $item->hostel->address,
                    "desc" => $item->hostel->desc,
                    "find_session_id" => $item->find_session_id,
                    'province' => optional($hostel->province)->name,
                    'district' => optional($hostel->district)->name,
                    'ward' => optional($hostel->ward)->name,
                ];
            });

        return response([
            'status' => 1,
            'data' => $items
        ]);
    }

    /**
     * @api {get} v2/account/config Config cộng trừ tiền
     * @apiName /config
     * @apiGroup Account
     *
     *
     * @apiDescription Api Config cộng trừ tiền
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getConfig(Request $request)
    {
        return response([
            'status' => 1,
            'data' => [
                'charge_owner' => option('charge_owner', 200000),
                'add_renter' => option('add_renter', 100000)
            ]
        ]);
    }

    /**
     * @api {post} v2/account/logout Logout
     * @apiName /logout
     * @apiGroup Account
     * @apiParam {String} token
     *
     *
     * @apiDescription Api Logout
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function logout(Request $request)
    {
        $token = $request->input('token');
        if (!empty($token)) {
            Token::query()
                ->where('token', $token)
                ->delete();
        }

        return response([
            'status' => 1,
        ]);
    }

    /**
     * @api {post} v2/account/recommend-hostels Recommend
     * @apiName /Recommend
     * @apiGroup Account
     * @apiParam {Number} limit
     * @apiParam {Number} offset
     * @apiParam {String} province_id
     * @apiParam {Array} district_id
     * @apiParam {Array} ward_id
     * @apiParam {String} type
     * @apiParam {String} type_rent
     * * @apiParam {String} price_min
     * @apiParam {Array} price_max
     *
     *
     *
     * @apiDescription Api gợi ý nhà trọ cho người thuê
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getHostelForRenter(Request $request)
    {
        $limit = $request->input('limit', 10);
        $offset = $request->input('offset', 0);

        $provinceId = $request->input('province_id');
        $districtIds = $request->input('district_id');
        $wardIds = $request->input('ward_id');
        $type = $request->input('type');
        $typeRent = $request->input('type_rent');
        $query = $request->input('q');
        $sort = $request->input('sort');

        $excludes = [];
        if($this->user) {
            $excludes = $this->user->excludeRecommends->pluck('id')->toArray();
        }

        $priceMin = $request->input('price_min');
        $priceMax = $request->input('price_max');

//        $provinceSearchedBefore = FindSession::query()
//            ->where('user_id', $this->user->id)
//            ->groupBy('province_id')
//            ->pluck('province_id')
//            ->toArray();

        $findSessionBefore = [];
        if($this->user) {
            $findSessionBefore = FindSession::query()
                ->where('user_id', $this->user->id)
                ->pluck('id')
                ->toArray();
        }

//        $districtSearchedBefore = \DB::table('find_session_districts')
//            ->whereIn('find_session_id', $findSessionBefore)
//            ->groupBy('district_id')
//            ->pluck('district_id')
//            ->toArray();


        $items = Hostel::query()
            ->with([
                'owner',
                'imagesMany'
            ])
            //->where('id', 10176)
            ->whereNotNull('province_id')
            ->whereNotNull('district_id')
            ->whereNotNull('ward_id')
            ->has('images')
            ->has('owner')
            ->where('number_empty_rooms', '>', 0)
            ->whereHas('owner.package', function($q) {
                $q->where('end_date', '>', Carbon::now());
                //$q->whereRaw('TIMESTAMPDIFF(MONTH, "end_date", "start_date") >= 1');
            })
            ->when(!empty($excludes), function ($q) use ($excludes) {
                $q->whereNotIn('hostels.id', $excludes);
            })
            ->when(!empty($provinceId), function ($q) use ($provinceId) {
                $q->where('hostels.province_id', $provinceId);
            })
            ->when(!empty($districtIds), function ($q) use ($districtIds) {
                $q->whereIn('hostels.district_id', $districtIds);
            })
            ->when(!empty($wardIds), function ($q) use ($wardIds) {
                $q->whereIn('hostels.ward_id', $wardIds);
            })
            ->when(!empty($priceMin), function ($q) use ($priceMin) {
                $q->where('min_price', '>=', $priceMin);
            })
            ->when(!empty($priceMax), function ($q) use ($priceMax) {
                $q->where('max_price', '<=', $priceMax);
            })
            ->when(!empty($sort), function ($q) use ($sort) {
                if ($sort == 'price_asc') {
                    $q->orderBy('max_price', 'asc');
                } else if ($sort == 'price_desc') {
                    $q->orderBy('max_price', 'desc');
                } else if ($sort == 'latest') {
                    $q->orderBy('created_at', 'desc');
                }
            })
            ->when(!empty($type), function ($q) use ($type) {
                $q->where('hostels.type', $type);
            })
            ->when(!empty($typeRent), function ($q) use ($typeRent) {
                $q->where('hostels.type_rent', $typeRent);
            })
//            ->when(!empty($provinceSearchedBefore), function ($q) use ($provinceId, $provinceSearchedBefore) {
//                if (empty($provinceId)) {
//                    $q->whereIn('hostels.province_id', $provinceSearchedBefore);
//                }
//            })
//            ->when(!empty($districtSearchedBefore), function ($q) use ($districtIds, $districtSearchedBefore) {
//                if (empty($districtIds)) {
//                    $q->whereIn('hostels.district_id', $districtSearchedBefore);
//                }
//            })
            ->when(!empty($query), function ($q) use ($query) {
                $q->where(function ($q) use ($query) {
                    $q->orWhere('hostels.name', 'LIKE', '%' . $query . '%');
                    $q->orWhere('hostels.desc', 'LIKE', '%' . $query . '%');
                    $q->orWhere('hostels.address', 'LIKE', '%' . $query . '%');
                    $q->orWhereHas('province', function($q) use ($query) {
                        $q->where('name', 'LIKE', '%'.$query.'%');
                    });
                    $q->orWhereHas('district', function($q) use ($query) {
                        $q->where('name', 'LIKE', '%'.$query.'%');
                    });
                    $q->orWhereHas('ward', function($q) use ($query) {
                        $q->where('name', 'LIKE', '%'.$query.'%');
                    });
                });
            })
            ->where('status_confirm', Hostel::CONFIRMED)
            ->with([
                'province',
                'district',
                'ward'
            ])
            ->limit($limit)
            ->offset($offset)
            ->orderBy('id', 'desc')
            ->get()
            ->map(function ($item) {
                $arr = $item->toArray();
                $images = $item->imagesMany->map(function ($item) {
                    return [
                        "url" => '/files/' . $item->image,
                        "id" => $item->id,
                        "type" => $item->type
                    ];
                })->toArray();
                $arr['images'] = null;
                if (!empty($images)) {
                    $arr['images'] = $images;
                }
                $arr['owner'] = [
                    'id' => $item->owner->id,
                    'name' => $item->owner->name_text,
                    'image' => $item->owner->image
                ];

                $arr['province_name'] = optional($item->province)->name;
                $arr['district_name'] = optional($item->district)->name;
                $arr['ward_name'] = optional($item->ward)->name;
                if ($this->user) {
                    $arr['is_favourite'] = Functions::checkFavourite($this->user->id, $item->id);
                }

                unset($arr['province']);
                unset($arr['district']);
                unset($arr['ward']);

                return $arr;
            });

        return response([
            'status' => 1,
            'data' => $items
        ]);
    }

    /**
     * @api {post} v2/account/exclude-hostel Exclude hostels
     * @apiName /exclude-hostel
     * @apiGroup Account
     * @apiParam {String} hostel_id
     *
     *
     * @apiDescription Api loại hostel ra khỏi danh sách recommend
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function excludeHostels(Request $request)
    {
        $user = $this->user;
        $hostelId = $request->input('hostel_id');

        $user->excludeRecommends()->attach($hostelId);

        return response([
            'status' => 1,
            'message' => 'Success'
        ]);
    }

    /**
     * @api {post} v2/account/exclude-leads Exclude leads
     * @apiName /exclude-leads
     * @apiGroup Account
     * @apiParam {String} id Id này chính là id đưọc trả ra trong api v2/search/customer
     *
     *
     * @apiDescription Api loại leads ra khỏi danh sách recommend
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function excludeLeads(Request $request)
    {
        $owner = $this->user;
        if ($this->user->type == User::STAFF) {
            $owner = $this->user->owner;
        }
        $findSessionId = $request->input('id');
        $findSession = FindSession::find($findSessionId);
        if (!$findSession) {
            return response([
                'status' => 0,
                'message' => 'Dữ liệu không hợp lệ'
            ]);
        }
        \DB::table('exclude_leads')
            ->where('find_session_id', $findSessionId)
            ->delete();

        \DB::table('exclude_leads')
            ->insert([
                'find_session_id' => $findSession->id,
                'user_id' => optional($owner)->id,
                'lead_id' => $findSession->lead_id
            ]);

        return response([
            'status' => 1,
            'message' => 'Success'
        ]);
    }

    /**
     * @api {post} v2/account/take-lead Đưa vào danh sách lead đã lấy số
     * @apiName /take-lead
     * @apiGroup Account
     * @apiParam {String} lead_id lead_id
     *
     *
     * @apiDescription Đưa vào danh sách lead đã lấy số
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function takeLead(Request $request)
    {
        $owner = $this->user;
        if ($this->user->type == User::STAFF) {
            $owner = $this->user->owner;
        }
        $leadId = $request->input('lead_id');

        LeadUserTake::create([
            'user_id' => $owner->id,
            'find_session_id' => $leadId
        ]);

        return response([
            'status' => 1,
            'message' => 'Success'
        ]);
    }

    /**
     * @api {get} v2/account/lead-taken Danh sách lead đã lấy số
     * @apiName /lead-taken
     * @apiGroup Account
     *
     *
     * @apiDescription Đưa vào danh sách lead đã lấy số
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function leadTaken(Request $request)
    {
        $owner = $this->user;
        if ($this->user->type == User::STAFF) {
            $owner = $this->user->owner;
        }
        $leads = LeadUserTake::query()
            ->where('user_id', $owner->id)
            ->with('findSession')
            ->has('findSession')
            ->get()
            ->map(function ($lead) {
                $item = $lead->findSession;
                $user = $item->user;
                $properties = $item->properties;
                $districtArr = [];
                if (isset($properties['district_id'])) {
                    foreach ($properties['district_id'] as $districtId) {
                        $districtArr[] = [
                            'districtid' => $districtId,
                            'name' => Functions::getDistrictName($districtId)->name
                        ];
                    }
                }

                $hostelType = null;
                if ($item->hostelType) {
                    $hostelType = [
                        'id' => $item->hostelType->id,
                        'name' => $item->hostelType->name
                    ];
                }
                $renter = null;
                $leadArr = null;
                if (empty($item->lead_id)) {
                    $renter = [
                        'id' => $user->id,
                        'name' => $user->name_text,
                        'phone' => $user->phone,
                        'image' => $user->image
                    ];
                } else {
                    $lead = $item->lead;
                    if ($lead) {
                        $leadArr = [
                            'name' => $lead->name,
                            'phone' => $lead->phone,
                            'source' => $lead->source,
                            'link' => $lead->source_link,
                            'content' => $lead->note
                        ];
                    }
                }

                $typeRent = null;
                if (isset($properties['type_rent'])) {
                    $typeRent = $properties['type_rent'];
                } else if (isset($properties['type'])) {
                    $typeRent = $properties['type'];
                }

                return [
                    'id' => $item->id,
                    'renter' => $renter,
                    'province' => [
                        'provinceid' => isset($properties['province_id']) ? $properties['province_id'] : null,
                        'name' => isset($properties['province_id']) ? Functions::getProvinceName($properties['province_id'])->name : null,
                    ],
                    'district' => $districtArr,
                    'min_price' => isset($properties['min_price']) ? $properties['min_price'] : null,
                    'max_price' => isset($properties['max_price']) ? $properties['max_price'] : null,
                    'status' => $item->status,
                    'created_at' => $item->created_at->format('d/m/Y H:i'),
                    'num_of_conversation' => $item->conversations->count(),
                    'type' => $typeRent,
                    'note' => $item->note,
                    'hostel_type' => $hostelType,
                    'lead' => $leadArr,
                    'is_lead' => empty($item->lead_id) ? false : true
                ];
            });

        return response([
            'status' => 1,
            'data' => $leads
        ]);
    }

    /**
     * @api {post} v2/account/add-refer-code Điền mã giới thiệu
     * @apiName /add-refer-code
     * @apiGroup Account
     * @apiParam {String} refer_code
     *
     * @apiDescription Đưa vào danh sách lead đã lấy số
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function addReferCode(Request $request)
    {
        $referCode = $request->input('refer_code');
        $user = $this->user;

        $userRefer = User::query()
            ->where('refer_code', $referCode)
            ->first();
        if (!$userRefer) {
            return response([
                'status' => 0,
                'message' => 'Không tồn tại mã giới thiệu trên hệ thống'
            ]);
        }

        if (!empty($user->refer_id)) {
            return response([
                'status' => 0,
                'message' => 'User đã tồn tại người giới thiệu trước đó'
            ]);
        }


        $user->refer_id = $userRefer->id;
        $user->refer_date = Carbon::now();
        $user->save();

        return response([
            'status' => 1,
            'message' => 'Thành công'
        ]);

    }

    /**
     * @api {get} v2/account/refer Danh sách user được giới thiệu
     * @apiName /refer
     * @apiGroup Account
     *
     * @apiDescription Danh sách user được giới thiệu
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function referList(Request $request)
    {
        $user = $this->user;
        $users = User::query()
            ->where('refer_id', $user->id)
            ->get()
            ->map(function ($item) {
                return [
                    'id' => $item->id,
                    'name' => $item->name_text,
                    'phone' => $item->phone,
                    'image' => $item->image,
                    'email' => $item->email,
                    'payment_status' => $item->payment_status
                ];
            });

        return response([
            'status' => 1,
            'data' => $users
        ]);
    }

    /**
     * @api {get} v2/account/refer-link Lấy dynamic link giới thiệu
     * @apiName /refer-link
     * @apiGroup Account
     *
     * @apiDescription Lấy dynamic link giới thiệu
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getAffiliateLink(Request $request)
    {
        $user = $this->user;
        $affLink = $user->aff_link;
        if (empty($affLink)) {
            $affLink = Functions::generateDynamicLinkAff($user);
            $user->aff_link = $affLink;
            $user->save();
        }

        return response([
            'status' => 1,
            'data' => $affLink
        ]);
    }

    /**
     * @api {post} v2/account/crawl-wishlist Wishlist crawl
     * @apiName /crawl-wishlist
     * @apiGroup Account
     * * @apiParam {String} id
     *
     * @apiDescription  Wishlist crawl
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function hostelPostWishlist(Request $request)
    {
        $user = $this->user;
        $id = $request->input('id');

        $user->crawlWishlist()->toggle([
            $id
        ]);
        return response([
            'status' => 1
        ]);
    }

    /**
     * @api {get} v2/account/crawl-wishlist get Wishlist crawl
     * @apiName /get-crawl-wishlist
     * @apiGroup Account
     *
     * @apiDescription get Wishlist crawl
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getHostelPostWishlist(Request $request)
    {
        $user = $this->user;

        $items = $user->crawlWishlist()
            ->with('medias')
            ->get()
            ->map(function ($item) {
                $arr = $item->toArray();
                $arr['province_name'] = optional($item->province)->name;
                $arr['district_name'] = optional($item->district)->name;
                $arr['ward_name'] = optional($item->ward)->name;

                return $arr;
            });
        return response([
            'status' => 1,
            'data' => $items
        ]);
    }

    /**
     * @api {get} v2/account/hostel-post get hostle post user
     * @apiName /hostel-post
     * @apiGroup Account
     *
     * @apiDescription get Wishlist crawl
     * @apiSuccess {Number} status 1 hoặc 0. 1 là thành công, 0 là không thành công.
     * @apiSuccess {String} message  Tin nhắn hệ thống.
     * @apiSuccess {String} data
     */
    public function getHostelPost(Request $request)
    {
        $user = $this->user;

        $items = HostelPostCrawl::query()
            ->with([
                'hostel',
                'province',
                'district',
                'ward',
                'userWishlists',
                'medias'
            ])
            ->whereHas('hostel', function ($q) use ($user) {
                $q->where('hostels.owner_id', $user->id);
            })
            ->get()
            ->map(function ($item) use ($user) {
                $arr = $item->toArray();
                unset($arr['user_wishlists']);
                $arr['province_name'] = optional($item->province)->name;
                $arr['district_name'] = optional($item->district)->name;
                $arr['ward_name'] = optional($item->ward)->name;
                $arr['hostel_type_name'] = optional($item->hostelType)->name;
                $arr['videos'] = null;
                if ($item->hostel) {
                    $arr['videos'] = $item->hostel->videos;
                }
                $wishlisted = false;
                if (in_array($user->id, $item->userWishlists->pluck('id')->toArray())) {
                    $wishlisted = true;
                }
                $arr['is_wishlist'] = $wishlisted;

                return $arr;
            });
        return response([
            'status' => 1,
            'data' => $items
        ]);
    }
}
