<?php
/**
 * Created by PhpStorm.
 * User: Asus
 * Date: 11/21/2017
 * Time: 11:37 AM
 */

namespace App\Components;

use App\Jobs\RemindCreateRoom;
use App\Models\Amenity;
use App\Models\Category;
use App\Models\CollectSpend;
use App\Models\Config;
use App\Models\ConfigHostel;
use App\Models\Contract;
use App\Models\ContractFee;
use App\Models\Conversation;
use App\Models\Coupon;
use App\Models\Course;
use App\Models\ElectricQuota;
use App\Models\ElectricWater;
use App\Models\Extra;
use App\Models\Hostel;
use App\Models\HostelFee;
use App\Models\HostelPostCrawl;
use App\Models\HostelRating;
use App\Models\Item;
use App\Models\Lesson;
use App\Models\Message;
use App\Models\MoneyDetail;
use App\Models\MoneyInfo;
use App\Models\MoneyUnit;
use App\Models\Notification;
use App\Models\Package;
use App\Models\RenterBike;
use App\Models\RenterRoom;
use App\Models\Room;
use App\Models\RoomBed;
use App\Models\RoomEw;
use App\Models\RoomFee;
use App\Models\RoomReservation;
use App\Models\RoomType;
use App\Models\SendZaloLog;
use App\Models\StatisticLog;
use App\Models\Teacher;
use App\Models\Transaction;
use App\Models\UserMoney;
use App\Models\UserPackage;
use App\Models\UserPackageFindHostel;
use App\Models\Warehouse;
use App\Models\WaterQuota;
use App\Models\Wishlist;
use App\Models_v2\Bookmark;
use App\Models_v2\FindSession;
use App\User;
use Carbon\Carbon;
use Dompdf\Exception;
use FCM;
use GuzzleHttp\Client;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Str;
use Image;
use Kreait\Firebase\DynamicLink\AndroidInfo;
use Kreait\Firebase\DynamicLink\CreateDynamicLink;
use Kreait\Firebase\DynamicLink\IOSInfo;
use Kreait\Firebase\DynamicLink\SocialMetaTagInfo;
use Kreait\Firebase\Factory;
use LaravelFCM\Message\OptionsBuilder;
use LaravelFCM\Message\PayloadDataBuilder;
use LaravelFCM\Message\PayloadNotificationBuilder;
use phpseclib\Crypt\RSA;
use Pusher\Pusher;

class Functions
{
    public static function getUserForRoom($room)
    {
        $user = RenterRoom::query()->where('room_id', $room->id)->where('is_head', 1)->first();
        if ($user) {
            return $user->account;
        } else {
            $user = RenterRoom::where('room_id', $room->id)->first();
            if ($user) {
                return $user->account;
            }
        }

        return null;

    }

    public static function getConfigNote(Hostel $hostel)
    {
        $item = ConfigHostel::query()
            ->where('hostel_id', $hostel->id)
            ->first();
        if ($item) {
            return html_entity_decode(strip_tags($item->voucher));
        }
        return null;
    }

    public static function sendZns($message)
    {
        $token = env('ZNS_TOKEN');

        $baseUrl = 'https://business.openapi.zalo.me/message/template';
        $url = $baseUrl . '?access_token=' . $token;
        $phone = $message['phone'];
        $phone = ltrim($phone, '0');
        if (!starts_with($phone, '84')) {
            $phone = '84' . $phone;
        }
        $postArr = [
            "phone" => $phone,
            "template_id" => $message['template_id'],
            "template_data" => $message['data'],
            "tracking_id" => uniqid()
        ];

        $client = new Client();
        $response = $client->post($url, [
            'json' => $postArr
        ]);
        $response = $response->getBody()->getContents();
        $response = json_decode($response, true);
        SendZaloLog::create([
            'properties' => $message,
            'response' => $response
        ]);
        return $response;
        // Send notification to the $notifiable instance...
    }

    public static function sendMessageInvoiceZns($data)
    {
        $token = env('ZNS_TOKEN');
        $baseUrl = 'https://business.openapi.zalo.me/message/template';
        $url = $baseUrl . '?access_token=' . $token;

        $hostelName = $data['hostel_name'];
        $roomName = $data['room_name'];
        $customerName = $data['customer_name'];
        $hostelName = mb_strimwidth($hostelName, 0, 25, '...');
        $roomName = mb_strimwidth($roomName, 0, 18, '...');
        $customerName = mb_strimwidth($customerName, 0, 25, '...');

        $postArr = [
            "phone" => $data['phone'],
            "template_id" => "201166",
            "template_data" => [
                "room_name" => $roomName,
                "amount" => $data['amount'],
                "url_extend" => $data['invoice_path'],
                "customer_name" => $customerName,
                "hostel_name" => $hostelName
            ],
            "tracking_id" => uniqid()
        ];

        $userId = null;
        if (auth('backend')->check()) {
            $userId = auth('backend')->user()->id;
        } else {
            $token = \request()->header('authorization');
            if ($token) {
                $user = \JWTAuth::parseToken()->toUser();
                if ($user) {
                    $userId = $user->id;
                }
            }
        }
        $owner = null;
        if (!empty($userId)) {
            $user = User::find($userId);
            if ($user->type == User::STAFF) {
                $owner = $user->owner;
            } else {
                $owner = $user;
            }
        }

        if (!empty($owner)) {
            if ($owner->number_zalo_mess <= 0) {
                return [];
            }
        }

        $client = new Client();
        $response = $client->post($url, [
            'json' => $postArr
        ]);
        $response = $response->getBody()->getContents();
        $response = json_decode($response, true);

        SendZaloLog::create([
            'user_id' => $userId,
            'hostel_id' => isset($data['hostel_id']) ? $data['hostel_id'] : null,
            'room_id' => isset($data['room_id']) ? $data['room_id'] : null,
            'customer_name' => $data['customer_name'],
            'customer_phone' => $data['phone'],
            'properties' => $postArr,
            'response' => $response
        ]);


        if (!empty($owner)) {
            if (is_array($response) && empty($response['error'])) {
                $owner->decrement('number_zalo_mess');
            }
        }


        return $response;
    }

    public static function getCurrentUserId()
    {
        $userId = null;
        if (auth('backend')->check()) {
            $userId = auth('backend')->user()->id;
        } else {
            $token = \request()->header('authorization');
            if ($token) {
                $user = \JWTAuth::parseToken()->toUser();
                if ($user) {
                    $userId = $user->id;
                }
            }
        }
        return $userId;
    }

    public static function getNumberRooms($room)
    {
        return [
            'used' => RenterRoom::query()->where('room_id', $room->id)->count()
        ];
    }


    public static function getSubCats($catId)
    {
        // dd($regions);
        $children = [];
        $regions = Category::query()->where('parent_id', $catId)->pluck('id')->toArray();
        foreach ($regions as $regionItem) {
            $gchildren = self::getSubCats($regionItem);
            if (!empty($gchildren)) {
                $children = array_merge($children, $gchildren);
            }
        }
        $children = array_merge($children, $regions);

        return $children;
    }

    public static function getTypeCpName(CollectSpend $item)
    {
        if ($item->type == CollectSpend::COLLECT) {
            return optional($item->typeCollect)->name;
        }

        return optional($item->typespend)->name;
    }

    public static function doCurl($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $data = json_decode(curl_exec($ch), true);
        curl_close($ch);

        return $data;
    }

    public static function getEwLatestRoom($room, $date = null)
    {
        $ew = ElectricWater::query()
            ->when(!empty($date), function ($q) use ($date) {
                $q->where('date_action', '<', $date->copy()->startOfMonth());
            }, function ($q) {
                $q->where('date_action', '<', Carbon::now()->copy()->startOfMonth());
            })
            ->orderBy('date_action', 'desc')
            ->where('room_id', $room->id)
            ->latest()
            ->first();
        if ($ew) {
            return [
                'e' => $ew->end_electric,
                'w' => $ew->end_water
            ];
        }

        return [
            'e' => 0,
            'w' => 0
        ];

    }

    public static function getEwLatestRoom4(Contract $contract, Carbon $date = null, HostelFee $fee)
    {
        $contractFees = ContractFee::query()->where('contract_id', $contract->id)->pluck('fee_id')->toArray();
        if (!in_array($fee->id, $contractFees)) {
            return [
                'start_e' => 0,
                'start_w' => 0,
                'end_e' => 0,
                'end_w' => 0
            ];
        }

        $ew = ElectricWater::query()
            ->orderBy('date_action', 'desc')
            ->where('contract_id', $contract->id)
            ->where('room_id', $contract->room_id)
            ->when(!empty($date), function ($q) use ($date) {
                $q->whereBetween('date_action', [
                    $date->copy()->startOfMonth()->startOfDay(),
                    $date->copy()->endOfMonth()->endOfDay(),
                ]);
            })
            ->latest()
            ->first();
        if ($ew) {
            return [
                'start_e' => $ew->start_electric,
                'start_w' => $ew->start_water,
                'end_e' => $ew->end_electric,
                'end_w' => $ew->end_water
            ];
        }

        $ewBefore = ElectricWater::query()
            ->where('room_id', $contract->room_id)
            ->where('contract_id', $contract->id)
            ->where('date_action', '<', $date->copy()->startOfMonth())
            ->orderBy('date_action', 'desc')
            ->first();

        if ($ewBefore) {
            return [
                'start_e' => $ewBefore->end_electric,
                'start_w' => $ewBefore->end_water,
                'end_e' => 0,
                'end_w' => 0
            ];
        }

        return [
            'start_e' => 0,
            'start_w' => 0,
            'end_e' => 0,
            'end_w' => 0
        ];

    }

    public static function getEwLatestRoom3($room, $date = null)
    {
        $ew = ElectricWater::query()
            ->orderBy('date_action', 'desc')
            ->where('room_id', $room->id)
            ->latest()
            ->first();
        if ($ew) {
            return [
                'e' => $ew->end_electric,
                'w' => $ew->end_water,
            ];
        }

        return [
            'e' => 0,
            'w' => 0
        ];

    }

    public static function getEwLatestRoom2($room, $date = null)
    {
        $ew = ElectricWater::query()
            ->when(!empty($date), function ($q) use ($date) {
                $q->where('date_action', '<', $date->copy()->startOfMonth());
            }, function ($q) {
                $q->where('date_action', '<', Carbon::now()->copy()->startOfMonth());
            })
            ->orderBy('date_action', 'desc')
            ->where('room_id', $room->id)
            ->latest()
            ->first();
        if ($ew) {
            return [
                'e' => $ew->end_electric,
                'w' => $ew->end_water
            ];
        }

        return null;

    }

    //Lấy theo HĐ
    public static function getEwLatestRoom5($room, $contract, $date = null)
    {
        $ew = ElectricWater::query()
            ->where('contract_id', $contract->id)
            ->when(!empty($date), function ($q) use ($date) {
                $q->where('date_action', '<', $date->copy()->startOfMonth());
            }, function ($q) {
                $q->where('date_action', '<', Carbon::now()->copy()->startOfMonth());
            })
            ->orderBy('date_action', 'desc')
            ->where('room_id', $room->id)
            ->latest()
            ->first();
        if ($ew) {
            return [
                'e' => $ew->end_electric,
                'w' => $ew->end_water
            ];
        }

        return null;

    }

    public static function getEwLatestContract($contract, $fee)
    {
        if (empty($fee)) {
            return 0;
        }

        $hostelFee = ContractFee::query()
            ->where('contract_id', $contract->id)
            ->where('fee_id', $fee->id)
            ->first();

        if ($hostelFee) {
            return $hostelFee->qty;
        }

        return 0;

    }

    public static function getLatestInvoice2($contractId)
    {
        $contract = Contract::find($contractId);
        if (!$contract) {
            return null;
        }

        $moneyInfo = MoneyInfo::query()->where('contract_id', $contractId)
            ->whereIn('type', [MoneyInfo::VOUCHER_CONTRACT, MoneyInfo::VOUCHER_ROOM_PRICE])
            ->orderBy('date_action', 'desc')
            ->first();

        if (!$moneyInfo) {
            return null;
        }

        $moneyDetail = MoneyDetail::where('money_info_id', $moneyInfo->id)
            ->orderBy('id', 'desc')
            ->first();
        if (!$moneyDetail) {
            return null;
        }

        return $moneyDetail->end_date;
    }

    public static function getLatestInvoice($contractId)
    {
        $contract = Contract::find($contractId);
        if (!$contract) {
            return null;
        }

        $moneyInfo = MoneyInfo::where('contract_id', $contractId)
            ->whereIn('type', [MoneyInfo::VOUCHER_CONTRACT, MoneyInfo::VOUCHER_ROOM_PRICE])
            ->orderBy('id', 'desc')
            ->where('pay', '>', 0)
            ->first();

        if (!$moneyInfo) {
            return null;
        }

        $moneyDetail = MoneyDetail::where('money_info_id', $moneyInfo->id)
            ->orderBy('id', 'desc')
            ->first();
        if (!$moneyDetail) {
            return null;
        }

        return $moneyDetail->end_date;
    }

    public static function getFacebookFromToken($code)
    {
        $app_id = env('FACEBOOK_CLIENT_ID');
        $secret = env('ACCOUNT_KIT_SECRET');
        $version = 'v1.1';

        $token_exchange_url = 'https://graph.accountkit.com/' . $version . '/access_token?' .
            'grant_type=authorization_code' .
            '&code=' . $code .
            "&access_token=AA|$app_id|$secret";
        $data = static::doCurl($token_exchange_url);
        if (isset($data['error'])) {
            return 'error';
        }
        $user_id = $data['id'];
        $user_access_token = $data['access_token'];
        $refresh_interval = $data['token_refresh_interval_sec'];

        $me_endpoint_url = 'https://graph.accountkit.com/' . $version . '/me?' .
            'access_token=' . $user_access_token;
        $data = static::doCurl($me_endpoint_url);
        $phone = isset($data['phone']) ? $data['phone']['number'] : '';
        $email = isset($data['email']) ? $data['email']['address'] : '';

        return $phone;
    }

    public static function getRemainRoom($room)
    {
        $paid = MoneyInfo::query()->where('room_id', $room->id)->sum('pay');
        $amount = MoneyInfo::query()->where('room_id', $room->id)->sum('amount');
        $discount = MoneyInfo::query()->where('room_id', $room->id)->sum('discount');

        return number_format($amount - $paid - $discount, 0, '.', '.');
    }

    public static function getRemainBed($room, $bed)
    {
        //dump($bed->id);
        $contract = Contract::query()->where('bed_id', $bed->id)->latest()->first();
        $paid = 0;
        $amount = 0;
        $discount = 0;
        if ($contract) {

            $paid = MoneyInfo::query()->where('contract_id', $contract->id)->sum('pay');
            $amount = MoneyInfo::query()->where('contract_id', $contract->id)->sum('amount');
            $discount = MoneyInfo::query()->where('contract_id', $contract->id)->sum('discount');
        }

        return number_format($amount - $paid - $discount, 0, '.', '.');
    }

    public static function updateHostelEmptyRooms($hostelId)
    {
        $hostel = Hostel::find($hostelId);
        if ($hostel) {
            $number = self::getNumberRoomsHostel($hostel);
            $hostel->number_empty_rooms = $number['number_empty_rooms'];
            $hostel->number_empty_room = $number['number_empty_rooms'];
            $hostel->number_rooms = $number['number_rooms'];
            $hostel->number_beds = $number['number_beds'];
            $hostel->save();
        }
    }

    public static function getNumberRoomsHostel(Hostel $hostel)
    {
        $numberRooms = Room::query()->where('hostel_id', $hostel->id)->count();
        if ($hostel->type_rent == Hostel::TYPE_RENT_ALL) {

            $usedRooms = RenterRoom::query()
                ->where('hostel_id', $hostel->id)
                ->whereNotNull('user_id')
                ->groupBy('room_id')
                ->get();
            $usedRooms = $usedRooms->count();
            $emptyRooms = $numberRooms - $usedRooms;
            $numberBeds = $numberRooms;
        } else {
            $numberBeds = Room::where('hostel_id', $hostel->id)->sum('max_renters');
            $usedBeds = RenterRoom::where('hostel_id', $hostel->id)->count();
            $emptyRooms = $numberBeds - $usedBeds;
            if ($emptyRooms < 0) {
                $emptyRooms = 0;
            }
        }

        return [
            'number_rooms' => $numberRooms,
            'number_empty_rooms' => $emptyRooms,
            'number_beds' => $numberBeds
        ];
    }

    public static function getNumberRoomsHostel2(Hostel $hostel)
    {
        $numberRooms = Room::query()->where('hostel_id', $hostel->id)->sum('max_renters');
        if ($hostel->type_rent == Hostel::TYPE_RENT_ALL) {

            $usedRooms = RenterRoom::query()->where('hostel_id', $hostel->id)
                ->whereNotNull('user_id')
                ->count();

            $emptyRooms = $numberRooms - $usedRooms;
        } else {
            $numberBeds = Room::query()->where('hostel_id', $hostel->id)->sum('max_renters');
            $numberRooms = $numberBeds;
            $usedBeds = RenterRoom::where('hostel_id', $hostel->id)->count();
            $usedRooms = $usedBeds;
            $emptyRooms = $numberBeds - $usedBeds;
            if ($emptyRooms < 0) {
                $emptyRooms = 0;
            }
        }

        return [
            'number_rooms' => $numberRooms,
            'number_empty_rooms' => $emptyRooms,
            'number_used_rooms' => $usedRooms
        ];
    }

    public static function generateHostelName($name)
    {
        $name = str_replace('Nhà trọ', '', $name);
        $name = str_replace('nhà trọ', '', $name);

        return $name;
    }

    public static function checkRoomType(Hostel $hostel)
    {
        return RoomType::where('hostel_id', $hostel->id)->count();
    }

    public static function checkFull(Room $room)
    {
        $maxRenters = $room->max_renters;
        $numberCurrentRenter = RenterRoom::where('room_id', $room->id)->count();

        if ($numberCurrentRenter == $maxRenters) {
            return true;
        }

        return false;
    }

    public static function updateMemberName($conversationId)
    {
        $conversation = Conversation::find($conversationId);
        if (!$conversation) {
            return;
        }
        $userIds = \DB::table('user_conversations')->where('conversation_id', $conversationId)
            ->pluck('user_id')->toArray();

        $userIds = array_unique($userIds);

        $users = User::whereIn('id', $userIds)->get();

        $nameArr = [];
        foreach ($users as $user) {
            $nameArr[] = $user->name_text;
        }

        $conversation->member_names = implode(',', $nameArr);
        $conversation->save();
    }

    public static function validateSecureHash($vnp_SecureHash, $inputDataItem)
    {
        $vnp_HashSecret = "HXSOAFEVNLPHABXZJQBWZYGJJIWTIJMC";
        $inputData = array();
        foreach ($inputDataItem as $key => $value) {
            if (substr($key, 0, 4) == "vnp_") {
                $inputData[$key] = $value;
            }
        }
        unset($inputData['vnp_SecureHashType']);
        unset($inputData['vnp_SecureHash']);
        ksort($inputData);
        $i = 0;
        $hashData = "";
        foreach ($inputData as $key => $value) {
            if ($i == 1) {
                $hashData = $hashData . '&' . $key . "=" . $value;
            } else {
                $hashData = $hashData . $key . "=" . $value;
                $i = 1;
            }
        }

        $secureHash = md5($vnp_HashSecret . $hashData);
        if ($secureHash === $vnp_SecureHash) {
            return true;
        }

        return false;
    }

    public static function ifEmptyRoom($room)
    {
        return RenterRoom::query()->where('room_id', $room->id)->count();
    }

    public static function imageStep($step, $position)
    {
        if ($step > 6 && $position == 6) {
            return '<span class="single-step__icon" style="border: 2px solid #FF5722"><img src="/frontend3/assets/img/step/' . $position . '_current.png" alt=""></span>';
        }

        if ($step == $position) {
            return '<span class="single-step__icon" style="border: 2px solid #FF5722"><img src="/frontend3/assets/img/step/' . $position . '_current.png" alt=""></span>';
        } else if ($step < $position) {
            return '<span class="single-step__icon"><img src="/frontend3/assets/img/step/' . $position . '_gray.png" alt=""></span>';

        }

        return '<span class="single-step__icon"><img src="/frontend3/assets/img/step/' . $position . '_passed.png" alt=""></span>';
    }

    public static function printMenu($menu)
    {
        $cnt = \App\Models\Category::where('parent_id', $menu->id)->orderBy('order', 'asc')->get();

        if ($cnt->count() > 0) {
            echo '<ol class="dd-list">';

            foreach ($cnt as $item) {

                echo ' <li class="dd-item" data-id="' . $item->id . '">';
                echo '<div class="dd-handle"> ' . $item->name . '</div>';

                self::printMenu($item);

                echo '</li>';
            }
            echo '</ol>';
        }

    }

    public static function printMenuCat($menu)
    {
        $cnt = \App\Models\Category::where('parent_id', $menu->id)->orderBy('order', 'asc')->get();

        if ($cnt->count() > 0) {
            echo '<ul>';

            foreach ($cnt as $item) {

                echo ' <li class="">';
                echo '<a class="cate-posts" href="#" data-href="' . url('/blog/danh-muc/' . $item->slug) . '"> ' . $item->name . '</a>';

                self::printMenu($item);

                echo '</li>';
            }
            echo '</ul>';
        }

    }

    public static function printSelect($menu = null, $delimiter = '', $selectedCategories = [])
    {
        if (empty($menu)) {
            $cnt = \App\Models\Category::where('parent_id', null)->orderBy('order', 'asc')->get();
        } else {
            $cnt = \App\Models\Category::where('parent_id', $menu->id)->orderBy('order', 'asc')->get();
        }
        if ($cnt->count() > 0) {

            foreach ($cnt as $item) {
                $message = '';

                if (in_array($item->id, $selectedCategories)) {
                    $message = 'selected';
                }

                echo '<option ' . $message . ' value="' . $item->id . '">' . $delimiter . $item->name . '</option>';
                $delimiter .= '----';
                self::printSelect($item, $delimiter, $selectedCategories);

            }

        }

    }

    public static function printSelectArr($menu = null, $delimiter = '', $selectedCategories = [])
    {
        if (empty($menu)) {
            $cnt = \App\Models\Category::where('parent_id', null)->orderBy('order', 'asc')->get();
        } else {
            $cnt = \App\Models\Category::where('parent_id', $menu->id)->orderBy('order', 'asc')->get();
        }
        if ($cnt->count() > 0) {


            foreach ($cnt as $item) {
                $message = '';

                if (in_array($item->id, $selectedCategories)) {
                    $message = 'selected';
                }

                echo '<option ' . $message . ' value="' . $item->id . '">' . $delimiter . $item->name . '</option>';
                $delimiter .= '----';
                self::printSelect($item, $delimiter, $selectedCategories);

            }
            echo '</ol>';
        }

    }

    public static function quickRandom($length = 20)
    {
        $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

        return substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
    }

    public static function checkDisplayType()
    {
        if (request()->has('type')) {
            $type = request()->get('type');

            if ($type == 'fb') {
                if (session()->has('fb_id')) {
                    return true;
                }
            }

            if ($type == 'gg') {
                if (session()->has('gg_id')) {
                    return true;
                }
            }
        }

        return false;
    }

    public static function remindCreateRoomJob($userId)
    {
        $job = (new RemindCreateRoom($userId))->delay(Carbon::now()->addDay(3));

        dispatch($job);
    }

    public static function getOld(User $user)
    {
        if (!empty($user->birthday)) {
            $old = Carbon::createFromFormat('d/m/Y', $user->birthday)->diffInYears(Carbon::now());

            return $old;
        }

        return null;
    }

    public static function getAmenitiesRoom($room)
    {
        $type = $room->type;
        if (!empty($type)) {
            $item = RoomType::find($type);
            if ($item) {
                $features = json_decode($item->features, true);
                if (is_array($features)) {
                    $amenities = Amenity::whereIn('id', $features)->get();

                    return $amenities;
                }
            }
        }

        return null;
    }

    public static function calculateStatusPaymentRoom($dateAction, $roomId, $item)
    {
        $startTime = \Carbon\Carbon::createFromFormat('d/m/Y', '01/' . $dateAction)->startOfMonth()->toDateString();
        $endTime = \Carbon\Carbon::createFromFormat('d/m/Y', '01/' . $dateAction)->endOfMonth()->toDateString();

        $moneyInfoItems = \App\Models\MoneyInfo::where('room_id', $roomId)->whereBetween('date_action', [
            $startTime,
            $endTime
        ])->get();

        $sum = 0;

        foreach ($moneyInfoItems as $moneyInfoItem) {


            $details = \App\Models\MoneyDetail::where('money_info_id', $moneyInfoItem->id)->get();
            $room = $moneyInfoItem->room;

            $dateAction = $item->date_action->format('m/Y');
            $pay = \App\Components\Functions::calculateAmountMonthForRoom($room, $dateAction)['pay'];

            foreach ($details as $detail) {
                $sum += $detail->amount;
            }

        }

        return [
            'pay' => $pay,
            'sum' => $sum,
        ];
    }

    public static function checkFavourite($userId, $hostelId)
    {
        $check = Wishlist::query()
            ->where('user_id', $userId)
            ->where('hostel_id', $hostelId)
            ->count();

        if ($check) {
            return true;
        }

        return false;
    }

    public static function checkRate($userId, $hostelId)
    {
        $check = HostelRating::query()
            ->where('user_id', $userId)
            ->where('hostel_id', $hostelId)
            ->count();

        if ($check) {
            return true;
        }

        return false;
    }

    public static function checkFavouriteSearchHostel($userId, $hostelId)
    {
        $check = Bookmark::query()
            ->where('user_id', $userId)
            ->where('hostel_id', $hostelId)
            ->count();

        if ($check) {
            return true;
        }

        return false;
    }

    public static function getHostelByUser($user)
    {
        if ($user->type == User::RENTER) {
            $item = RenterRoom::where('user_id', $user->id)->first();
            if ($item) {
                return $item->hostel_id;
            }
        }

        return null;
    }

    public static function br2nl($text)
    {
        $text = preg_replace('#<br[/\s]*>#si', "\n", $text);
        $text = trim($text);

        return $text;
    }

    public static function getProvinces()
    {
        return cache()->rememberForever('provinces', function () {
            return \DB::table('province')->orderBy('point', 'desc')->orderBy(\DB::raw('name COLLATE utf8_vietnamese_ci'))->get();
        });
    }

    public static function getDistrictName($districtid)
    {
        return optional(cache()->rememberForever('name-district' . $districtid, function () use ($districtid) {
            return \DB::table('district')->where('districtid', $districtid)->first();
        }));
    }

    public static function getProvinceName($provinceid)
    {
        return optional(cache()->rememberForever('name-province' . $provinceid, function () use ($provinceid) {
            return \DB::table('province')->where('provinceid', $provinceid)->first();
        }));
    }

    public static function getWardName($wardid)
    {
        return optional(cache()->rememberForever('name-ward-' . $wardid, function () use ($wardid) {
            return \DB::table('ward')->where('wardid', $wardid)->first();
        }));
    }

    public static function getMessageArr($message)
    {
        $sender = optional($message->sender);
        $attachments = optional($message->attachments);
        $hostels = optional($message->hostels);
        $requestConfirm = optional($message->requestConfirm);

        return [

            "id" => $message->id,
            'conversation_id' => $message->conversation_id,
            'display_text' => $message->display_text,
            "type" => $message->type,
            "created_at" => $message->created_at->format('d/m/Y H:i'),
            "sender" => [
                "id" => $sender->id,
                "name" => $sender->name_text,
                "phone" => $sender->phone,
                "avatar" => $sender->image
            ],
            "content" => $message->content,
            "attachments" => $attachments->map(function ($item) {
                return [
                    "id" => $item->id,
                    "type" => $item->type,
                    "thumbnail" => $item->thumbnail(),
                    "url" => $item->url(),
                    "duration" => $item->duration(),
                    "width" => $item->width(),
                    "height" => $item->height()
                ];
            }),
            "hostels" => $hostels->map(function ($item) {
                return [
                    "id" => $item->id,
                    "name" => $item->name,
                    "image" => $item->image,
                    "address" => $item->address,
                    'province_name' => optional($item->province)->name,
                    'district_name' => optional($item->district)->name,
                    'ward_name' => optional($item->ward)->name,
                    "desc" => $item->desc
                ];
            }),
            "location" => [
                "longitude" => $message->lng,
                "latitude" => $message->lat
            ],
            'preview' => [
                'url' => !empty($message->preview) ? isset($message->preview['url']) ? $message->preview['url'] : null : null,
                'title' => !empty($message->preview) ? isset($message->preview['title']) ? $message->preview['title'] : null : null,
                'desc' => !empty($message->preview) ? isset($message->preview['description']) ? $message->preview['description'] : null : null,
                'image' => !empty($message->preview) ? isset($message->preview['image']) ? $message->preview['image'] : null : null
            ],
            'transaction' => [
                'id' => $requestConfirm->id,
                'request_by' => $requestConfirm->request_by,
                'request_by_name' => optional($requestConfirm->userRequestBy)->name_text,
                'status' => $requestConfirm->status,
                'accepts' => $requestConfirm->accepts
            ]

        ];
    }

    public static function checkUserOnlineV2($userId, $conversationId)
    {
        $pusher = \PusherService::getClient();
        $channelName = 'presence-online-status-v2';
        $usersChannel = $pusher->get('/channels/' . $channelName . '/users');

        $userOnlineArr = [];
        if (isset($usersChannel['result'])) {
            if (isset($usersChannel['result']['users'])) {
                foreach ($usersChannel['result']['users'] as $item) {
                    $userIdOnline = $item['id'];
                    $userOnlineArr[] = $userIdOnline;
                }
            }
        }

        $channelConversationName = 'presence-read-conversation-v2-' . $conversationId;
        $usersChannelConversation = $pusher->get('/channels/' . $channelConversationName . '/users');
        $userOnlineConversationArr = [];
        if (isset($usersChannelConversation['result'])) {
            if (isset($usersChannelConversation['result']['users'])) {
                foreach ($usersChannelConversation['result']['users'] as $item2) {
                    $userIdOnlineConversation = $item2['id'];
                    $userOnlineConversationArr[] = $userIdOnlineConversation;
                }
            }
        }

        if (!in_array($userId, $userOnlineArr)) {
            return true;
        }

        return false;
    }

    public static function checkUserOnlineNoConversationV2($userId)
    {
        $pusher = \PusherService::getClient();
        $channelName = 'presence-online-status-v2';
        $usersChannel = $pusher->get('/channels/' . $channelName . '/users');

        $userOnlineArr = [];
        if (isset($usersChannel['result'])) {
            if (isset($usersChannel['result']['users'])) {
                foreach ($usersChannel['result']['users'] as $item) {
                    $userIdOnline = $item['id'];
                    $userOnlineArr[] = $userIdOnline;
                }
            }
        }


        if (!in_array($userId, $userOnlineArr)) {
            return true;
        }


        return false;
    }

    public static function checkUserOnlineConversationV2($userId, $conversationId)
    {
        $pusher = \PusherService::getClient();

        $channelConversationName = 'presence-read-conversation-v2-' . $conversationId;
        $usersChannelConversation = $pusher->get('/channels/' . $channelConversationName . '/users');
        $userOnlineConversationArr = [];
        if (isset($usersChannelConversation['result'])) {
            if (isset($usersChannelConversation['result']['users'])) {
                foreach ($usersChannelConversation['result']['users'] as $item2) {
                    $userIdOnlineConversation = $item2['id'];
                    $userOnlineConversationArr[] = $userIdOnlineConversation;
                }
            }
        }
        if (in_array($userId, $userOnlineConversationArr)) {
            return true;
        }

        return false;
    }

    public static function countBadge($accountId)
    {
        $countNotifications = \DB::table('notifications')->where('notifications.to_user', $accountId)
            ->where('notifications.is_read', Notification::NOT_READ)
            ->orderBy('notifications.created_at', 'desc')
            ->count();

        return $countNotifications;
    }

    public static function getUserIdForRoom($roomId)
    {
        $user = RenterRoom::where('room_id', $roomId)->where('is_head', 1)->first();
        if ($user) {
            return $user->account->id;
        } else {
            $user = RenterRoom::where('room_id', $roomId)->first();
            if ($user) {
                return $user->account->id;
            }
        }

        return null;

    }

    public static function getUser($userId)
    {
        $user = User::find($userId);

        return [
            'name' => $user->name,
            'image' => $user->image
        ];
    }

    public static function checkLikePost($postId)
    {
        $userId = auth('backend')->user()->id;

        return \DB::table('user_posts')->where('user_id', $userId)->where('social_post_id', $postId)->count();

    }

    public static function checkLikePostApi($postId, $userId)
    {
        return \DB::table('user_posts')->where('user_id', $userId)->where('social_post_id', $postId)->count();

    }

    public static function getFeeRoom($room)
    {

        $ew = self::getEwRoom($room);

        $retVal = [];

        $retVal[] = [
            'id' => $room->id,
            'name' => 'Tiền đặt cọc',
            'value' => $room->deposit,
            'type' => 'DEPOSIT'
        ];

        $retVal[] = [
            'id' => $room->id,
            'name' => 'Tiền phòng',
            'value' => $room->price,
            'type' => 'ROOM_PRICE'
        ];

        $retVal[] = [
            'id' => $room->id,
            'name' => 'Tiền điện',
            'value' => $ew['electric'],
            'type' => 'ELECTRIC'
        ];

        $retVal[] = [
            'id' => $room->id,
            'name' => 'Tiền nước',
            'value' => $ew['water'],
            'type' => 'WATER'
        ];

        $fees = RoomFee::where('room_id', $room->id)->get();

        foreach ($fees as $fee) {
            $retVal[] = [
                'id' => $fee->id,
                'name' => $fee->name,
                'value' => $fee->fee,
                'type' => 'FEE'
            ];
        }

        return $retVal;

    }

    public static function getStatusTextAttribute($type)
    {

        if ($type == Room::FULL) {
            return 'Đã đầy';
        } else if ($type == Room::AVAILABLE) {
            return 'Còn trống';
        } else if ($type == Room::NEED_MORE) {
            return 'Cần ở ghép';
        }

        return 'Chưa rõ';
    }

    public static function getCurrentRenter($room)
    {
        return User::find($room->current_renter);

    }

    public static function getNumberRenter($roomId)
    {
        return RenterRoom::where('room_id', $roomId)->count();
    }

    public static function calculateOweHostel($hostel, $startDate = null, $endDate = null)
    {
        $owes = MoneyInfo::where('hostel_id', $hostel->id)->where('remain', '>', 0);

        if (!empty($startDate) && !empty($endDate)) {
            $startDateParse = Carbon::createFromFormat('d/m/Y', '01/' . $startDate)->toDateString();
            $endDateParse = Carbon::createFromFormat('d/m/Y', '01/' . $endDate)->toDateString();

            $owes = $owes->whereBetween('date_action', [$startDateParse, $endDateParse]);
        }

        $sum = $owes->sum('remain');

        return $sum;
    }

    public static function getOweByHostel($hostel)
    {
        $owes = MoneyInfo::where('hostel_id', $hostel->id)->where('remain', '>', 0)->get();

        return $owes;
    }

    public static function getIncomeMonthByHostel($hostel)
    {

        $retVal = [];
        for ($i = 1; $i <= 12; $i++) {
            $spend = self::getSpendMonth($hostel, $i);
            $amount = self::getCollectMonth($hostel, $i);
            $itemVal['month'] = $i;
            $itemVal['amount'] = $amount;
            $itemVal['spend'] = $spend;
            $itemVal['profit'] = $amount - $spend;
            $retVal[] = $itemVal;
        }

        usort($retVal, 'self::sortByMonth');

        return $retVal;
    }

    public static function checkLastTime($lastTime, $collectToDate2)
    {
        $lastTimeObj = Carbon::createFromFormat('Y-m-d', $lastTime);
        if ($lastTimeObj->month == $collectToDate2->month) {
            return $collectToDate2->addMonth()->startOfMonth()->greaterThan($lastTime);
        }

        return $collectToDate2->startOfMonth()->greaterThan($lastTime);
    }

    public static function calculateMoneyInRange($contract, $startDate, $endDate)
    {
        $roomPrice = $contract->room_price;
        $diffDays = $startDate->diffInDays($endDate);

        return intval($roomPrice / 30 * $diffDays);
    }

    public static function calculatePeriod($startDate, $endDate)
    {
        $diffDays = $startDate->diffInDays($endDate);

        return round($diffDays / 30, 2);
    }

    public static function calculatePeriod2($startDate, $endDate)
    {
        $endFirst = clone $startDate;

        $le = ($startDate->diffInDays($endFirst->lastOfMonth()) + 1) / $startDate->daysInMonth;
        $diffMonths = $endDate->diffInMonths($startDate);

        return round($le + $diffMonths, 2);
    }

    public static function getIncomeMonthByOwner()
    {

        if (auth('backend')->user()->type == User::STAFF) {
            $hostelArrs = Functions::getHostelArrStaff();
        } else {
            $hostelArrs = Hostel::where('owner_id', auth('backend')->user()->id)->pluck('id')->toArray();
        }
        $retVal = [];
        for ($i = 1; $i <= 12; $i++) {
            $spend = self::getSpendMonthOwner($hostelArrs, $i);
            $amount = self::getCollectMonthOwner($hostelArrs, $i);
            $itemVal['month'] = $i;
            $itemVal['amount'] = $amount;
            $itemVal['spend'] = $spend;
            $itemVal['profit'] = $amount - $spend;
            $retVal[] = $itemVal;
        }

        usort($retVal, 'self::sortByMonth');


        return $retVal;
    }

    public static function getIncomeMonthByOwnerApi($userId)
    {

        $retVal = [];
        for ($i = 1; $i <= 12; $i++) {
            $spend = self::getSpendMonthOwnerApi($i, null, $userId);
            $amount = self::getCollectMonthOwnerApi($i, null, $userId);
            $itemVal['month'] = $i;
            $itemVal['amount'] = $amount;
            $itemVal['spend'] = $spend;
            $itemVal['profit'] = $amount - $spend;
            $retVal[] = $itemVal;
        }

        usort($retVal, 'self::sortByMonth');

        return $retVal;
    }

    public static function getIncomeMonthByHostelApi($hostel, $startDate = null, $endDate = null)
    {

        $startObj = Carbon::now()->firstOfYear();
        $endObj = Carbon::now()->endOfYear();

        $diffInMonths = $startObj->diffInMonths($endObj);

        if (!empty($startDate) && !empty($endDate)) {

            $startObj = Carbon::createFromFormat('d/m/Y', '01/' . $startDate);
            $endObj = Carbon::createFromFormat('d/m/Y', '01/' . $endDate);

            $diffInMonths = $startObj->diffInMonths($endObj);

        }


        $retVal = [];
        for ($start = 0; $start <= $diffInMonths; $start++) {

            $i = $startObj->month;
            $j = $startObj->year;
            $spend = self::getSpendMonth($hostel, $i, $j);
            $amount = self::getCollectMonth($hostel, $i, $j);
            $itemVal['doanh_thu'] = $amount;
            $itemVal['chi_phi'] = $spend;
            $itemVal['loi_nhuan'] = $amount - $spend;
            $itemVal['time'] = $i . '/' . $j;
            $retVal[] = $itemVal;
            $startObj = $startObj->addMonth(1);

        }

        usort($retVal, 'self::sortByTime');

        return $retVal;
    }

    public static function sortByTime($a, $b)
    {
        $a = $a['time'];
        $b = $b['time'];

        if ($a == $b) {
            return 0;
        }

        $a1 = Carbon::createFromFormat('d/m/Y', '01/' . $a);
        $b1 = Carbon::createFromFormat('d/m/Y', '01/' . $b);

        return ($a1->lessThan($b1)) ? -1 : 1;
    }

    public static function sortByMonth($a, $b)
    {
        $a = $a['month'];
        $b = $b['month'];

        if ($a == $b) {
            return 0;
        }


        return ($a < $b) ? -1 : 1;
    }

    public static function getSpendMonth($hostel, $month, $year = null)
    {
        if (empty($year)) {
            $year = Carbon::now()->year;
        }

        return StatisticLog::query()->where('hostel_id', $hostel->id)
            ->where('type', CollectSpend::SPEND)
            // ->has( 'collectSpend' )
            ->where('month', $month)
            ->where('year', $year)
            ->sum('amount');
    }

    public static function getCollectMonth($hostel, $month, $year = null)
    {
        if (empty($year)) {
            $year = Carbon::now()->year;
        }

        return StatisticLog::query()->where('hostel_id', $hostel->id)
            ->where('type', CollectSpend::COLLECT)
            // ->has( 'collectSpend' )
            ->where('month', $month)
            ->where('year', $year)
            ->sum('amount');
    }

    public static function getSpendMonthOwner($hostelArrs, $month, $year = null)
    {
        if (empty($year)) {
            $year = Carbon::now()->year;
        }
        $owner = auth('backend')->user();
        if ($owner->type == User::STAFF) {
            $owner = $owner->owner;
        }
        $ownerId = $owner->id;
        return StatisticLog::query()
            ->where(function ($q) use ($hostelArrs, $ownerId) {
                $q->orWhereIn('statistic_logs.hostel_id', $hostelArrs);
                $q->orWhere('statistic_logs.owner_id', $ownerId);
            })
            ->where('type', CollectSpend::SPEND)
            ->where('month', $month)
            ->where('year', $year)
            ->sum('amount');
    }

    public static function getSpendMonthOwnerApi($month, $year = null, $userId)
    {
        if (empty($year)) {
            $year = Carbon::now()->year;
        }
        $hostelArrs = Hostel::query()->where('owner_id', $userId)->pluck('id')->toArray();
        return StatisticLog::query()
            ->where(function ($q) {
                $q->orWhereNull('collect_spend_id');
                $q->orWhere(function ($q) {
                    $q->has('collectSpend');
                });
            })
            ->where(function ($q) use ($hostelArrs, $userId) {
                $q->orWhereIn('statistic_logs.hostel_id', $hostelArrs);
                $q->orWhere('statistic_logs.owner_id', $userId);
            })
            ->where('type', CollectSpend::SPEND)
            ->where('month', $month)
            ->where('year', $year)
            ->sum('amount');
    }

    public static function getCollectMonthOwner($hostelArrs, $month, $year = null)
    {
        if (empty($year)) {
            $year = Carbon::now()->year;
        }

        $date = Carbon::createFromFormat('d/m/Y', '01/' . $month . '/' . $year);
        $owner = auth('backend')->user();
        if ($owner->type == User::STAFF) {
            $owner = $owner->owner;
        }
        $ownerId = $owner->id;

        return StatisticLog::query()
            ->where(function ($q) {
                $q->orWhereNull('collect_spend_id');
                $q->orWhere(function ($q) {
                    $q->has('collectSpend');
                });
            })
            ->where(function ($q) use ($hostelArrs, $ownerId) {
                $q->orWhereIn('statistic_logs.hostel_id', $hostelArrs);
                $q->orWhere('statistic_logs.owner_id', $ownerId);
            })
            ->where('type', CollectSpend::COLLECT)
            ->where('month', $month)
            ->where('year', $year)
            ->sum('amount');
    }

    public static function getCollectMonthOwnerApi($month, $year = null, $userId)
    {
        if (empty($year)) {
            $year = Carbon::now()->year;
        }

        $hostelArrs = Hostel::query()->where('owner_id', $userId)->pluck('id')->toArray();

        return StatisticLog::query()
            ->where(function ($q) {
                $q->orWhereNull('collect_spend_id');
                $q->orWhere(function ($q) {
                    $q->has('collectSpend');
                });
            })
            ->where(function ($q) use ($hostelArrs, $userId) {
                $q->orWhereIn('statistic_logs.hostel_id', $hostelArrs);
                $q->orWhere('statistic_logs.owner_id', $userId);
            })
            ->where('type', CollectSpend::COLLECT)
            //->has( 'collectSpend' )
            ->where('month', $month)
            ->where('year', $year)
            ->sum('amount');
    }

    public static function getTotalRoomHostel($hostel, $startDate = null, $endDate = null)
    {
        $totalRooms = Room::query()->where('hostel_id', $hostel->id);

        if (!empty($startDate) && !empty($endDate)) {
            $startDateParse = Carbon::createFromFormat('d/m/Y', '01/' . $startDate)->toDateTimeString();
            $endDateParse = Carbon::createFromFormat('d/m/Y', '01/' . $endDate)->toDateTimeString();
            $totalRooms = $totalRooms->whereBetween('rooms.created_at', [$startDateParse, $endDateParse]);
        }

        $totalRooms = $totalRooms->count();

        $renters = Room::join('renter_rooms', 'rooms.id', '=', 'renter_rooms.room_id')
            ->where('rooms.hostel_id', $hostel->id);

        if (!empty($startDate) && !empty($endDate)) {
            $startDateParse = Carbon::createFromFormat('d/m/Y', '01/' . $startDate)->toDateTimeString();
            $endDateParse = Carbon::createFromFormat('d/m/Y', '01/' . $endDate)->toDateTimeString();
            $renters = $renters->whereBetween('renter_rooms.created_at', [$startDateParse, $endDateParse]);
        }

        $renters = $renters->count();

        $roomUsers = Room::join('renter_rooms', 'rooms.id', '=', 'renter_rooms.room_id')
            ->where('rooms.hostel_id', $hostel->id)->groupBy('renter_rooms.room_id');

        if (!empty($startDate) && !empty($endDate)) {
            $startDateParse = Carbon::createFromFormat('d/m/Y', '01/' . $startDate)->toDateTimeString();
            $endDateParse = Carbon::createFromFormat('d/m/Y', '01/' . $endDate)->toDateTimeString();
            $roomUsers = $roomUsers->whereBetween('renter_rooms.created_at', [$startDateParse, $endDateParse]);
        }

        $roomUsers = $roomUsers->get()->count();

        $numberKwh = ElectricWater::where('hostel_id', $hostel->id);
        $waters = ElectricWater::where('hostel_id', $hostel->id);

        if (!empty($startDate) && !empty($endDate)) {
            $startDateParse = Carbon::createFromFormat('d/m/Y', '01/' . $startDate)->toDateTimeString();
            $endDateParse = Carbon::createFromFormat('d/m/Y', '01/' . $endDate)->toDateTimeString();
            $numberKwh = $numberKwh->whereBetween('date_action', [$startDateParse, $endDateParse]);
            $waters = $waters->whereBetween('date_action', [$startDateParse, $endDateParse]);
        }

        $numberKwh = $numberKwh->sum('delta_electric');
        $waters = $waters->sum('delta_water');

        return [
            'total_rooms' => $totalRooms,
            'total_room_user' => $roomUsers,
            'renters' => $renters,
            'kwh' => $numberKwh,
            'waters' => $waters
        ];

    }

    public static function getEwRoom($room)
    {
        $check = RoomEw::where('room_id', $room->id)->first();

        if (!$check) {
            $hostel = $room->hostel;

            if ($hostel) {
                return [
                    'electric' => $hostel->electric_price,
                    'water' => $hostel->water_price
                ];
            }

            return [
                'electric' => 0,
                'water' => 0
            ];
        }

        return [
            'electric' => $check->price_electric,
            'water' => $check->price_water
        ];
    }


    public static function getRooms($rooms)
    {
        $data = json_decode($rooms, true);
        $retVal = '';
        if (is_array($data)) {
            foreach ($data as $item) {
                $room = Room::find($item);
                $retVal .= $room->name . ', ';
            }
        }

        return $retVal;
    }

    public static function getRoomsApi($rooms)
    {
        $data = json_decode($rooms, true);
        $retVal = [];
        if (is_array($data)) {
            foreach ($data as $item) {
                $room = Room::find($item);
                $retVal[] = $room->name;
            }
        }

        return $retVal;
    }

    public static function updateNumberEmptyRoom(Hostel $hostel)
    {
        $numberUsedRoom = RenterRoom::where('hostel_id', $hostel->id)
            ->whereNotNull('user_id')->pluck('room_id')->toArray();

        if (!empty($numberUsedRoom)) {
            $numberEmptyRoom = Room::where('hostel_id', $hostel->id)->whereNotIn('id', $numberUsedRoom)->count();

            $hostel->number_empty_room = $numberEmptyRoom;
            $hostel->number_empty_rooms = $numberEmptyRoom;
            $hostel->save();
        }
    }

    public static function numberToRomanRepresentation($number)
    {
        $map = array(
            'M' => 1000,
            'CM' => 900,
            'D' => 500,
            'CD' => 400,
            'C' => 100,
            'XC' => 90,
            'L' => 50,
            'XL' => 40,
            'X' => 10,
            'IX' => 9,
            'V' => 5,
            'IV' => 4,
            'I' => 1
        );
        $returnValue = '';
        while ($number > 0) {
            foreach ($map as $roman => $int) {
                if ($number >= $int) {
                    $number -= $int;
                    $returnValue .= $roman;
                    break;
                }
            }
        }

        return $returnValue;
    }

    public static function getHostelArrStaff()
    {
        if (!auth('backend')->check()) {
            return null;
        }

        if (auth('backend')->user()->type == User::STAFF) {
            $user = auth('backend')->user();
            $hostelArrs = $user->staffHostelArr->pluck('hostel_id')->toArray();

            if (empty($hostelArrs) || in_array(-1, $hostelArrs)) {
                return Hostel::where('owner_id', $user->staff_owner_id)->pluck('id')->toArray();
            }

            return $hostelArrs;
        }

        return null;
    }

    public static function getHostelArrStaffApi($user)
    {

        if ($user->type == User::STAFF) {
            $hostelArrs = $user->staffHostelArr->pluck('hostel_id')->toArray();

            if (empty($hostelArrs) || in_array(-1, $hostelArrs)) {
                return Hostel::where('owner_id', $user->staff_owner_id)->pluck('id')->toArray();
            }

            return $hostelArrs;
        }

        return null;
    }

    public static function _make_url_clickable_cb($matches)
    {
        $ret = '';
        $url = $matches[2];

        if (empty($url)) {
            return $matches[0];
        }
        // removed trailing [.,;:] from URL
        if (in_array(substr($url, -1), array('.', ',', ';', ':')) === true) {
            $ret = substr($url, -1);
            $url = substr($url, 0, strlen($url) - 1);
        }

        return $matches[1] . "<a target='_blank' href=\"$url\" rel=\"nofollow\">$url</a>" . $ret;
    }


    public static function _make_web_ftp_clickable_cb($matches)
    {
        $ret = '';
        $dest = $matches[2];
        $dest = 'http://' . $dest;

        if (empty($dest)) {
            return $matches[0];
        }
        // removed trailing [,;:] from URL
        if (in_array(substr($dest, -1), array('.', ',', ';', ':')) === true) {
            $ret = substr($dest, -1);
            $dest = substr($dest, 0, strlen($dest) - 1);
        }

        return $matches[1] . "<a href=\"$dest\" rel=\"nofollow\">$dest</a>" . $ret;
    }

    public static function _make_email_clickable_cb($matches)
    {
        $email = $matches[2] . '@' . $matches[3];

        return $matches[1] . "<a href=\"mailto:$email\">$email</a>";
    }

    public static function convertTextToLink($ret)
    {

        $ret = ' ' . $ret;
        // in testing, using arrays here was found to be faster
        $ret = preg_replace_callback('#([\s>])([\w]+?://[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', 'self::_make_url_clickable_cb', $ret);
        $ret = preg_replace_callback('#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', 'self::_make_web_ftp_clickable_cb', $ret);
        $ret = preg_replace_callback('#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', 'self::_make_email_clickable_cb', $ret);

        // this one is not in an array because we need it to run last, for cleanup of accidental links within links
        $ret = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>", $ret);
        $ret = trim($ret);

        return $ret;
    }

    public static function uploadImage($file, $old = null)
    {
        try {
            $filename = time() . uniqid() . '.' . $file->getClientOriginalExtension();

            $img = Image::make($file->getRealPath());
//            switch ($img->exif('Orientation')) {
//
//                case 2:
//                    $img->flip();
//                    break;
//
//                case 3:
//                    $img->rotate(180);
//                    break;
//
//                case 4:
//                    $img->rotate(180)->flip();
//                    break;
//
//                case 5:
//                    $img->rotate(270)->flip();
//                    break;
//
//                case 6:
//                    $img->rotate(270);
//                    break;
//
//                case 7:
//                    $img->rotate(90)->flip();
//                    break;
//
//                case 8:
//                    $img->rotate(90);
//                    break;
//            }

//			if ( $img->height() > 1024 ) {
//				$img = $img->resize( null, $img->height() / 2, function ( $constraint ) {
//					$constraint->aspectRatio();
//				} );
//			}
            $img = $img->save(public_path('files/' . $filename));

            if ($old) {
                @unlink(public_path('files/' . $old));
            }

            return $filename;
        } catch (Exception $exception) {
            \Log::info($exception->getTraceAsString());

            return null;
        }
    }

    public static function createEmailQueue($data = [])
    {
        if (!empty($data)) {
            \DB::table('mail_queues')->insert($data);
        }
    }

    public static function printCategory($category)
    {
        $cnt = \App\Models\Category::where('parent_id', $category->id)->orderBy('order', 'asc')->get();

        if ($cnt->count() > 0) {
            echo '<ol class="dd-list">';

            foreach ($cnt as $item) {

                echo ' <li class="dd-item" data-id="' . $item->id . '">';
                echo '<div class="dd-handle"> ' . $item->name . '</div>';

                self::printCategory($item);

                echo '</li>';
            }
            echo '</ol>';
        }

    }

    public static function printCategoryPost($category)
    {
        $cnt = \App\Models\CategoryPost::publish()->where('parent_id', $category->id)->orderBy('order', 'asc')->get();

        if ($cnt->count() > 0) {
            echo '<ol class="dd-list">';

            foreach ($cnt as $item) {

                echo ' <li class="dd-item" data-id="' . $item->id . '">';
                echo '<div class="dd-handle"> ' . $item->name . '</div>';

                self::printCategoryPost($item);

                echo '</li>';
            }
            echo '</ol>';
        }

    }

    public static function printCategoryFrontend($category)
    {
        $cnt = \App\Models\Category::publish()->where('parent_id', $category->id)->orderBy('order', 'asc')->get();

        if ($cnt->count() > 0) {
            echo '<ul class="submenu">';


            foreach ($cnt as $item) {
                echo '<li >';
                echo '<a data-id="' . $item->id . '" href = "' . url('khoa-hoc/danh-muc/' . str_slug($item->name) . '-' . $item->id) . '" >' . $item->name . '</a >';
                self::printCategoryFrontend($item);
                echo '</li>';

            }
            echo '</ul >';
        }
    }

    public static function listHostelTransformer($items, $userId)
    {
        $arr = [];
        foreach ($items as $item) {
            $id = $item->id;
            $name = $item->name;
            $address = $item->address;
            $verified = $item->status_confirm;
            $favorite = !empty($userId) ? Functions::checkFavourite($userId, $item->id) : false;
            $price = Functions::getPriceHostelFrontend3($item);
            $minPrice = $price['smallest'];
            $maxPrice = $price['greatest'];
            $totalRoom = Room::query()->where('hostel_id', $item->id)->count();
            $emptyRoom = Functions::getEmptyRoomHostel($item);
            $area = Functions::getAreaHostelFrontend3($item);
            $minArea = $area['smallest'];
            $maxArea = $area['greatest'];
            $lat = $item->lat;
            $lng = $item->lng;
            $highlightAmenities = Functions::getAmenitiesHostel($item);


            $arr[] = [
                'id' => $id,
                'name' => $name,
                'address' => $address,
                'verified' => $verified,
                'favorite' => $favorite,
                'min_price' => $minPrice,
                'max_price' => $maxPrice,
                'empty_room_count' => $emptyRoom,
                'total_room' => $totalRoom,
                'min_area' => $minArea,
                'max_area' => $maxArea,
                'lat' => $lat,
                'lng' => $lng,
                'highlight_amenities' => $highlightAmenities,
                'background_image' => $item->image
            ];


        }

        return $arr;
    }

    public static function createWarehouseIfEmpty($userId)
    {
        $check = Warehouse::where('owner_id', $userId)->count();
        if ($check == 0) {
            Warehouse::create([
                'owner_id' => $userId,
                'name' => 'Kho tổng'
            ]);
        }
    }


    public static function sendNotificationFacebookLogin($facebookId, $token, $after = null, $friends = [])
    {
        $url = 'https://graph.facebook.com/v2.12/' . $facebookId . '/friends?access_token=' . $token;
        if (!empty($after)) {
            $url = 'https://graph.facebook.com/v2.12/' . $facebookId . '/friends?access_token=' . $token . '&after=' . $after;
        }
        $json = file_get_contents($url);
        $data = json_decode($json, true);

        if (isset($data['data'])) {
            if (is_array($data['data'])) {
                $items = $data['data'];
                foreach ($items as $item) {
                    $friends[] = $item['id'];
                }
            }
        }

        if (isset($data['paging']['cursors']["after"])) {
            self::sendNotificationFacebookLogin($facebookId, $token, $data['paging']['cursors']["after"], $friends);
        }

        return $friends;

    }

    public static function uploadVideo($file, $old = null)
    {
        $filename = time() . uniqid() . '.' . $file->getClientOriginalExtension();
        $file->move(public_path('videos/'), $filename);

        if ($old) {
            @unlink(public_path('videos/' . $old));
        }

        return $filename;
    }

    public static function uploadFile(UploadedFile $file, $old = null)
    {
        $filename = time() . uniqid() . '.' . $file->getClientOriginalExtension();
        if (str_contains($file->getClientOriginalName(), 'php')) {
            return null;
        }
        if (str_contains($file->getClientOriginalExtension(), 'php')) {
            return null;
        }
        $file->move(public_path('files/'), $filename);

        if ($old) {
            @unlink(public_path('files/' . $old));
        }

        return $filename;
    }


    public static function uploadFileStorage($file, $old = null)
    {
        $filename = time() . uniqid() . '.' . $file->getClientOriginalExtension();
        $file->move(storage_path('files/'), $filename);

        if ($old) {
            @unlink(storage_path('files/' . $old));
        }

        return $filename;
    }

    public static function filterInputNumber($num)
    {
        $num = trim($num);
        $num = str_replace('.', '', $num);
        $num = str_replace(',', '', $num);
        if (is_string($num) && !empty($num)) {
            return $num;
        }
        $num = preg_replace('/\s+/', '', $num);
        if (empty($num)) {
            return 0;
        }


        $num = (int)$num;
        if (!is_numeric($num)) {
            return 0;
        }

        return $num;
    }

    public static function filterFloatNumber($num)
    {
        $num = trim($num);
        $num = str_replace(',', '.', $num);
        $num = preg_replace('/\s+/', '', $num);
        if (empty($num)) {
            return 0;
        }

        $num = (float)$num;
        if (!is_numeric($num)) {
            return 0;
        }

        return $num;
    }

    public static function filterTextNumber($num)
    {
        $num = trim($num);
        $num = str_replace('.', '', $num);
        $num = str_replace(',', '', $num);
        if (is_string($num)) {
            return $num;
        }
        $num = preg_replace('/\s+/', '', $num);

        return (string)$num;
    }

    public static function getDateTimeRange2($timeRange)
    {
        $result = [];
        switch ($timeRange) {
            case 'yesterday':
                $result['start_time'] = Carbon::now()->subDay(1)->format('d/m/Y');
                $result['end_time'] = Carbon::now()->subDay(1)->format('d/m/Y');
                break;

            case 'today':
                $result['start_time'] = Carbon::now()->format('d/m/Y');
                $result['end_time'] = Carbon::now()->format('d/m/Y');
                break;

            case 'week':
                $result['start_time'] = Carbon::now()->startOfWeek()->format('d/m/Y');
                $result['end_time'] = Carbon::now()->format('d/m/Y');
                break;

            case 'last_7_days':
                $result['start_time'] = Carbon::now()->subDay(7)->format('d/m/Y');
                $result['end_time'] = Carbon::now()->format('d/m/Y');
                break;

            case 'last_week':
                $result['end_time'] = Carbon::now()->subWeek(1)->endOfWeek()->format('d/m/Y');
                $result['start_time'] = Carbon::now()->subWeek(1)->startOfWeek()->format('d/m/Y');
                break;

            case 'month':
                $result['start_time'] = Carbon::now()->startOfMonth()->format('d/m/Y');
                $result['end_time'] = Carbon::now()->format('d/m/Y');
                break;

            case 'last_30_days':
                $result['start_time'] = Carbon::now()->subDay(30)->format('d/m/Y');
                $result['end_time'] = Carbon::now()->format('d/m/Y');
                break;

            case 'last_month':
                $result['start_time'] = Carbon::now()->subMonth(1)->startOfMonth()->format('d/m/Y');
                $result['end_time'] = Carbon::now()->subMonth(1)->endOfMonth()->format('d/m/Y');
                break;

            default:
                $result['start_time'] = null;
                $result['end_time'] = null;
                break;
        }

        return $result;
    }

    public static function calculateAmountMonthForRoom($room, $dateAction)
    {
        if (empty($dateAction)) {
            $startDate = Carbon::now()->startOfMonth()->toDateString();
            $endDate = Carbon::now()->endOfMonth()->toDateString();
        } else {
            $startDate = Carbon::createFromFormat('d/m/Y', '01/' . $dateAction)->startOfMonth()->toDateString();
            $endDate = Carbon::createFromFormat('d/m/Y', '01/' . $dateAction)->endOfMonth()->toDateString();
        }
        $fee = RoomFee::where('room_id', $room->id)->sum('fee');
        $extras = Extra::where('room_id', $room->id)->where('date_action', '>=', $startDate)->where('date_action', '<=', $endDate)
            ->sum('amount');

        $pay = Extra::where('room_id', $room->id)->where('date_action', '>=', $startDate)->where('date_action', '<=', $endDate)
            ->sum('pay');

        $pay2 = Transaction::where('room_id', $room->id)->where('date_action', '>=', $startDate)
            ->where('date_action', '<=', $endDate)
            ->sum('amount');

        $ewAmount = 0;

        $ew = ElectricWater::where('room_id', $room->id)->where('date_action', '>=', $startDate)->where('date_action', '<=', $endDate)->first();

        if ($ew) {
            $ewPrice = Functions::getEwRoom($room);

            $deltaWater = $ew->delta_water;
            $deltaElectric = $ew->delta_electric;

            $ewAmountElectric = $deltaElectric * $ewPrice['electric'];
            $ewAmountWater = $deltaWater * $ewPrice['water'];

            $ewAmount = $ewAmountElectric + $ewAmountWater;
        }

        $priceRoom = $room->price;

        return [
            'amount' => $fee + $extras + $ewAmount + $priceRoom,
            'pay' => $pay + $pay2
        ];
    }

    public static function checkAddRenter(Room $room)
    {
        $hostel = $room->hostel;
        if ($hostel->type_rent == Hostel::TYPE_RENT_ALL) {
            $check = Contract::query()
                ->has('renter')
                ->where('status', '<>', Contract::EXPIRE)
                ->where('status', '<>', Contract::LIQUIDATED)
                ->where('room_id', $room->id)
                ->count();
            if ($check) {
                return 1;
            } else {
                $check2 = Contract::query()->where('status', '<>', Contract::LIQUIDATED)
                    ->has('renter')
                    ->where('room_id', $room->id)
                    ->where('end_date', '<', Carbon::now()->toDateString())
                    ->count();

                if ($check2) {
                    return 2;
                }
            }
        }

        return 3;
    }

    public static function checkContractRoom(Room $room)
    {
        return Contract::where('room_id', $room->id)
            ->where('status', Contract::VALIDATED)->count();
    }

    public static function checkReserve(Room $room)
    {
        return RoomReservation::query()->where('room_id', $room->id)->count();
    }

    public static function calculateAmountForOrder($moneyInfoId)
    {
        $amount = 0;
        $moneyInfo = MoneyInfo::find($moneyInfoId);
        if ($moneyInfo) {
            $amount = $moneyInfo->amount;
        }
        $pay = CollectSpend::query()->where('money_info_id', $moneyInfoId)
            ->where('type', CollectSpend::COLLECT)
            ->sum('amount');

        return [
            'amount' => $amount,
            'pay' => $pay
        ];
    }

    public static function getPriceHostelArr($hostels)
    {
        if (!is_array($hostels)) {
            return null;
        }

        $smallest = Room::query()->whereIn('hostel_id', $hostels)->orderBy('price', 'asc')->first();
        $greatest = Room::query()->whereIn('hostel_id', $hostels)->orderBy('price', 'desc')->first();

        if (!$smallest || !$greatest) {
            return null;
        }

        return [
            'smallest' => $smallest->price,
            'greatest' => $greatest->price,
        ];
    }

    public static function getPriceHostel(Hostel $hostel)
    {
        $rooms = Room::query()->where('hostel_id', $hostel->id);

        if ($rooms->count()) {
            $smallest = Room::query()->where('hostel_id', $hostel->id)->orderBy('price', 'asc')->first();
            $greatest = Room::query()->where('hostel_id', $hostel->id)->orderBy('price', 'desc')->first();

            if (!$smallest || !$greatest) {
                return null;
            }

            if ($smallest->price == $greatest->price) {
                return $smallest->price;
            } else {


                return 'Từ ' . self::formatPriceText($smallest->price) . ' đến ' . self::formatPriceText($greatest->price) . ' triệu';
            }
        }

        return null;
    }

    public static function getPriceHostelForFinding(Hostel $hostel)
    {
        $rooms = Room::query()->where('hostel_id', $hostel->id)->count();

        if ($rooms > 0) {
            $smallest = Room::query()->where('hostel_id', $hostel->id)->orderBy('price', 'asc')->first();
            $greatest = Room::query()->where('hostel_id', $hostel->id)->orderBy('price', 'desc')->first();

            $smallestPrice = 0;
            $greatestPrice = 0;
            if ($smallest) {
                $smallestPrice = $smallest->price;
            }

            if ($greatest) {
                $greatestPrice = $greatest->price;
            }

            return [
                'smallest' => $smallestPrice,
                'greatest' => $greatestPrice
            ];
        }

        return null;
    }


    public static function getPriceHostelFrontend3(Hostel $hostel)
    {
        $roomsCount = Room::query()->where('hostel_id', $hostel->id)->count();

        if ($roomsCount > 0) {

            $usedRoom = RenterRoom::query()
                ->where('hostel_id', $hostel->id)
                ->whereNotNull('user_id')
                ->pluck('room_id')
                ->toArray();

            if (!empty($usedRoom)) {

                $smallest = Room::query()->where('hostel_id', $hostel->id)->whereNotIn('id', $usedRoom)->orderBy('price', 'asc')->first();
                $greatest = Room::query()->where('hostel_id', $hostel->id)->whereNotIn('id', $usedRoom)->orderBy('price', 'desc')->first();
            } else {
                $smallest = Room::query()->where('hostel_id', $hostel->id)->orderBy('price', 'asc')->first();
                $greatest = Room::query()->where('hostel_id', $hostel->id)->orderBy('price', 'desc')->first();
            }

            $smallestPrice = 0;
            $greatestPrice = 0;
            if ($smallest) {
                $smallestPrice = $smallest->price;
            }

            if ($greatest) {
                $greatestPrice = $greatest->price;
            }

            return [
                'smallest' => $smallestPrice,
                'greatest' => $greatestPrice
            ];
        }

        return null;
    }


    public static function getAreaHostelFrontend3(Hostel $hostel)
    {
        $rooms = Room::where('hostel_id', $hostel->id);

        if ($rooms->count()) {

            $usedRoom = RenterRoom::where('hostel_id', $hostel->id)->whereNotNull('user_id')->pluck('room_id')->toArray();

            if (!empty($usedRoom)) {

                $smallest = Room::where('hostel_id', $hostel->id)->whereNotIn('id', $usedRoom)->orderBy('size', 'asc')->first();
                $greatest = Room::where('hostel_id', $hostel->id)->whereNotIn('id', $usedRoom)->orderBy('size', 'desc')->first();
            } else {
                $smallest = Room::where('hostel_id', $hostel->id)->orderBy('size', 'asc')->first();
                $greatest = Room::where('hostel_id', $hostel->id)->orderBy('size', 'desc')->first();
            }

            $smallestSize = 0;
            $greatestSize = 0;
            if ($smallest) {
                $smallestSize = $smallest->size;
            }

            if ($greatest) {
                $greatestSize = $greatest->size;
            }

            return [
                'smallest' => $smallestSize,
                'greatest' => $greatestSize
            ];
        }

        return null;
    }

    public static function convertFileSize($bytes, $decimals = 2)
    {
        if (!is_numeric($bytes)) {
            return '0B';
        }
        $size = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
        $factor = floor((strlen($bytes) - 1) / 3);

        return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$size[$factor];
    }

    public static function hostelTransform(Hostel $hostel)
    {
        if (!$hostel) {
            return null;
        }
        $images = json_decode($hostel->images, true);

        $imgArr = [];
        foreach ($images as $image) {
            $imgArr[] = '/files/' . $image;
        }

        $hostel->images = $imgArr;

        if (!empty($hostel->province_id)) {
            $province = Functions::getProvinceName($hostel->province_id);

            if ($province) {
                $hostel->province_name = $province->name;
            }
        }

        if (!empty($hostel->district_id)) {
            $district = Functions::getDistrictName($hostel->district_id);

            if ($district) {
                $hostel->district_name = $district->name;
            }
        }

        if (!empty($hostel->ward_id)) {
            $ward = Functions::getWardName($hostel->ward_id);

            if ($ward) {
                $hostel->ward_name = $ward->name;
            }
        }

        $hostel->desc = nl2br($hostel->desc);

        $amenities = Functions::getAmenitiesHostel($hostel);
        $policies = Functions::getPoliciesHostel($hostel);

        $hostel->amenities = $amenities;
        $hostel->policies = $policies;

        return $hostel;
    }

    public static function getAmenitiesHostel(Hostel $hostel)
    {
        $amenities = Amenity::whereIn('user_id', [0, $hostel->owner_id])
            ->where('type', Amenity::AMENITY)
            ->get();

        $retVal = [];

        foreach ($amenities as $amenity) {

            $isCheck = false;

            $hostelAmenity = \DB::table('hostel_amenities')->where('amenities_id', $amenity->id)
                ->where('hostel_id', $hostel->id)->count();

            if ($hostelAmenity) {
                $isCheck = true;
            }

            $retVal[] = [
                'is_check' => $isCheck,
                'id' => $amenity->id,
                'name' => $amenity->name,
                'image' => '/files/' . $amenity->mobile_image
            ];
        }

        return $retVal;
    }

    public static function getPoliciesHostel(Hostel $hostel)
    {
        $amenities = Amenity::whereIn('user_id', [0, $hostel->owner_id])
            ->where('type', Amenity::POLICY)
            ->get();

        $retVal = [];

        foreach ($amenities as $amenity) {
            $isCheck = false;

            $hostelAmenity = \DB::table('hostel_policies')->where('policy_id', $amenity->id)
                ->where('hostel_id', $hostel->id)->count();

            if ($hostelAmenity) {
                $isCheck = true;
            }

            $retVal[] = [
                'is_check' => $isCheck,
                'id' => $amenity->id,
                'name' => $amenity->name,
                'image' => '/files/' . $amenity->mobile_image
            ];
        }

        return $retVal;
    }

    public static function checkDateAvailable($room)
    {
//        dump($room->date_available);
        $checkRenter = RenterRoom::where('room_id', $room->id)
            ->count();

        if ($checkRenter == 0) {
            if (empty(trim($room->date_available))) {
                return 'Có thể chuyển ngay';
            }

            if (!empty(trim($room->date_available))) {
                //dump($room->date_available);
                return Carbon::createFromFormat('Y-m-d', trim($room->date_available))->format('d/m/Y');
            }

            return 'Có thể chuyển ngay';
        }

        return 'Không thể chuyển đến';
    }

    public static function calculateNumberRenter($room)
    {
        return RenterRoom::query()->where('room_id', $room->id)->count();
    }

    public static function getEmptyRoomHostel(Hostel $hostel)
    {
        $usedRoom = RenterRoom::query()->where('hostel_id', $hostel->id)->whereNotNull('user_id')->pluck('room_id')->toArray();

        return Room::query()->where('hostel_id', $hostel->id)->whereNotIn('id', $usedRoom)->count();
    }

    public static function getRenterHostel(Hostel $hostel)
    {
        return RenterRoom::query()->where('hostel_id', $hostel->id)->count();
    }

    public static function getEmptyRoomHostelByFloor(Hostel $hostel, $floor)
    {
        $usedRoom = RenterRoom::query()->where('hostel_id', $hostel->id)->whereNotNull('user_id')->pluck('room_id')->toArray();

        return Room::query()->where('hostel_id', $hostel->id)->where('floor', $floor)->whereNotIn('id', $usedRoom)->count();
    }

    public static function getEmptyRoomHostelByBlockName(Hostel $hostel, $blockName)
    {
        if ($hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
            $numberBeds = Room::where('hostel_id', $hostel->id)
                ->where('block_name', $blockName)
                ->sum('max_renters');
            $roomArrs = Room::where('hostel_id', $hostel->id)
                ->where('block_name', $blockName)
                ->pluck('id')
                ->toArray();
            $usedBeds = RenterRoom::where('hostel_id', $hostel->id)
                ->whereIn('room_id', $roomArrs)
                ->count();

            $remain = $numberBeds - $usedBeds;
            if ($remain < 0) {
                $remain = 0;
            }

            return $remain;
        } else {

            $usedRoom = RenterRoom::where('hostel_id', $hostel->id)
                ->whereNotNull('user_id')
                ->groupBy('room_id')
                ->pluck('room_id')
                ->toArray();

            return Room::where('hostel_id', $hostel->id)
                ->where('block_name', $blockName)
                ->whereNotIn('id', $usedRoom)->count();
        }
    }

    public static function getRoomHostelByFloor(Hostel $hostel, $floor)
    {
        if ($hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
            return Room::where('hostel_id', $hostel->id)
                ->where('floor', $floor)
                ->sum('max_renters');
        }

        return Room::where('hostel_id', $hostel->id)->where('floor', $floor)->count();
    }

    public static function getRoomHostelByBlockName(Hostel $hostel, $blockName)
    {
        return Room::where('hostel_id', $hostel->id)->where('block_name', $blockName)->count();
    }

    public static function formatPriceText($number)
    {
        // return $number;
        //$price = round($number / 1000000);
        $value = $number / 1000000;

        return rtrim(rtrim((string)number_format($value, 1, ".", ""), "0"), ".");
    }

    public static function shortNumber($number)
    {
        if ($number >= 10000000) {
            return round($number / 1000000, 1) . 'tr';
        }

        if ($number < 1000000) {
            return round($number / 1000, 1) . ' ngàn';
        }
    }

    public static function getPrice($price)
    {
        $retVal = [];
        switch ($price) {
            case 1:
                $retVal = [
                    'start' => 1,
                    'end' => 2000000
                ];
                break;


            case 2:
                $retVal = [
                    'start' => 1000000,
                    'end' => 2000000
                ];
                break;

            case 3:
                $retVal = [
                    'start' => 2000000,
                    'end' => 3000000
                ];
                break;

            case 4:
                return [
                    'start' => 3000000,
                    'end' => 5000000
                ];
                break;

            case 5:
                $retVal = [
                    'start' => 5000000,
                    'end' => 7000000
                ];
                break;

            case 6:
                $retVal = [
                    'start' => 7000000,
                    'end' => 10000000
                ];
                break;

            case 7:
                $retVal = [
                    'start' => 10000000,
                    'end' => 15000000
                ];
                break;

            case 8:
                $retVal = [
                    'start' => 0,
                    'end' => 2000000
                ];
                break;

            case 9:
                $retVal = [
                    'start' => 0,
                    'end' => 2000000
                ];
                break;

            default:
                $retVal = [
                    'start' => null,
                    'end' => null
                ];
                break;

        }

        return $retVal;
    }

    public static function getSize($size)
    {
        $retVal = [];
        switch ($size) {
            case 1:
                $retVal = [
                    'start' => 0,
                    'end' => 20
                ];
                break;


            case 2:
                $retVal = [
                    'start' => 20,
                    'end' => 30
                ];
                break;

            case 3:
                $retVal = [
                    'start' => 30,
                    'end' => 50
                ];
                break;

            case 4:
                return [
                    'start' => 50,
                    'end' => 60
                ];
                break;

            case 5:
                $retVal = [
                    'start' => 60,
                    'end' => 70
                ];
                break;

            case 6:
                $retVal = [
                    'start' => 70,
                    'end' => 80
                ];
                break;

            case 7:
                $retVal = [
                    'start' => 80,
                    'end' => 90
                ];
                break;

            case 8:
                $retVal = [
                    'start' => 90,
                    'end' => 100
                ];
                break;

            default:
                $retVal = [
                    'start' => 0,
                    'end' => 0
                ];
                break;

        }

        return $retVal;
    }

    public static function getNumber($number)
    {
        $number = (int)$number;
        if ($number < 10 && $number > 0) {
            return '0' . $number;
        }

        return $number;
    }

    public static function checkDisplayHostel($hostel)
    {
        $cntRoom = Room::where('hostel_id')->count();
        if ($cntRoom == 0) {
            return false;
        }


    }

    public static function geocode($query = null)
    {
        $query = urlencode($query);
        try {
            // $url = 'https://maps.googleapis.com/maps/api/geocode/json?address=' . $query . '&key=AIzaSyCp_rmACoTyFXA_hLjPRMiJKhoJx4_oVHc';


            $url = 'https://maps.googleapis.com/maps/api/geocode/json?address=' . $query . '&key=AIzaSyAhDKdnaIyBJXh1Mb6DDzAc6ksINmUIOZw';

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_PROXYPORT, 3128);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
            $json = curl_exec($ch);
            curl_close($ch);

            $data = json_decode($json, true);

            $lat = null;
            $lng = null;
            if (isset($data['results'][0])) {
                $result = $data['results'][0];

                $lat = $result['geometry']['location']['lat'];
                $lng = $result['geometry']['location']['lng'];
            }

            $itemArr = ['lat' => $lat, 'lng' => $lng];


        } catch (Exception $exception) {
            return [
                'lat' => null,
                'lng' => null
            ];
        }

        return $itemArr;
    }

    public static function calculateElectricAmount($amount, Room $room, $type, $feeId = null)
    {
        $hostel = $room->hostel;

        $res = 0;
        $quota = null;
        if ($type == HostelFee::ELECTRIC) {

            if (!empty($feeId)) {
                $quota = ElectricQuota::where('hostel_id', $hostel->id)->where('fee_id', $feeId)->first();
                if (!$quota) {
                    $quota = ElectricQuota::where('hostel_id', $hostel->id)->first();
                }
            } else {
                $quota = ElectricQuota::where('hostel_id', $hostel->id)->first();
            }
        } else if ($type == HostelFee::WATER) {
            if (!empty($feeId)) {
                $quota = WaterQuota::where('hostel_id', $hostel->id)->where('fee_id', $feeId)->first();
                if (!$quota) {
                    $quota = WaterQuota::where('hostel_id', $hostel->id)->first();
                }
            } else {
                $quota = WaterQuota::where('hostel_id', $hostel->id)->first();
            }
        }

        if (!empty($quota)) {
            if ($amount > 0 && $amount <= $quota->quota_1) {
                $res = $amount * $quota->price_quota_1;
            }

            if ($amount > $quota->quota_1 && $amount <= ($quota->quota_2 + $quota->quota_1)) {
                $res = $quota->quota_1 * $quota->price_quota_1 + ($amount - $quota->quota_1) * $quota->price_quota_2;
            }

            if ($amount > ($quota->quota_2 + $quota->quota_1) && $amount <= ($quota->quota_3 + $quota->quota_2 + $quota->quota_1)) {
                $res = $quota->quota_1 * $quota->price_quota_1
                    + $quota->quota_2 * $quota->price_quota_2
                    + ($amount - $quota->quota_1 - $quota->quota_2) * $quota->price_quota_3;
            }

            if ($amount > ($quota->quota_3 + $quota->quota_2 + $quota->quota_1) && $amount <= ($quota->quota_4 + $quota->quota_3 +
                    $quota->quota_2 + $quota->quota_1)
            ) {
                $res = $quota->quota_1 * $quota->price_quota_1
                    + $quota->quota_2 * $quota->price_quota_2
                    + $quota->quota_3 * $quota->price_quota_3
                    + ($amount - $quota->quota_1 - $quota->quota_2 - $quota->quota_3) * $quota->price_quota_4;
            }

            if ($amount > ($quota->quota_4 + $quota->quota_3 +
                    $quota->quota_2 + $quota->quota_1) && $amount <= ($quota->quota_5 + $quota->quota_4 + $quota->quota_3 + $quota->quota_2 + $quota->quota_1)
            ) {
                $res = $quota->quota_1 * $quota->price_quota_1
                    + $quota->quota_2 * $quota->price_quota_2
                    + $quota->quota_3 * $quota->price_quota_3
                    + $quota->quota_4 * $quota->price_quota_4
                    + ($amount - $quota->quota_1 - $quota->quota_2 - $quota->quota_3 - $quota->quota_4)
                    * $quota->price_quota_5;
            }

            if ($amount > ($quota->quota_5 + $quota->quota_4 +
                    $quota->quota_3 + $quota->quota_2 + $quota->quota_1) && $amount <= ($quota->quota_6 + $quota->quota_5 + $quota->quota_4 +
                    $quota->quota_3 + $quota->quota_2 + $quota->quota_1)
            ) {
                $res = $quota->quota_1 * $quota->price_quota_1
                    + $quota->quota_2 * $quota->price_quota_2
                    + $quota->quota_3 * $quota->price_quota_3
                    + $quota->quota_4 * $quota->price_quota_4
                    + $quota->quota_5 * $quota->price_quota_5
                    + ($amount - $quota->quota_1 - $quota->quota_2 - $quota->quota_3 - $quota->quota_4 - $quota->quota_5)
                    * $quota->price_quota_6;
            }

            if ($amount > ($quota->quota_6 + $quota->quota_5 + $quota->quota_4 +
                    $quota->quota_3 + $quota->quota_2 + $quota->quota_1)
            ) {
                $res = $quota->quota_1 * $quota->price_quota_1
                    + $quota->quota_2 * $quota->price_quota_2
                    + $quota->quota_3 * $quota->price_quota_3
                    + $quota->quota_4 * $quota->price_quota_4
                    + $quota->quota_5 * $quota->price_quota_5
                    + $quota->quota_6 * $quota->price_quota_6
                    + ($amount - $quota->quota_1 - $quota->quota_2 - $quota->quota_3
                        - $quota->quota_4 - $quota->quota_5 - $quota->quota_6)
                    * $quota->price_quota_7;
            }

            return $res;
        }

        return $res;
    }

    public static function checkExistDate($hostel, $startDateVoucher, $endDateVoucher, $contract, $roomId, $hostelId)
    {
        $check = 0;

        if (is_string($endDateVoucher)) {
            $endDateVoucher = Carbon::createFromFormat('Y-m-d', $endDateVoucher);
        }

        if ($endDateVoucher->greaterThan($contract->end_date)) {
            return 1;
        }

        if ($hostel->type_rent == Hostel::TYPE_RENT_ALL) {
            $check = MoneyDetail::query()->where('start_date', '<=', $startDateVoucher)
                ->whereIn('type', [
                    MoneyInfo::VOUCHER_CONTRACT,
                    MoneyInfo::VOUCHER_ROOM_PRICE
                ])
                ->where('contract_status', '<>', Contract::LIQUIDATED)
                ->where('end_date', '>=', $endDateVoucher)
                ->where('room_id', $roomId)
                ->where('hostel_id', $hostelId)
                ->count();


            if ($check == 0) {

                $check = MoneyDetail::where('start_date', '<=', $endDateVoucher)
                    ->where('end_date', '>=', $endDateVoucher)
                    ->whereIn('type', [
                        MoneyInfo::VOUCHER_CONTRACT,
                        MoneyInfo::VOUCHER_ROOM_PRICE
                    ])
                    ->where('contract_status', '<>', Contract::LIQUIDATED)
                    ->where('room_id', $roomId)
                    ->where('hostel_id', $hostelId)
                    ->count();

                //      dd($check->pluck('start_date', 'end_date')->toArray());

                if ($check == 0) {


                    $check = MoneyDetail::where('start_date', '<=', $startDateVoucher)
                        ->where('end_date', '>=', $startDateVoucher)
                        ->whereIn('type', [
                            MoneyInfo::VOUCHER_CONTRACT,
                            MoneyInfo::VOUCHER_ROOM_PRICE
                        ])
                        ->where('contract_status', '<>', Contract::LIQUIDATED)
                        ->where('room_id', $roomId)
                        ->where('hostel_id', $hostelId)
                        ->count();

                    if ($check == 0) {

                        if ($check == 0) {
                            $check = MoneyDetail::where('start_date', '>=', $startDateVoucher)
                                ->whereIn('type', [
                                    MoneyInfo::VOUCHER_CONTRACT,
                                    MoneyInfo::VOUCHER_ROOM_PRICE
                                ])
                                ->where('contract_status', '<>', Contract::LIQUIDATED)
                                ->where('end_date', '<=', $endDateVoucher)
                                ->where('room_id', $roomId)
                                ->where('hostel_id', $hostelId)
                                ->count();
                        }
                    }


                }
            }

        } else {
            $check = MoneyDetail::where('start_date', '<=', $startDateVoucher)
                ->where('end_date', '>=', $endDateVoucher)
                ->where('renter_id', $contract->renter_id)
                ->where('contract_status', '<>', Contract::LIQUIDATED)
                ->whereIn('type', [
                    MoneyInfo::VOUCHER_CONTRACT,
                    MoneyInfo::VOUCHER_ROOM_PRICE
                ])
                ->where('room_id', $roomId)->where('hostel_id', $hostelId)->count();

            if ($check == 0) {
                $check = MoneyDetail::where('start_date', '<=', $endDateVoucher)
                    ->where('end_date', '>=', $endDateVoucher)
                    ->where('renter_id', $contract->renter_id)
                    ->where('contract_status', '<>', Contract::LIQUIDATED)
                    ->whereIn('type', [
                        MoneyInfo::VOUCHER_CONTRACT,
                        MoneyInfo::VOUCHER_ROOM_PRICE
                    ])
                    ->where('room_id', $roomId)->where('hostel_id', $hostelId)->count();

                if ($check == 0) {


                    MoneyDetail::where('start_date', '<=', $startDateVoucher)
                        ->where('end_date', '>=', $startDateVoucher)
                        ->where('renter_id', $contract->renter_id)
                        ->where('contract_status', '<>', Contract::LIQUIDATED)
                        ->whereIn('type', [
                            MoneyInfo::VOUCHER_CONTRACT,
                            MoneyInfo::VOUCHER_ROOM_PRICE
                        ])
                        ->where('room_id', $roomId)->where('hostel_id', $hostelId)->count();

                    if ($check == 0) {
                        $check = MoneyDetail::where('start_date', '>=', $startDateVoucher)
                            ->where('end_date', '<=', $endDateVoucher)
                            ->where('renter_id', $contract->renter_id)
                            ->where('contract_status', '<>', Contract::LIQUIDATED)
                            ->whereIn('type', [
                                MoneyInfo::VOUCHER_CONTRACT,
                                MoneyInfo::VOUCHER_ROOM_PRICE
                            ])
                            ->where('room_id', $roomId)->where('hostel_id', $hostelId)->count();
                    }
                }
            }
        }

        return $check;
    }

    public static function getPeriodNumber($period)
    {
        $res = 1;

        switch ($period) {
            case Room::ONE_MONTH_PERIOD:
                $res = 1;
                break;

            case Room::TWO_MONTH_PERIOD:
                $res = 2;
                break;

            case Room::THREE_MONTH_PERIOD:
                $res = 3;
                break;

            case 6:
                $res = 6;
                break;

            case 12:
                $res = 12;
                break;

            case Room::FIVE_MONTH_PERIOD:
                $res = 5;
                break;

            case Room::SIX_MONTH_PERIOD:
                $res = 6;
                break;

            case Room::ONE_YEAR_PERIOD:
                $res = 12;
                break;

            case Room::FOUR_MONTH_PERIOD:
                $res = 4;
                break;

            default:
                $res = 1;
                break;
        }

        return $res;
    }

    public static function updateIsEmptyRoom(Room $room)
    {
        $status = false;
        $hostel = $room->hostel;
        if (!$hostel) {
            return;
        }

        if ($hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
            $maxRenters = $room->max_renters;
            $numberCurrentRenters = RenterRoom::where('room_id', $room->id)->count();
            if ($numberCurrentRenters < $maxRenters) {
                $status = true;
            }
        } else if ($hostel->type_rent == Hostel::TYPE_RENT_ALL) {
            $numberCurrentRenters = RenterRoom::where('room_id', $room->id)->count();
            if ($numberCurrentRenters <= 0) {
                $status = true;
            }
        }

        $room->is_empty = $status;
        $room->save();

        return;
    }


    public static function checkIsEmpty(Room $room, $type)
    {
        $status = false;

        if ($type == Hostel::TYPE_RENT_EVERY) {
            $maxRenters = $room->max_renters;
            $numberCurrentRenters = RenterRoom::where('room_id', $room->id)->count();
            if ($numberCurrentRenters < $maxRenters) {
                $status = true;
            }
        } else if ($type == Hostel::TYPE_RENT_ALL) {
            $numberCurrentRenters = RenterRoom::where('room_id', $room->id)->count();
            if ($numberCurrentRenters == 0) {
                $status = true;
            }
        }

        return $status;
    }

    public static function chartPayment($hostelId = null, $userId)
    {
        $paids = MoneyInfo::where('remain', 0);
        $unpaids = MoneyInfo::where('remain', '>', 0);
        $year = Carbon::now()->year;
        $currentMonth = Carbon::now()->month;
        $startMonth = $currentMonth - 2;

        $returnArr = [];

        for ($i = $startMonth; $i <= $currentMonth; $i++) {

            $month = $i;
            if (!empty($month) && !empty($year)) {
                $startDate = Carbon::createFromFormat('d/m/Y', '01/' . $month . '/' . $year)->startOfMonth()->toDateString();
                $endDate = Carbon::createFromFormat('d/m/Y', '01/' . $month . '/' . $year)->endOfMonth()->toDateString();

                $paids = $paids->whereBetween('date_action', [$startDate, $endDate]);
                $unpaids = $unpaids->whereBetween('date_action', [$startDate, $endDate]);
            }


            if (!empty($hostelId)) {
                $paids = $paids->where('hostel_id', $hostelId);
                $unpaids = $unpaids->where('hostel_id', $hostelId);
            } else {
                $hostels = Hostel::where('owner_id', $userId)->pluck('id')->toArray();
                $paids = $paids->whereIn('hostel_id', $hostels);
                $unpaids = $unpaids->whereIn('hostel_id', $hostels);
            }

            $paidCnt = $paids->count();
            $unPaidCnt = $unpaids->count();
            $paidAmount = $paids->sum('amount');
            $unpaidAmount = $unpaids->sum('amount');

            $returnArr[] = [
                'month' => $i,
                'year' => $year,
                'paid_cnt' => $paidCnt,
                'paid_amount' => $paidAmount,
                'unpaid_cnt' => $unPaidCnt,
                'unpaid_amount' => $unpaidAmount,
                'cnt' => $paidCnt + $unPaidCnt
            ];
        }

        return $returnArr;
    }

    public static function buildVnPayUrl($amount, $vnp_IpAddr, $bankcode, $vnp_Locale, $vnp_TxnRef)
    {
        // $vnp_TxnRef = 148;
        $amount = (int)$amount * 100;
        $vnp_Url = "https://pay.vnpay.vn/vpcpay.html";
        $vnp_Returnurl = "https://itro.vn/order/callback";
        $vnpay_tmn_code = "BIGLINKS"; //VNPAY will send to you
        $vnpay_hash_secret = "HXSOAFEVNLPHABXZJQBWZYGJJIWTIJMC";

        $inputData = array(
            "vnp_TmnCode" => $vnpay_tmn_code, //Tham so nay lay tu VNPAY
            "vnp_Amount" => $amount,
            "vnp_Command" => "pay",
            "vnp_CreateDate" => date('YmdHis'),
            "vnp_CurrCode" => "VND",
            "vnp_IpAddr" => $vnp_IpAddr,
            "vnp_Locale" => $vnp_Locale,
            "vnp_OrderInfo" => 'Thanh toán đơn hàng mã: ' . $vnp_TxnRef,
            "vnp_OrderType" => 'billpayment',
            "vnp_ReturnUrl" => $vnp_Returnurl,
            "vnp_TxnRef" => $vnp_TxnRef,
            "vnp_Version" => "2.0.0",
        );


        $out = $inputData;
        if (isset($bankcode) && $bankcode != null) {
            $out = array_merge($inputData, array("vnp_BankCode" => $bankcode));
        }
        ksort($out);
        $query = "";
        $i = 0;
        $hashdata = "";
        foreach ($out as $key => $value) {
            if ($i == 1) {
                $hashdata .= '&' . $key . "=" . $value;
            } else {
                $hashdata .= $key . "=" . $value;
                $i = 1;
            }
            $query .= urlencode($key) . "=" . urlencode($value) . '&';
        }

        $vnp_Url = $vnp_Url . "?" . $query;
        if (isset($vnpay_hash_secret)) {
            $vnpSecureHash = md5($vnpay_hash_secret . $hashdata);
            // $vnpSecureHash = '123456';
            $vnp_Url .= 'vnp_SecureHashType=MD5&vnp_SecureHash=' . $vnpSecureHash;
        }

        return $vnp_Url;

    }

    public static function redeemCoupon($coupon, $userId, $isOrder = false)
    {
        $user = User::find($userId);
        if ($isOrder == true) {
            if (empty($coupon)) {
                return;
            }
        }
        if (empty($coupon)) {
            return [
                'status' => 0,
                'message' => 'Không được bỏ trống mã coupon'
            ];
        }

        $check = \DB::table('coupon_generates')->where('code', $coupon)->first();

        if (!$check) {
            return [
                'status' => 0,
                'message' => 'Coupon không tồn tại'
            ];
        }

        if ($check->is_active == 0) {
            return [
                'status' => 0,
                'message' => 'Coupon chưa được kích hoạt'
            ];
        }
//		if ( $check->status == Coupon::COUPON_GENERATE_USED ) {
//			return redirect()->back()->with( 'error', 'Mã coupon đã được sử dụng' );
//		}


        $couponId = $check->coupon_id;
        $couponItem = Coupon::find($couponId);
        if (!$couponItem) {
            return [
                'status' => 0,
                'message' => 'Không tìm thấy mã khuyến mại'
            ];
        }

        if (!empty($couponItem->from_date_expire)) {
            if ($couponItem->from_date_expire->greaterThan(Carbon::now())) {
                return [
                    'status' => 0,
                    'message' => 'Coupon chưa thể sử dụng'
                ];
            }
        }

        if (!empty($couponItem->end_date_expire)) {
            if ($couponItem->end_date_expire->lessThan(Carbon::now())) {
                return [
                    'status' => 0,
                    'message' => 'Coupon đã quá hạn sử dụng'
                ];
            }
        }


        $numberUse = $couponItem->number_use;

        $numberUseBefore = \DB::table('log_coupons')
            ->where('code', $coupon)
            ->count();

        $numberUserInCoupon = \DB::table('log_coupons')
            ->where('coupon_id', $couponItem->id)
            ->count();

        if ($numberUserInCoupon > 1) {
            return [
                'status' => 0,
                'message' => 'Bạn đã tham gia chương trình này trước đó'
            ];
        }

        if ($numberUseBefore >= $numberUse) {
            return [
                'status' => 0,
                'message' => 'Coupon đã được sử dụng trước đó'
            ];
        }


        $packageId = $couponItem->package_ids;
        $packageApply = $couponItem->package_apply;
        $currentPackage = UserPackage::query()->where('user_id', $userId)->first();
        if (!empty($packageApply)) {

            if ($currentPackage) {
                $currentPackageId = $currentPackage->package_id;
                $packageApplyArr = json_decode($packageApply, true);

                if (!in_array(-1, $packageApplyArr)) {
                    if (!in_array($currentPackageId, $packageApplyArr)) {
                        return [
                            'status' => 0,
                            'message' => 'Coupon không áp dụng cho gói cước hiện tại của bạn'
                        ];
                        // return redirect()->back()->with('error', 'Coupon không áp dụng cho gói cước hiện tại của bạn');
                    }
                }
            }
        }

        $packageName = null;
        $endTime = null;


        if ($currentPackage) {
            if (!empty($packageId)) {

                if ($currentPackage->package_id < $packageId) {

                    $currentPackage->package_id = $packageId;
                }
            }

            $currentPackage->end_date = $currentPackage->end_date->addMonth($couponItem->number_month_more);
            $currentPackage->save();

            $packageNew = Package::find($packageId);
            if ($packageNew) {
                $packageName = $packageNew->name;
            }
            $endTime = $currentPackage->end_date->format('d/m/Y');
        }

        \DB::table('log_coupons')->insert([
            'user_id' => $userId,
            'coupon_id' => $couponItem->id,
            'coupon_generate_id' => $check->id,
            'code' => $coupon,
            'created_at' => Carbon::now()->toDateTimeString(),
            'updated_at' => Carbon::now()->toDateTimeString(),
        ]);

        \DB::table('coupon_generates')->where('code', $coupon)
            ->update([
                'status' => Coupon::COUPON_GENERATE_USED,
                'used_by' => $userId,
                'used_by_name_phone' => $user->name_text . ' - ' . $user->phone
            ]);

        \DB::table('coupon_transactions')->where('code', $coupon)
            ->where('coupon_id', $couponId)
            ->update([
                'status' => Coupon::COUPON_GENERATE_USED,

            ]);

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

    public static function updateCurrentHostel($user)
    {
        if ($user->type != User::RENTER) {
            return null;
        }

        $renterRoom = RenterRoom::query()
            ->where('user_id', $user->id)
            ->first();
        if ($renterRoom) {
            return $renterRoom->hostel_id;
        }

        return null;
    }

    public static function getNameImageConversation($id, $conversationImage, $conversationName, $hostelId, $userCurrent)
    {

        $userIds = \DB::table('user_conversations')
            ->where('conversation_id', $id)
            ->pluck('user_id')->toArray();


        if (count($userIds) == 2) {
            if (empty($hostelId)) {
                foreach ($userIds as $userId) {
                    if ($userId == $userCurrent) {
                        $user = User::find($userId);
                        if ($user) {
                            $conversationName = $user->name_text;
                            $conversationImage = $user->image;
                        }
                    }
                }
            }
        }

        if (str_contains($conversationImage, '/files/')) {
            $conversationImage = '/files/' . str_replace('/files/', '', $conversationImage);
        } else {
            if (!str_contains($conversationImage, '/frontend3/')) {
                $conversationImage = '/files/' . $conversationImage;
            }
        }

        return [
            'name' => $conversationName,
            'image' => $conversationImage
        ];

    }

    public static function createRoomConversation($roomId, $userId)
    {
        $user = User::find($userId);

        $room = Room::find($roomId);

        $hostel = $room->hostel;
        $ownerId = $hostel->owner_id;

        $userArr = \DB::table('staff_hostels')
            ->where('hostel_id', $hostel->id)
            ->pluck('user_id')
            ->toArray();

        $userArr[] = $ownerId;

        $members = User::whereIn('id', $userArr)
            ->get()->pluck('id')->toArray();


        $currentRenter = RenterRoom::where('room_id', $room->id)->pluck('user_id')->toArray();

        $members = array_merge($members, $currentRenter);

        $membersArr = array_unique($members);


        sort($membersArr);

        $conversation = Conversation::create([
            'name' => $room->name,
            'image' => '/frontend3/assets/img/placeholder.png',
            'members' => implode(',', $membersArr),
            'hostel_id' => $room->hostel->id,
            'room_id' => $room->id,
            'user_id' => $userId
        ]);

        $conversation->users()->sync($membersArr);

        $message = Message::create([
            'content' => ' đã tạo cuộc hội thoại',
            'conversation_id' => $conversation->id,
            'type' => Message::TYPE_SYSTEM,
            'from' => $userId
        ]);

        $conversation->update([
            'last_message_id' => $message->id,
            'last_message_time' => Carbon::now()->toDateTimeString()
        ]);


        $pusher = \PusherService::getClient();

        $userConverIds = \DB::table('user_conversations')
            ->where('conversation_id', $conversation->id)
            ->pluck('user_id')
            ->toArray();

        foreach ($userConverIds as $userConverId) {

            $messageArr = $message->toArray();
            if ($userConverId == $userId) {
                $messageArr['content'] = 'Bạn ' . $messageArr['content'];
            } else {
                $messageArr['content'] = $user->name_text . ' ' . $messageArr['content'];
            }
            $pusher->trigger('chat-' . $userConverId, 'new-message', $messageArr);

        }

        return $conversation;
    }

    public static function checkFullPeriod(Carbon $from, Carbon $to, $dayCollect)
    {
        if ($from->copy()->startOfDay()->equalTo($to->copy()->startOfDay())) {
            return false;
        }

        if ($from->copy()->day == $to->copy()->addDay(1)->day) {
            return true;
        }

        if ($from->copy()->day == $to->copy()->day) {
            return true;
        }

        if ($from->copy()->subDay(1)->day == $to->copy()->subDay(1)->day) {
            return true;
        }

        if ($from->copy()->addDay(1)->day == $to->copy()->addDay(1)->day) {
            return true;
        }

        /*
         * end_date.getDay() == day_collect && ((start_date.minusDay(1).getDay() <= end_date.getDay() && start_date.minusDay(1).getMonth == 2)
         * || (start_date.minusDay(1).getDay() == end_date.minusDay(1).getMonth != 2))
         */

        if (($from->copy()->diffInDays($to->copy()) + 1) >= 28 && $to->copy()->day == $dayCollect && (($from->copy()->subDay()->day <= $to->copy()->day && $from->copy()->subDay()->month == 2)
                || ($from->copy()->subDay()->day == $to->copy()->day && $from->copy()->subDay(1)->month != 2))) {
            return true;
        }

        /*
         * start_date.minusDay(1).day == day_collect && (end_date.month == 2 && (end_date.day == 28 || end_date.day == 29))
         */
        if ($from->copy()->diffInDays($to->copy()) + 1 >= 28 && $from->copy()->subDay()->day == $dayCollect
            && ($to->copy()->month == 2 && ($to->copy()->day == 28 || $to->copy()->day == 29))) {
            return true;
        }

        return false;
    }

    public static function calculateMoneyInRangeFuture(Carbon $from, Carbon $to, $dayCollect, $period, $cost, $collectTo)
    {

        if (empty($collectTo)) {
            return 0;
        }

        if (self::checkFullPeriod($from->copy(), $to->copy(), $dayCollect)) {
            return $period * $cost;
        }

        $money = 0;
        $collectTo = $collectTo->copy();
        $originalTo = $to->copy();

        if ($collectTo->lessThanOrEqualTo($to)) {
            $to = $collectTo;
        }

        while ($from->lessThanOrEqualTo($to)) {

            if ($from->copy()->day <= $dayCollect && $from->month == $to->month && $from->year == $to->year) {
                $month = $from->copy()->month;
                $year = $from->copy()->year;


            } else if ($from->copy()->day <= $dayCollect) {

                $month = $from->copy()->month;
                $year = $from->copy()->year;

            } else {
                $month = $from->copy()->firstOfMonth()->addMonth()->month;
                $year = $from->copy()->firstOfMonth()->addMonth()->year;

            }


            if (($month == $collectTo->month && $year == $collectTo->year)) {
                if ($collectTo->day < $dayCollect) {
                    $dayCollect = $collectTo->day;
                }
            }

            if (($month == $from->month && $year == $from->year) && ($month == $collectTo->month && $year == $collectTo->year)) {

                if ($from->day < $dayCollect) {
                    $dayCollect = $collectTo->day;
                }
            }


            if (checkdate($month, $dayCollect, $year)) {
                $toTemp = Carbon::createFromFormat('d-m-Y', $dayCollect . '-' . $month . '-' . $year);

            } else {

                $tempDayCollect = Carbon::createFromFormat('d-m-Y', '01-' . $month . '-' . $year)->lastOfMonth()->day;
                $toTemp = Carbon::createFromFormat('d-m-Y', $tempDayCollect . '-' . $month . '-' . $year);
            }

            //    dump($toTemp->toDateString());
            if ($collectTo->between($from, $toTemp)) {

                $toTemp = $collectTo;
            }

//            if($toTemp->greaterThan($to))
//            {
//                return $money;
//            }

            if (self::checkFullPeriod($from, $toTemp, $dayCollect)) {
                if (!$from->equalTo($toTemp)) {
                    $money += 1 * $cost;
                }

            } else {
                $diffDays = $toTemp->copy()->diffInDays($from->copy());
                if (self::checkFullPeriod($from->copy(), $toTemp->copy(), $dayCollect)) {
                    $numberDays = $from->daysInMonth;
                } else {
                    //dump($from->copy()->toDateString(), $to->copy()->toDateString());
                    if (self::checkFullPeriod($from->copy(), $originalTo->copy(), $dayCollect)) {

                        $numberDays = $from->daysInMonth;
                    } else {
                        $numberDays = 30;
                    }

                }
                $money += intval($cost / ($numberDays) * ($diffDays + 1));
            }
//            dump($from->copy()->toDateString());
//            dump($toTemp->copy()->toDateString());
//            dump($money);
//            dump('---');
            $from = $toTemp->copy()->addDay();
            //dump($from->copy()->toDateString());
        }

        return $money;
    }

    public static function calculateMoneyInRange2(Carbon $from, Carbon $to, $dayCollect, $period, $cost, $collectTo)
    {

        if (empty($collectTo)) {
            return 0;
        }

//		if ( self::checkFullPeriod( $from->copy(), $to->copy(), $dayCollect ) ) {
//			return $period * $cost;
//		}

        $money = 0;
        $collectTo = $collectTo->copy();
        $originalTo = $to->copy();

        if ($collectTo->lessThanOrEqualTo($to)) {
            $to = $collectTo;
        }

        while ($from->lessThanOrEqualTo($to)) {

            if ($from->copy()->day < $dayCollect && $from->month == $to->month && $from->year == $to->year) {
                $month = $from->copy()->month;
                $year = $from->copy()->year;


            } else if ($from->copy()->day < $dayCollect) {

                $month = $from->copy()->month;
                $year = $from->copy()->year;

            } else {
                $month = $from->copy()->firstOfMonth()->addMonth()->month;
                $year = $from->copy()->firstOfMonth()->addMonth()->year;

            }


            if (($month == $collectTo->month && $year == $collectTo->year)) {
                if ($collectTo->day < $dayCollect) {
                    $dayCollect = $collectTo->day;
                }
            }

            if (($month == $from->month && $year == $from->year) && ($month == $collectTo->month && $year == $collectTo->year)) {

                if ($from->day < $dayCollect) {
                    $dayCollect = $collectTo->day;
                }
            }


            if (checkdate($month, $dayCollect, $year)) {
                $toTemp = Carbon::createFromFormat('d-m-Y', $dayCollect . '-' . $month . '-' . $year);

            } else {

                $tempDayCollect = Carbon::createFromFormat('d-m-Y', '01-' . $month . '-' . $year)->lastOfMonth()->day;
                $toTemp = Carbon::createFromFormat('d-m-Y', $tempDayCollect . '-' . $month . '-' . $year);
            }

            //    dump($toTemp->toDateString());
            if ($collectTo->between($from, $toTemp)) {

                $toTemp = $collectTo;
            }

//            if($toTemp->greaterThan($to))
//            {
//                return $money;
//            }

            if (self::checkFullPeriod($from, $toTemp, $dayCollect)) {

                if (!$from->equalTo($toTemp)) {
                    $money += 1 * $cost;
                }

            } else {
                $diffDays = $toTemp->copy()->diffInDays($from->copy());
                if (self::checkFullPeriod($from->copy(), $toTemp->copy(), $dayCollect)) {
                    $numberDays = $from->daysInMonth;
                } else {
                    //dump($from->copy()->toDateString(), $to->copy()->toDateString());
                    if (self::checkFullPeriod($from->copy(), $originalTo->copy(), $dayCollect)) {

                        $numberDays = $from->daysInMonth;
                    } else {
                        $numberDays = 30;
                    }

                }
                $money += intval($cost / ($numberDays) * ($diffDays + 1));
            }
//            dump($from->copy()->toDateString());
//            dump($toTemp->copy()->toDateString());
//            dump($money);
//            dump('---');
            $from = $toTemp->copy()->addDay();
            //dump($from->copy()->toDateString());
        }

        return $money;
    }


    public static function calculateMoneyInRange3(Carbon $from, Carbon $to, $cost, $dayCollect = null)
    {
        $money = 0;
        while ($from->lessThanOrEqualTo($to)) {
            if ($from->copy()->day < $dayCollect) {
                $month = $from->copy()->month;
                $year = $from->copy()->year;
            } else {
                $month = $from->copy()->firstOfMonth()->addMonth()->month;
                $year = $from->copy()->firstOfMonth()->addMonth()->year;
            }

            if (checkdate($month, $dayCollect, $year)) {
                $toTemp = Carbon::createFromFormat('d-m-Y', $dayCollect . '-' . $month . '-' . $year);

            } else {

                $tempDayCollect = Carbon::createFromFormat('d-m-Y', '01-' . $month . '-' . $year)->lastOfMonth()->day;
                $toTemp = Carbon::createFromFormat('d-m-Y', $tempDayCollect . '-' . $month . '-' . $year);
            }

//            dump($money);
//                dump($to->toDateString());

            if ($toTemp->greaterThan($to)) {
                $toTemp = $to->copy();
            }


            if (self::checkFullPeriod($from, $toTemp, $dayCollect)) {

                if (!$from->copy()->startOfDay()->equalTo($toTemp->copy()->startOfDay())) {

                    $money += 1 * $cost;
                } else if ($from->copy()->startOfDay()->equalTo($toTemp->copy()->startOfDay())) {

                    $money += intval(round($cost / ($from->copy()->daysInMonth)));
                }
            } else {
                $diffDays = $toTemp->copy()->diffInDays($from->copy());

                if (self::checkFullPeriod($from->copy(), $toTemp->copy(), $dayCollect)) {
                    $numberDays = $from->daysInMonth;
                } else {
                    //dump($from->copy()->toDateString(), $to->copy()->toDateString());
                    if (self::checkFullPeriod($from->copy(), $to->copy(), $dayCollect)) {
                        $numberDays = $from->daysInMonth;
                    } else {
                        $numberDays = 30;
                    }

                }
                $money += intval($cost / ($numberDays) * ($diffDays + 1));
            }
//            dump($from->copy()->toDateString());
//            dump($toTemp->copy()->toDateString());
//            dump($money);
//            dump('---');
            $from = $toTemp->copy()->addDay();
        }

        return $money;
    }

    public static function calculateMoneyInRange4(Carbon $from, Carbon $to, $cost, $dayCollect = null, $isEnd = false)
    {
        $money = 0;
        $fromO = $from->copy();
        while ($from->lessThanOrEqualTo($to)) {
            if ($from->copy()->day <= $dayCollect) {
                $month = $from->copy()->month;
                $year = $from->copy()->year;
            } else {
                $month = $from->copy()->firstOfMonth()->addMonth()->month;
                $year = $from->copy()->firstOfMonth()->addMonth()->year;
            }


            $tempDayCollect = Carbon::createFromFormat('d-m-Y', '01-' . $month . '-' . $year)->lastOfMonth()->day;
            $toTemp = Carbon::createFromFormat('d-m-Y', $tempDayCollect . '-' . $month . '-' . $year);

            if (checkdate($month, $dayCollect, $year)) {
                $toTemp = Carbon::createFromFormat('d-m-Y', $dayCollect . '-' . $month . '-' . $year);
                if ($toTemp->copy()->equalTo($from->copy())) {
                    if ($fromO->copy()->notEqualTo($to->copy())) {
                        $toTemp->addMonth()->subDay();
                    }
                }

            }

            if ($toTemp->greaterThan($to)) {
                $toTemp = $to->copy();
            }


            if (self::checkFullPeriod($from, $toTemp, $dayCollect)) {

                if (!$from->copy()->startOfDay()->equalTo($toTemp->copy()->startOfDay())) {

                    $money += 1 * $cost;
                } else if ($from->copy()->startOfDay()->equalTo($toTemp->copy()->startOfDay())) {

                    $money += intval(round($cost / ($from->copy()->daysInMonth)));
                }
            } else {
                $diffDays = $toTemp->copy()->diffInDays($from->copy());

                if (self::checkFullPeriod($from->copy(), $toTemp->copy(), $dayCollect)) {
                    $numberDays = $from->daysInMonth;
                } else {
                    //dump($from->copy()->toDateString(), $to->copy()->toDateString());
                    if (self::checkFullPeriod($from->copy(), $to->copy(), $dayCollect)) {
                        $numberDays = $from->daysInMonth;
                    } else {
                        if ($isEnd) {
                            $numberDays = $from->daysInMonth; //TH is_end = true nghĩa là khi thanh lý HĐ, lấy số ngày bắt đầu theo số ngày thật
                        } else {
                            $numberDays = 30; //TH tao HD lay 30 ngay
                        }

                    }

                }
                //  dd($cost / ($numberDays) * ($diffDays + 1));
                $money += intval(($cost / $numberDays) * ($diffDays + 1));

            }
//            dump($from->copy()->toDateString());
//            dump($toTemp->copy()->toDateString());
//            dump($money);
//            dump('---');
            $from = $toTemp->copy()->addDay();
        }

        return $money;
    }

    public static function calculateMoneyInRangeUpdateMoneyInfo(Carbon $from, Carbon $to, $cost, $dayCollect = null)
    {
        $money = 0;
        $fromO = $from->copy();
        while ($from->lessThanOrEqualTo($to)) {
            if ($from->copy()->day <= $dayCollect) {
                $month = $from->copy()->month;
                $year = $from->copy()->year;
            } else {
                $month = $from->copy()->firstOfMonth()->addMonth()->month;
                $year = $from->copy()->firstOfMonth()->addMonth()->year;
            }


            $tempDayCollect = Carbon::createFromFormat('d-m-Y', '01-' . $month . '-' . $year)->lastOfMonth()->day;
            $toTemp = Carbon::createFromFormat('d-m-Y', $tempDayCollect . '-' . $month . '-' . $year);

            if (checkdate($month, $dayCollect, $year)) {
                $toTemp = Carbon::createFromFormat('d-m-Y', $dayCollect . '-' . $month . '-' . $year);
                if ($toTemp->copy()->equalTo($from->copy())) {
                    if ($fromO->copy()->notEqualTo($to->copy())) {
                        $toTemp->addMonth()->subDay();
                    }
                }

            }

            if ($toTemp->greaterThan($to)) {
                $toTemp = $to->copy();
            }


            if (self::checkFullPeriod($from, $toTemp, $dayCollect)) {

                if (!$from->copy()->startOfDay()->equalTo($toTemp->copy()->startOfDay())) {

                    $money += 1 * $cost;
                } else if ($from->copy()->startOfDay()->equalTo($toTemp->copy()->startOfDay())) {

                    $money += intval(round($cost / ($from->copy()->daysInMonth)));
                }
            } else {
                $diffDays = $toTemp->copy()->diffInDays($from->copy());

                if (self::checkFullPeriod($from->copy(), $toTemp->copy(), $dayCollect)) {
                    $numberDays = $from->daysInMonth;
                } else {
                    //dump($from->copy()->toDateString(), $to->copy()->toDateString());
                    if (self::checkFullPeriod($from->copy(), $to->copy(), $dayCollect)) {
                        $numberDays = $from->daysInMonth;
                    } else {
                        $numberDays = $from->daysInMonth;
                    }

                }

                $money += intval($cost / ($numberDays) * ($diffDays + 1));

            }
//            dump($from->copy()->toDateString());
//            dump($toTemp->copy()->toDateString());
//            dump($money);
//            dump('---');
            $from = $toTemp->copy()->addDay();
        }

        return $money;
    }

    public static function calculateDayInRange(Carbon $from, Carbon $to, $dayCollect = null)
    {
        $retVal = 0;
        while ($from->lessThanOrEqualTo($to)) {
            if ($from->copy()->day <= $dayCollect) {
                $month = $from->copy()->month;
                $year = $from->copy()->year;
            } else {
                $month = $from->copy()->firstOfMonth()->addMonth()->month;
                $year = $from->copy()->firstOfMonth()->addMonth()->year;
            }


            if (checkdate($month, $dayCollect, $year)) {
                $toTemp = Carbon::createFromFormat('d-m-Y', $dayCollect . '-' . $month . '-' . $year);

            } else {

                $tempDayCollect = Carbon::createFromFormat('d-m-Y', '01-' . $month . '-' . $year)->lastOfMonth()->day;
                $toTemp = Carbon::createFromFormat('d-m-Y', $tempDayCollect . '-' . $month . '-' . $year);
            }

//            dump($money);
//                dump($to->toDateString());

            if ($toTemp->greaterThan($to)) {
                $toTemp = $to->copy();
            }


            if (self::checkFullPeriod($from, $toTemp, $dayCollect)) {

                if (!$from->copy()->startOfDay()->equalTo($toTemp->copy()->startOfDay())) {

                    $retVal += 1;
                } else if ($from->copy()->startOfDay()->equalTo($toTemp->copy()->startOfDay())) {

                    $retVal += 1 / ($from->copy()->daysInMonth);
                }

            } else {
                $diffDays = $toTemp->copy()->diffInDays($from->copy());

                if (self::checkFullPeriod($from->copy(), $toTemp->copy(), $dayCollect)) {
                    $numberDays = $from->daysInMonth;
                } else {
                    //dump($from->copy()->toDateString(), $to->copy()->toDateString());
                    if (self::checkFullPeriod($from->copy(), $to->copy(), $dayCollect)) {
                        $numberDays = $from->daysInMonth;
                    } else {
                        $numberDays = 30;
                    }

                }
                $retVal += 1 / ($numberDays) * ($diffDays + 1);

            }
//			dump($from->copy()->toDateString());
//			dump($toTemp->copy()->toDateString());
//            dump($from->copy()->toDateString());
//            dump($toTemp->copy()->toDateString());
//            dump($money);
//            dump('---');
            $from = $toTemp->copy()->addDay();
        }

        return $retVal;
    }

    public static function stripInvalidXml($value)
    {
        $ret = "";
        $current = '';
        if (empty($value)) {
            return $ret;
        }

        $length = strlen($value);
        for ($i = 0; $i < $length; $i++) {
            $current = ord($value{$i});
            if (($current == 0x9) ||
                ($current == 0xA) ||
                ($current == 0xD) ||
                (($current >= 0x20) && ($current <= 0xD7FF)) ||
                (($current >= 0xE000) && ($current <= 0xFFFD)) ||
                (($current >= 0x10000) && ($current <= 0x10FFFF))
            ) {
                $ret .= chr($current);
            } else {
                $ret .= " ";
            }
        }

        return $ret;
    }

    public static function getDateMoneyInfo($moneyInfo)
    {
        $moneyDetail = MoneyDetail::query()->where('money_info_id', $moneyInfo->id)->first();

        if ($moneyDetail) {
            $firstMoneyInfo = Carbon::createFromFormat('Y-m-d', $moneyDetail->start_date);
            $secondMoneyInfo = Carbon::createFromFormat('Y-m-d', $moneyDetail->end_date);

            $diffMoneyInfo = $secondMoneyInfo->diffInDays($firstMoneyInfo) + 1;
            $firstMoneyInfo = $firstMoneyInfo->format('d/m/Y');
            $secondMoneyInfo = $secondMoneyInfo->format('d/m/Y');
        }

        return [
            'start_date' => $firstMoneyInfo,
            'end_date' => $secondMoneyInfo,
            'diff' => $diffMoneyInfo
        ];
    }


    public static function getContractTemplate($contract, $contractTemplate, $renter, $isDownload = false)
    {
        $customerName = $contract->name;

        $ownerName = $contract->hostel->owner->name;
        $ownerPhone = $contract->hostel->owner->phone;
        $ownerAddress = $contract->hostel->owner->address_text;
        $ownerIdNumber = $contract->hostel->owner_id_number;
        $renterIdNumber = $contract->id_number;
        $renterAddress = '';
        $renterIdNumberDate = '.............';
        $renterIdNumberLocation = '.............';
        if ($contract->renter) {
            $renterContract = $contract->renter;
            $renterAddress = $contract->renter->address_text;

            if (!empty($renterContract->id_number_date)) {
                $renterIdNumberDate = Carbon::createFromFormat('Y-m-d', $renterContract->id_number_date)->format('d/m/Y');
            }

            $renterIdNumberLocation = $renterContract->id_number_location;

        }
        $renterPhone = $contract->phone;
        $renterEmail = $contract->email;
        $hostelAddress = $contract->room->hostel->address_text;
        $ownerBirthYear = $contract->room->hostel->owner->birthday;



   
        
        try {
            $renterBirthYear = !empty($renter->birthday) ? Carbon::createFromFormat('Y-m-d', $renter->birthday)->format('d/m/Y') : '......';
        } catch (\Exception $e) {
            $renterBirthYear = $renter->birthday;
        }
        
        try {
            $renterBirthYear = !empty($renter->birthday) ? Carbon::createFromFormat('Y-m-d H:i:s', $renter->birthday)->format('d/m/Y') : '       ...';
        } catch (\Exception $e) {
            $renterBirthYear = $renter->birthday;
        }

        $startDay = $contract->start_date->day;
        $startMonth = $contract->start_date->month;
        $startYear = $contract->start_date->year;

        $endDay = $contract->end_date->day;
        $endMonth = $contract->end_date->month;
        $endYear = $contract->end_date->year;

        $diffYear = $contract->end_date->diffInYears($contract->start_date);
        $diffMonth = $contract->end_date->addDays(1)->diffInMonths($contract->start_date);

        $f = new \NumberFormatter('vi_VN', \NumberFormatter::SPELLOUT);

        $roomPriceText = $f->format($contract->room_price) . ' đồng';
        $period = $contract->period;

        $roomPrice = number_format($contract->room_price, 0, '.', '.');
        $roomName = $contract->room->name;
        $bedName = optional($contract->bed)->name;
        $roomSize = $contract->room->size;
        $roomFloor = $contract->room->block_name;
        $contractDeposit = number_format($contract->deposit, 0, '.', '.');
        $contractDepositText = $f->format($contract->deposit) . ' đồng';


        $config = Config::query()->where('owner_id', $contract->hostel->owner_id)->first();
        if ($config) {
            if (!empty($config->logo)) {
                $contractTemplate = str_replace('{Logo}', '<img width="100" src="' . public_path('/files/'.$config->logo) . '" style="max-width: 100px" />', $contractTemplate);
            } else {
                $contractTemplate = str_replace('{Logo}', '<img width="100" src="https://itro.vn/frontend3/assets/img/logo.png" style="max-width: 100px" />', $contractTemplate);
            }
        } else {
            $contractTemplate = str_replace('{Logo}', '<img width="100" src="https://itro.vn/frontend3/assets/img/logo.png" style="max-width: 100px" />', $contractTemplate);
        }

        $location = null;
        if ($renter) {
            $location = $renter->address_detail;
        }


        $firstMoneyInfo = '.............';
        $secondMoneyInfo = '............';
        $diffMoneyInfo = '.............';
        $amountMoneyInfo = '.............';
        $firstAmountMoneyInfo = '.............';
        $firstAmountMoneyInfoText = '.............';
        $amountMoneyInfoText = '.............';
        $diffMonth = $contract->end_date->addDays(1)->diffInMonths($contract->date_contract);
        $moneyInfo = MoneyInfo::query()->where('contract_id', $contract->id)
            ->whereIn('type', [MoneyInfo::VOUCHER_CONTRACT, MoneyInfo::VOUCHER_ROOM_PRICE])
            ->latest('id')
            ->first();

        if ($moneyInfo) {
            $moneyDetail = MoneyDetail::query()->where('money_info_id', $moneyInfo->id)->first();

            if ($moneyDetail) {
                $firstMoneyInfo = Carbon::createFromFormat('Y-m-d', $moneyDetail->start_date);
                $secondMoneyInfo = Carbon::createFromFormat('Y-m-d', $moneyDetail->end_date);

                $diffMoneyInfo = $secondMoneyInfo->diffInDays($firstMoneyInfo) + 1;
                $firstMoneyInfo = $firstMoneyInfo->format('d/m/Y');
                $secondMoneyInfo = $secondMoneyInfo->format('d/m/Y');
            }

            $amountMoneyInfo = number_format($moneyInfo->amount, 0, '.', '.');
            $amountMoneyInfoText = $f->format($amountMoneyInfo) . ' đồng';

            $firstAmountMoneyInfo = number_format($moneyInfo->amount + $contract->deposit, 0, '.', '.');
            $firstAmountMoneyInfoText = $f->format($moneyInfo->amount + $contract->deposit) . ' đồng';
        }
        $customDeposit = 0;
        $remainDeposit = 0;
        $reserveId = $contract->reserve_id;
        if (!empty($reserveId)) {
            $reserve = RoomReservation::withTrashed()->find($reserveId);
            if ($reserve) {
                $customDeposit = $reserve->deposit;
            }
        }
        if ($moneyInfo) {
            $remainDeposit = $moneyInfo->amount + $contract->deposit - $customDeposit;
        }


        //Xử lý riêng cho cityland
        if ($contract->hostel->owner->id == 8724) {
            $moneyInfos = MoneyInfo::query()->where('contract_id', $contract->id)
                ->whereIn('type', [MoneyInfo::VOUCHER_CONTRACT, MoneyInfo::VOUCHER_ROOM_PRICE])
                ->latest('id')
                ->take(2)
                ->get();

            if ($contract->start_date->day >= $contract->day_collect) {
                $moneyInfos = MoneyInfo::query()->where('contract_id', $contract->id)
                    ->whereIn('type', [
                        MoneyInfo::VOUCHER_CONTRACT,
                        MoneyInfo::VOUCHER_ROOM_PRICE
                    ])
                    ->latest('id')
                    ->take(1)
                    ->get();
            }

            $moneyInfos = $moneyInfos->sortBy(function ($item) {
                return $item->id;
            });

            //	dd($contract->room_price);
            $remainDeposit = $moneyInfos->sum(function ($item) {
                    return $item->amount;
                }) + $contract->room_price * 2 - $customDeposit;
            $cityLandDepositBlock = view('admin2.contract.cityland_contract_deposit', compact('moneyInfos', 'contract', 'customDeposit', 'remainDeposit'))->render();
        }
        $deposit = $contract->deposit;
        $doubleDeposit = $contract->deposit;
        $depositText = ucfirst($f->format($deposit)) . ' đồng';
        $remainDepositText = $f->format($remainDeposit) . ' đồng';

        $contractTemplate = str_replace('{RemainDeposit}', number_format($remainDeposit, 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('{Deposit}', number_format($deposit, 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('{DepositText}', $depositText, $contractTemplate);
        $contractTemplate = str_replace('{CustomDeposit}', number_format($customDeposit, 0, '.', '.'), $contractTemplate);

        if (isset($cityLandDepositBlock)) {
            $contractTemplate = str_replace('{CityLandDepositBlock}', $cityLandDepositBlock, $contractTemplate);
        }

        //xu ly cho thland
        $fees = ContractFee::query()->where('contract_id', $contract->id)->has('fee')->get();
        $serviceFees = view('admin2.contract.thland_service_fee', compact('fees'))->render();

        $contractTemplate = str_replace('{NumberRenters}', Functions::calculateNumberRenter($contract->room), $contractTemplate);
        $contractTemplate = str_replace('{MaxRenters}', $contract->room->max_renters, $contractTemplate);
        $contractTemplate = str_replace('{RenterName}', $customerName, $contractTemplate);
        $contractTemplate = str_replace('{RenterEmail}', $renterEmail, $contractTemplate);
        $contractTemplate = str_replace('{CustomerName}', $customerName, $contractTemplate);
        $contractTemplate = str_replace('{OwnerName}', $ownerName, $contractTemplate);
        $contractTemplate = str_replace('{OwnerPhone}', $ownerPhone, $contractTemplate);
        $contractTemplate = str_replace('{OwnerAddress}', $ownerAddress, $contractTemplate);
        $contractTemplate = str_replace('{OwnerIdNumber}', $ownerIdNumber, $contractTemplate);
        $contractTemplate = str_replace('{ContractDeposit}', $contractDeposit, $contractTemplate);
        $contractTemplate = str_replace('{ContractDepositText}', $contractDepositText, $contractTemplate);
        $contractTemplate = str_replace('<p>{ServiceFees}</p>', $serviceFees, $contractTemplate);
        $contractTemplate = str_replace('{DiffYear}', $diffYear, $contractTemplate);
        $contractTemplate = str_replace('{DiffMonth}', $diffMonth, $contractTemplate);

        $contractTemplate = str_replace('{RenterIdNumber}', $renterIdNumber, $contractTemplate);
        $contractTemplate = str_replace('{RenterIdNumberLocation}', $renterIdNumberLocation, $contractTemplate);
        $contractTemplate = str_replace('{RenterIdNumberDate}', $renterIdNumberDate, $contractTemplate);
        $contractTemplate = str_replace('{RenterAddress}', $renterAddress, $contractTemplate);
        $contractTemplate = str_replace('{RenterPhone}', $renterPhone, $contractTemplate);
        $contractTemplate = str_replace('{RoomName}', $roomName, $contractTemplate);
        $contractTemplate = str_replace('{BedName}', $bedName, $contractTemplate);
        $contractTemplate = str_replace('{RoomSize}', $roomSize, $contractTemplate);
        $contractTemplate = str_replace('{RoomFloor}', $roomFloor, $contractTemplate);

        $contractTemplate = str_replace('{RoomPrice}', $roomPrice, $contractTemplate);
        $contractTemplate = str_replace('{RoomPriceText}', $roomPriceText, $contractTemplate);
        $contractTemplate = str_replace('{HostelAddress}', $hostelAddress, $contractTemplate);
        $contractTemplate = str_replace('{Period}', $period, $contractTemplate);
        $contractTemplate = str_replace('{OwnerBirthYear}', $ownerBirthYear, $contractTemplate);
        $contractTemplate = str_replace('{RenterBirthYear}', $renterBirthYear, $contractTemplate);
        $contractTemplate = str_replace('{HostelAddress}', $contract->hostel->address, $contractTemplate);


        $contractTemplate = str_replace('{FirstMoneyInfo}', $firstMoneyInfo, $contractTemplate);
        $contractTemplate = str_replace('{SecondMoneyInfo}', $secondMoneyInfo, $contractTemplate);
        $contractTemplate = str_replace('{DiffMoneyInfo}', $diffMoneyInfo, $contractTemplate);
        $contractTemplate = str_replace('{AmountMoneyInfo}', $amountMoneyInfo, $contractTemplate);
        $contractTemplate = str_replace('{AmountMoneyInfoText}', $amountMoneyInfoText, $contractTemplate);
        $contractTemplate = str_replace('{FirstAmountMoneyInfo}', $firstAmountMoneyInfo, $contractTemplate);
        $contractTemplate = str_replace('{FirstAmountMoneyInfoText}', $firstAmountMoneyInfoText, $contractTemplate);
        $contractTemplate = str_replace('{RenterLocation}', $location, $contractTemplate);


        $contractTemplate = str_replace('{DiffMonths}', $diffMonth, $contractTemplate);


        $contractTemplate = str_replace('{StartDay}', $startDay, $contractTemplate);
        $contractTemplate = str_replace('{StartMonth}', $startMonth, $contractTemplate);
        $contractTemplate = str_replace('{StartYear}', $startYear, $contractTemplate);

        $contractTemplate = str_replace('{EndDay}', $endDay, $contractTemplate);
        $contractTemplate = str_replace('{EndMonth}', $endMonth, $contractTemplate);
        $contractTemplate = str_replace('{EndYear}', $endYear, $contractTemplate);
        $contractTemplate = str_replace('{DayCollect}', $contract->day_collect, $contractTemplate);
        $contractTemplate = str_replace('{DeadlineEndDate}', $contract->end_date->subDay(30)->format('d/m/Y'), $contractTemplate);


        $contractTemplate = str_replace('{NowDay}', $contract->created_at->day, $contractTemplate);
        $contractTemplate = str_replace('{NowMonth}', $contract->created_at->month, $contractTemplate);
        $contractTemplate = str_replace('{NowYear}', $contract->created_at->year, $contractTemplate);

        $renters = User::query()->select(\DB::raw('users.*, renter_rooms.date_joined, renter_rooms.contract_id'))
            ->join('renter_rooms', 'users.id', '=', 'renter_rooms.user_id')
            ->whereNull('renter_rooms.deleted_at')
            ->where('renter_rooms.room_id', $contract->room->id)->get();
        $bikes = RenterBike::query()->where('room_id', $contract->room->id)->get();
        $numberBikes = $bikes->count();

        //	$rentersView = str_replace('<br/>', "\r\n \r\n", view('admin2.contract.renters_print', compact('renters'))->render());
        $rentersView = view('admin2.contract.renters_print', compact('renters', 'numberBikes'))->render();
        $items = Item::query()->join('room_items', 'items.id', '=', 'room_items.item_id')
            ->where('room_id', $contract->room->id)
            ->get();
        if ($contract->hostel->owner->id == 24822 || $contract->hostel->owner->id == 56626) //fix cho zeta
        {
            $rentersView = view('admin2.contract.zeta_renters', compact('renters', 'numberBikes'))->render();
            $bikesView = view('admin2.contract.zeta_bikes', compact('bikes'))->render();
            $zetaItems = view('admin2.contract.zeta_items', compact('items'))->render();
            $contractTemplate = str_replace('{Bikes}', $bikesView, $contractTemplate);
            $contractTemplate = str_replace('{ZetaItems}', $zetaItems, $contractTemplate);
            $contractTemplate = str_replace('{ZetaRenters}', $rentersView, $contractTemplate);
        }

        $electricPrice = 0;
        $waterPrice = 0;
        $hostelFee = HostelFee::query()->where('type', HostelFee::ELECTRIC)
            ->where('hostel_id', $contract->hostel->id)
            ->first();

        $hostelFeeWater = HostelFee::query()->where('type', HostelFee::WATER)
            ->where('hostel_id', $contract->hostel->id)
            ->first();

        if ($hostelFee) {
            $electric = ElectricQuota::query()->where('hostel_id', $contract->hostel->id)
                ->where('fee_id', $hostelFee->id)
                ->first();

        } else {
            $electric = ElectricQuota::query()
                ->where('hostel_id', $contract->hostel->id)
                ->first();

        }

        if ($hostelFeeWater) {
            $water = WaterQuota::query()->where('hostel_id', $contract->hostel->id)
                ->where('fee_id', $hostelFeeWater->id)
                ->first();
        } else {
            $water = WaterQuota::query()->where('hostel_id', $contract->hostel->id)->first();
        }

        if ($electric) {
            $electricPrice = $electric->price_quota_1;
        }

        if ($water) {
            $waterPrice = $water->price_quota_1;
        }

        $itemsView = view('admin2.contract.room_items_print', compact('items'))->render();

        $fees = ContractFee::query()->join('hostel_fees', 'contract_fees.fee_id', '=', 'hostel_fees.id')
            ->where('contract_id', $contract->id)
            ->get();
        $serviceView = view('admin2.contract.service_print', compact('fees', 'electricPrice', 'waterPrice'))->render();
        $initElectric = 0;
        $initWater = 0;
        foreach ($fees as $feeItem) {
            if ($feeItem->type == HostelFee::ELECTRIC) {
                $initElectric = $feeItem->qty;
            } else if ($feeItem->type == HostelFee::WATER) {
                $initWater = $feeItem->qty;
            }
        }

        $contractTemplate = str_replace('{ElectricPrice}', number_format($electricPrice, 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('{WaterPrice}', number_format($waterPrice, 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('{InitElectric}', number_format($initElectric, 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('{InitWater}', number_format($initWater, 0, '.', '.'), $contractTemplate);

        if ($contract->hostel->owner->id == 8724) {
            $contractTemplate = str_replace('<p>{Assets}</p>', view('admin2.contract.room_assets')->render(), $contractTemplate);
        } else {
            $items = \DB::table('room_items')->where('room_id', $contract->room_id)->get();
            //dd($items);
            $contractTemplate = str_replace('<p>{Assets}</p>', view('admin2.contract.room_assets_2', compact('items'))->render(), $contractTemplate);
        }


        $numberAdult = 0;
        $numberChildren = 0;

        $roomId = $contract->room->id;
        $renters = RenterRoom::query()->where('room_id', $roomId)
            ->with('renter')
            ->get();
        foreach ($renters as $renter) {
            $renterItem = $renter->renter;
            if (empty($renterItem->birthday)) {
                $numberAdult++;
            } else {
                $age = Carbon::now()->diffInYears($renterItem->birthday);
                if ($age >= 12) {
                    $numberAdult++;
                } else {
                    $numberChildren++;
                }
            }
        }

        $contractTemplate = str_replace('{NumberPeople}', number_format($renters->count(), 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('{NumberAdult}', number_format($numberAdult, 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('{NumberChildren}', number_format($numberChildren, 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('<p>{Renters}</p>', $rentersView, $contractTemplate);
        $contractTemplate = str_replace('<p>{Items}</p>', $itemsView, $contractTemplate);
        $contractTemplate = str_replace('<p>{Services}</p>', $serviceView, $contractTemplate);
        $contractTemplate = str_replace('</p> <p', '</p><p', $contractTemplate);
        $configHostel = ConfigHostel::query()->where('hostel_id', $contract->hostel_id)->first();

        if ($configHostel) {
            if (!empty($configHostel->signature)) {

                $signature = '<img style="max-height: 100px" src="https://itro.vn/files/' . $configHostel->signature . '" />';

                $signatureImageUrl = "https://itro.vn/files/". $configHostel->signature;
                $arrContextOptions= [
                    'ssl' => [
                        'verify_peer'=> false,
                        'verify_peer_name'=> false,
                    ],
                ];
                $signatureImage = false;
                try {
                    $signatureImage = file_get_contents($signatureImageUrl,false, stream_context_create($arrContextOptions));
                } catch(\Exception $e) {
                    $signatureImage = false;
                }
//                try {
//                    $signatureImage = file_get_contents($signatureImageUrl,false, stream_context_create($arrContextOptions));
//                } catch (e) {
//                    $signatureImage = false;
//                }

                if ($signatureImage !== false) {
                    $signature = '<img style="height: 100px" src="data:image/jpeg;base64,'.base64_encode($signatureImage) . '" />';
                }

//                if (!$isDownload) {
                    $contractTemplate = str_replace('{Signature}', $signature, $contractTemplate);
//                }
            } else {
                $contractTemplate = str_replace('{Signature}', '', $contractTemplate);
            }
        } else {
            $contractTemplate = str_replace('{Signature}', '', $contractTemplate);
        }
        if (!empty($contract->renter_signature)) {
            $renterSignature = '<img style="height: 100px" src="https://itro.vn/files/' . $contract->renter_signature . '" />';

            $renterSignatureImageUrl = "https://itro.vn/files/". $contract->renter_signature;

            $arrContextOptions= [
                'ssl' => [
                    'verify_peer'=> false,
                    'verify_peer_name'=> false,
                ],
            ];
            $renterSignatureImage = false;
            try {
                $renterSignatureImage = file_get_contents($renterSignatureImageUrl,false, stream_context_create($arrContextOptions));
            } catch(\Exception $e) {
                $renterSignatureImage = false;
            }

            if ($renterSignatureImage !== false) {
                $renterSignature = '<img style="height: 100px" src="data:image/jpeg;base64,'.base64_encode($renterSignatureImage) . '" />';
            }

//            if (!$isDownload) {
                $contractTemplate = str_replace('{RenterSignature}', $renterSignature, $contractTemplate);
//            }
        } else {
            $contractTemplate = str_replace('{RenterSignature}', '', $contractTemplate);
        }
        $contractTemplate = self::stripInvalidXml($contractTemplate);

        return $contractTemplate;
    }


    public static function getContractPreview(array $params, $contractTemplate)
    {
        $hostelId = $params['hostel_id'];
        $roomId = $params['room_id'];
        $startDate = $params['start_date'];
        $endDate = $params['end_date'];
        $customerName = $params['customer_name'];
        $renterIdNumber = $params['id_number'];
        $roomPriceInput = $params['room_price'];
        $period = $params['period'];
        $renterAddress = $params['renter_address'];
        $renterIdNumberDate = $params['renter_id_number_date'];
        $renterIdNumberLocation = $params['renter_id_number_location'];
        $renterPhone = $params['phone'];
        $renterBirthday = $params['renter_birthday'];
        $dateContract = $params['date_contract'];
        $dayCollect = $params['day_collect'];

        $startDate = Carbon::createFromFormat('d/m/Y', $startDate);
        $endDate = Carbon::createFromFormat('d/m/Y', $endDate);
        $dateContract = Carbon::createFromFormat('d/m/Y', $dateContract);


        $hostel = Hostel::find($hostelId);
        $room = Room::find($roomId);

        $ownerName = $hostel->owner->name;
        $ownerPhone = $hostel->owner->phone;
        $ownerAddress = $hostel->owner->address_text;
        $ownerIdNumber = $hostel->owner_id_number;

        $hostelAddress = $hostel->address_text;
        $ownerBirthYear = $hostel->owner->birthday;
        try {
            $renterBirthYear = !empty($renterBirthday) ? Carbon::createFromFormat('d/m/Y', $renterBirthday)->format('d/m/Y') : ' ......................';
        } catch (\Exception $e) {
            $renterBirthYear = $renterBirthday;
        }
        
        try {
            $renterBirthYear = !empty($renter->birthday) ? Carbon::createFromFormat('Y-m-d H:i:s', $renter->birthday)->format('d/m/Y') : '       ...';
        } catch (\Exception $e) {
            $renterBirthYear = $renter->birthday;
        }

        $startDay = $startDate->copy()->day;
        $startMonth = $startDate->copy()->month;
        $startYear = $startDate->copy()->year;

        $endDay = $endDate->copy()->day;
        $endMonth = $endDate->copy()->month;
        $endYear = $endDate->copy()->year;

        $diffYear = $endDate->copy()->diffInYears($startDate->copy());
        $diffMonth = $endDate->copy()->diffInMonths($startDate->copy());

        $f = new \NumberFormatter('vi_VN', \NumberFormatter::SPELLOUT);

        $roomPriceText = $f->format($roomPriceInput) . ' đồng';

        $roomPrice = number_format($roomPriceInput, 0, '.', '.');
        $roomName = $room->name;
        $roomSize = $room->size;


        $contractTemplate = str_replace('{RenterName}', $customerName, $contractTemplate);

        $contractTemplate = str_replace('{CustomerName}', $customerName, $contractTemplate);
        $contractTemplate = str_replace('{OwnerName}', $ownerName, $contractTemplate);
        $contractTemplate = str_replace('{OwnerPhone}', $ownerPhone, $contractTemplate);
        $contractTemplate = str_replace('{OwnerAddress}', $ownerAddress, $contractTemplate);
        $contractTemplate = str_replace('{OwnerIdNumber}', $ownerIdNumber, $contractTemplate);

        $contractTemplate = str_replace('{DiffYear}', $diffYear, $contractTemplate);
        $contractTemplate = str_replace('{DiffMonth}', $diffMonth, $contractTemplate);

        $contractTemplate = str_replace('{RenterIdNumber}', $renterIdNumber, $contractTemplate);
        $contractTemplate = str_replace('{RenterIdNumberLocation}', $renterIdNumberLocation, $contractTemplate);
        $contractTemplate = str_replace('{RenterIdNumberDate}', $renterIdNumberDate, $contractTemplate);
        $contractTemplate = str_replace('{RenterAddress}', $renterAddress, $contractTemplate);
        $contractTemplate = str_replace('{RenterPhone}', $renterPhone, $contractTemplate);
        $contractTemplate = str_replace('{RoomName}', $roomName, $contractTemplate);
        $contractTemplate = str_replace('{RoomSize}', $roomSize, $contractTemplate);

        $contractTemplate = str_replace('{RoomPrice}', $roomPrice, $contractTemplate);
        $contractTemplate = str_replace('{RoomPriceText}', $roomPriceText, $contractTemplate);
        $contractTemplate = str_replace('{HostelAddress}', $hostelAddress, $contractTemplate);
        $contractTemplate = str_replace('{Period}', $period, $contractTemplate);
        $contractTemplate = str_replace('{OwnerBirthYear}', $ownerBirthYear, $contractTemplate);
        $contractTemplate = str_replace('{RenterBirthYear}', $renterBirthYear, $contractTemplate);
        $contractTemplate = str_replace('{HostelAddress}', $hostel->address, $contractTemplate);

        $config = Config::query()->where('owner_id', $hostel->owner_id)->first();
        if ($config) {
            if (!empty($config->logo)) {
                $contractTemplate = str_replace('{Logo}', '<img width="100" src="https://itro.vn/files/' . $config->logo . '" style="max-width: 100px" />', $contractTemplate);
            } else {
                $contractTemplate = str_replace('{Logo}', '<img width="100" src="https://itro.vn/frontend3/assets/img/logo.png" style="max-width: 100px" />', $contractTemplate);
            }
        } else {
            $contractTemplate = str_replace('{Logo}', '<img width="100" src="https://itro.vn/frontend3/assets/img/logo.png" style="max-width: 100px" />', $contractTemplate);
        }


        $firstMoneyInfo = '.............';
        $secondMoneyInfo = '............';
        $diffMoneyInfo = '.............';
        $amountMoneyInfo = '.............';
        $firstTimeAmount = '.............';
        $diffMonth = $endDate->copy()->diffInMonths($dateContract);
        $customDeposit = 0;
        $remainDeposit = 0;
        $deposit = 0;

        $contractTemplate = str_replace('{RemainDeposit}', number_format($remainDeposit, 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('{CustomDeposit}', number_format($customDeposit, 0, '.', '.'), $contractTemplate);

        if (isset($cityLandDepositBlock)) {
            $contractTemplate = str_replace('{CityLandDepositBlock}', $cityLandDepositBlock, $contractTemplate);
        }
        $contractTemplate = str_replace('{FirstMoneyInfo}', $firstMoneyInfo, $contractTemplate);
        $contractTemplate = str_replace('{SecondMoneyInfo}', $secondMoneyInfo, $contractTemplate);
        $contractTemplate = str_replace('{DiffMoneyInfo}', $diffMoneyInfo, $contractTemplate);
        $contractTemplate = str_replace('{AmountMoneyInfo}', $amountMoneyInfo, $contractTemplate);

        $contractTemplate = str_replace('{DiffMonths}', $diffMonth, $contractTemplate);


        $contractTemplate = str_replace('{StartDay}', $startDay, $contractTemplate);
        $contractTemplate = str_replace('{StartMonth}', $startMonth, $contractTemplate);
        $contractTemplate = str_replace('{StartYear}', $startYear, $contractTemplate);

        $contractTemplate = str_replace('{EndDay}', $endDay, $contractTemplate);
        $contractTemplate = str_replace('{EndMonth}', $endMonth, $contractTemplate);
        $contractTemplate = str_replace('{EndYear}', $endYear, $contractTemplate);
        $contractTemplate = str_replace('{DayCollect}', $dayCollect, $contractTemplate);
        $contractTemplate = str_replace('{DeadlineEndDate}', $endDate->copy()->subDay(30)->format('d/m/Y'), $contractTemplate);


        $contractTemplate = str_replace('{NowDay}', Carbon::now()->day, $contractTemplate);
        $contractTemplate = str_replace('{NowMonth}', Carbon::now()->month, $contractTemplate);
        $contractTemplate = str_replace('{NowYear}', Carbon::now()->year, $contractTemplate);

        $renters = User::query()->select(\DB::raw('users.*, renter_rooms.date_joined, renter_rooms.contract_id'))
            ->join('renter_rooms', 'users.id', '=', 'renter_rooms.user_id')
            ->whereNull('renter_rooms.deleted_at')
            ->where('renter_rooms.room_id', $room->id)->get();
        $numberBikes = RenterBike::query()->where('room_id', $room->id)->count();

        //	$rentersView = str_replace('<br/>', "\r\n \r\n", view('admin2.contract.renters_print', compact('renters'))->render());
        $rentersView = view('admin2.contract.renters_print', compact('renters', 'numberBikes'))->render();

        $items = Item::query()->join('room_items', 'items.id', '=', 'room_items.item_id')
            ->where('room_id', $room->id)
            ->get();

        $electricPrice = 0;
        $waterPrice = 0;
        $hostelFee = HostelFee::query()->where('type', HostelFee::ELECTRIC)
            ->where('hostel_id', $hostel->id)
            ->first();

        $hostelFeeWater = HostelFee::query()->where('type', HostelFee::WATER)
            ->where('hostel_id', $hostel->id)
            ->first();

        if ($hostelFee) {
            $electric = ElectricQuota::query()->where('hostel_id', $hostel->id)
                ->where('fee_id', $hostelFee->id)
                ->first();

        } else {
            $electric = ElectricQuota::query()
                ->where('hostel_id', $hostel->id)
                ->first();

        }

        if ($hostelFeeWater) {
            $water = WaterQuota::query()->where('hostel_id', $hostel->id)
                ->where('fee_id', $hostelFeeWater->id)
                ->first();
        } else {
            $water = WaterQuota::query()->where('hostel_id', $hostel->id)->first();
        }

        if ($electric) {
            $electricPrice = $electric->price_quota_1;
        }

        if ($water) {
            $waterPrice = $water->price_quota_1;
        }

        $itemsView = view('admin2.contract.room_items_print', compact('items'))->render();

        $fees = ContractFee::query()->join('hostel_fees', 'contract_fees.fee_id', '=', 'hostel_fees.id')
            ->where('contract_id', $contract->id)
            ->get();
        $serviceView = view('admin2.contract.service_print', compact('fees', 'electricPrice', 'waterPrice'))->render();
        $initElectric = 0;
        $initWater = 0;
        foreach ($fees as $feeItem) {
            if ($feeItem->type == HostelFee::ELECTRIC) {
                $initElectric = $feeItem->qty;
            } else if ($feeItem->type == HostelFee::WATER) {
                $initWater = $feeItem->qty;
            }
        }

        $contractTemplate = str_replace('{ElectricPrice}', number_format($electricPrice, 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('{WaterPrice}', number_format($waterPrice, 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('{InitElectric}', number_format($initElectric, 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('{InitWater}', number_format($initWater, 0, '.', '.'), $contractTemplate);

        $contractTemplate = str_replace('<p>{Assets}</p>', view('admin2.contract.room_assets')->render(), $contractTemplate);


        $numberAdult = 0;
        $numberChildren = 0;

        $roomId = $contract->room->id;
        $renters = RenterRoom::query()->where('room_id', $roomId)
            ->with('renter')
            ->get();
        foreach ($renters as $renter) {
            $renterItem = $renter->renter;
            if (empty($renterItem->birthday)) {
                $numberAdult++;
            } else {
                $age = Carbon::now()->diffInYears($renterItem->birthday);
                if ($age >= 12) {
                    $numberAdult++;
                } else {
                    $numberChildren++;
                }
            }
        }

        $contractTemplate = str_replace('{NumberPeople}', number_format($renters->count(), 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('{NumberAdult}', number_format($numberAdult, 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('{NumberChildren}', number_format($numberChildren, 0, '.', '.'), $contractTemplate);
        $contractTemplate = str_replace('<p>{Renters}</p>', $rentersView, $contractTemplate);
        $contractTemplate = str_replace('<p>{Items}</p>', $itemsView, $contractTemplate);
        $contractTemplate = str_replace('<p>{Services}</p>', $serviceView, $contractTemplate);
        $contractTemplate = str_replace('</p> <p', '</p><p', $contractTemplate);
        $configHostel = ConfigHostel::query()->where('hostel_id', $contract->hostel_id)->first();

//        if ($configHostel) {
//            if (!empty($configHostel->signature)) {
//                $signature = '<img style="max-width: 150px" src="https://itro.vn/files/' . $configHostel->signature . '" />';
//
//                if (!$isDownload) {
//                    $contractTemplate = str_replace('{Signature}', $signature, $contractTemplate);
//                }
//            } else {
//                $contractTemplate = str_replace('{Signature}', '', $contractTemplate);
//            }
//        } else {
//            $contractTemplate = str_replace('{Signature}', '', $contractTemplate);
//        }
//        if (!empty($contract->renter_signature)) {
//            $renterSignature = '<img style="max-width: 150px" src="https://itro.vn/files/' . $contract->renter_signature . '" />';
//            if (!$isDownload) {
//                $contractTemplate = str_replace('{RenterSignature}', $renterSignature, $contractTemplate);
//            }
//        } else {
//            $contractTemplate = str_replace('{RenterSignature}', '', $contractTemplate);
//        }
        if ($configHostel) {
            if (!empty($configHostel->signature)) {

                $signature = '<img style="max-height: 100px" src="https://itro.vn/files/' . $configHostel->signature . '" />';

                $signatureImageUrl = "https://itro.vn/files/". $configHostel->signature;
                $arrContextOptions= [
                    'ssl' => [
                        'verify_peer'=> false,
                        'verify_peer_name'=> false,
                    ],
                ];
                $signatureImage = file_get_contents($signatureImageUrl,false, stream_context_create($arrContextOptions));
                if ($signatureImage !== false) {
                    $signature = '<img style="height: 100px" src="data:image/jpeg;base64,'.base64_encode($signatureImage) . '" />';
                }

//                if (!$isDownload) {
                    $contractTemplate = str_replace('{Signature}', $signature, $contractTemplate);
//                }
            } else {
                $contractTemplate = str_replace('{Signature}', '', $contractTemplate);
            }
        } else {
            $contractTemplate = str_replace('{Signature}', '', $contractTemplate);
        }
        if (!empty($contract->renter_signature)) {
            $renterSignature = '<img style="height: 100px" src="https://itro.vn/files/' . $contract->renter_signature . '" />';

            $renterSignatureImageUrl = "https://itro.vn/files/". $contract->renter_signature;
            $arrContextOptions= [
                'ssl' => [
                    'verify_peer'=> false,
                    'verify_peer_name'=> false,
                ],
            ];
            $renterSignatureImage = file_get_contents($renterSignatureImageUrl,false, stream_context_create($arrContextOptions));
            if ($renterSignatureImage !== false) {
                $renterSignature = '<img style="height: 100px" src="data:image/jpeg;base64,'.base64_encode($renterSignatureImage) . '" />';
            }

//            if (!$isDownload) {
                $contractTemplate = str_replace('{RenterSignature}', $renterSignature, $contractTemplate);
//            }
        } else {
            $contractTemplate = str_replace('{RenterSignature}', '', $contractTemplate);
        }
        $contractTemplate = self::stripInvalidXml($contractTemplate);

        return $contractTemplate;
    }


    public static function getVoucherTemplate($voucherTemplate)
    {
        $table = view('admin2.money.print_bill.table')->render();
        $voucherTemplate = str_replace('{Table}', $table, $voucherTemplate);

        return $voucherTemplate;

    }


    /**
     * Calculates the great-circle distance between two points, with
     * the Haversine formula.
     *
     * @param float $latitudeFrom Latitude of start point in [deg decimal]
     * @param float $longitudeFrom Longitude of start point in [deg decimal]
     * @param float $latitudeTo Latitude of target point in [deg decimal]
     * @param float $longitudeTo Longitude of target point in [deg decimal]
     * @param float $earthRadius Mean earth radius in [m]
     *
     * @return float Distance between points in [m] (same as earthRadius)
     */
    public static function haversineGreatCircleDistance(
        $latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 6371000
    )
    {
        // convert from degrees to radians
        $latFrom = deg2rad($latitudeFrom);
        $lonFrom = deg2rad($longitudeFrom);
        $latTo = deg2rad($latitudeTo);
        $lonTo = deg2rad($longitudeTo);

        $latDelta = $latTo - $latFrom;
        $lonDelta = $lonTo - $lonFrom;

        $angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) +
                cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));

        return $angle * $earthRadius;
    }

    public static function censorText($target)
    {
        $count = strlen($target) - 2;
        if ($count <= 0) {
            $count = 1;
        }
        $output = substr_replace($target, str_repeat('*', $count), 1, $count);

        return $output;
    }


    public static function statFromMoneyInfo(Carbon $from, Carbon $to, $cost, $dayCollect = null, $period = 1)
    {
        $retVal = [];
//		if ( $period == 1 ) {
//			if ( self::checkFullPeriod( $from, $to, $dayCollect ) ) {
//				return [
//					[
//						'from'  => $from->copy()->toDateString(),
//						'to'    => $to->copy()->toDateString(),
//						'month' => $from->copy()->month,
//						'year'  => $from->copy()->year,
//						'money' => $cost
//					]
//				];
//			}
//		}
        while ($from->lessThanOrEqualTo($to)) {
            if ($period > 1) {
                $month = $from->copy()->firstOfMonth()->addMonth($period - 1)->month;
                $year = $from->copy()->firstOfMonth()->addMonth($period - 1)->year;
                if ($dayCollect <= $from->copy()->day) {
                    $month = $from->copy()->firstOfMonth()->addMonth($period)->month;
                    $year = $from->copy()->firstOfMonth()->addMonth($period)->year;
                }
            } else {
                $month = $from->copy()->month;
                $year = $from->copy()->year;
                if ($from->copy()->month == $to->copy()->month && $from->copy()->year == $to->copy()->year) {
                    $month = $from->copy()->month;
                    $year = $from->copy()->year;
                    $dayCollect = $to->copy()->day;
                } else {
                    if ($dayCollect <= $from->copy()->day) {

                        $month = $from->copy()->firstOfMonth()->addMonth()->month;
                        $year = $from->copy()->firstOfMonth()->addMonth()->year;
                    }
                }
            }


            if (checkdate($month, $dayCollect, $year)) {
                $toTemp = Carbon::createFromFormat('d-m-Y', $dayCollect . '-' . $month . '-' . $year);

            } else {

                $tempDayCollect = Carbon::createFromFormat('d-m-Y', '01-' . $month . '-' . $year)->lastOfMonth()->day;
                $toTemp = Carbon::createFromFormat('d-m-Y', $tempDayCollect . '-' . $month . '-' . $year);
            }

//            dump($money);
//                dump($to->toDateString());

            if ($toTemp->greaterThan($to)) {
                $toTemp = $to->copy();
            }

            if (self::checkFullPeriod($from->copy(), $toTemp->copy(), $dayCollect)) {
                $money = $cost;
            } else {
                $money = self::calculateMoneyInRange3($from->copy(), $toTemp->copy(), $cost, $dayCollect);
            }


            $retVal[] = [
                'from' => $from->copy()->toDateString(),
                'to' => $toTemp->copy()->toDateString(),
                'month' => $from->copy()->month,
                'year' => $from->copy()->year,
                'money' => $money
            ];
            $from = $toTemp->copy()->addDay();
        }

        return $retVal;
    }

    public static function syncCrm($item)
    {

        $user = User::find($item->id);
        if (!$user) {
            return;
        }

        if (empty($user->phone)) {
            return;
        }

        if ($user->type != User::OWNER) {
            return;
        }

        $check = \DB::connection('crm')->table('tblleads')
            ->where('phonenumber', $item->phone)
            ->count();

        if ($check == 0) {
            $leadId = \DB::connection('crm')->table('tblleads')
                ->insertGetId([
                    'phonenumber' => $item->phone,
                    'address' => $item->address,
                    'dateadded' => Carbon::now()->toDateTimeString(),
                    'country' => 243,
                    'name' => $item->name_text,
                    'email' => $item->email,
                    'status' => 7,
                    'source' => 3,
                ]);

            $tag1 = \DB::connection('crm')->table('tbltags')
                ->insertGetId([
                    'name' => 'Ngày đăng ký: ' . $item->created_at->format('d/m/Y')
                ]);

            $tag2 = \DB::connection('crm')->table('tbltags')
                ->insertGetId([
                    'name' => 'Nguồn đăng ký: ' . $item->from_text
                ]);

            $tag3 = \DB::connection('crm')->table('tbltags')
                ->insertGetId([
                    'name' => 'Phân hệ: ' . $item->branch_app_text
                ]);

            \DB::connection('crm')->table('tbltaggables')
                ->insertGetId([
                    'rel_id' => $leadId,
                    'rel_type' => 'lead',
                    'tag_id' => $tag1,
                    'tag_order' => 1,
                ]);


            \DB::connection('crm')->table('tbltaggables')
                ->insertGetId([
                    'rel_id' => $leadId,
                    'rel_type' => 'lead',
                    'tag_id' => $tag2,
                    'tag_order' => 2,
                ]);

            \DB::connection('crm')->table('tbltaggables')
                ->insertGetId([
                    'rel_id' => $leadId,
                    'rel_type' => 'lead',
                    'tag_id' => $tag3,
                    'tag_order' => 3,
                ]);
        }
    }

    public static function getStartEndElectricWater(HostelFee $hostelFee, Contract $contract, Room $room, $month)
    {
        $startElectric = 0;
        $startWater = 0;
        $endElectric = 0;
        $endWater = 0;

        try {
            $startTime = Carbon::createFromFormat('d/m/Y', '01/' . $month)->startOfMonth()->startOfDay()->toDateString();
            $endTime = Carbon::createFromFormat('d/m/Y', '01/' . $month)->endOfMonth()->endOfDay()->toDateString();
        } catch (\Exception $exception) {
            return [
                'start_electric' => $startElectric,
                'start_water' => $startWater,
                'end_electric' => $endElectric,
                'end_water' => $endWater
            ];
        }

        $item = MoneyInfo::where('room_id', $room->id)
            ->where('type', MoneyInfo::VOUCHER_SERVICE)
            ->validate($contract->id)->whereBetween(
                'date_action', [$startTime, $endTime]
            )->first();

        $moneyDetail = null;
        if ($item) {
            $moneyDetail = MoneyDetail::where('money_info_id', $item->id)
                ->where('hostel_fee_id', $hostelFee->id)->first();
        }

        $info = null;
        
        

        if ($moneyDetail) {

            $info = json_decode($moneyDetail->qty, true);
            $startElectric = $info['start'];
            $startWater = $info['start'];

            $endElectric = $info['end'];
            $endWater = $info['end'];
            
        } else {

            $startTime = Carbon::createFromFormat('d/m/Y', '01/' . $month)->startOfMonth()->startOfDay()->toDateString();
            $endTime = Carbon::createFromFormat('d/m/Y', '01/' . $month)->endOfMonth()->endOfDay()->toDateString();

            $lastInfo = ElectricWater::where('hostel_id', $contract->room->hostel->id)
                ->where('room_id', $contract->room->id)
                ->whereBetween('date_action', [$startTime, $endTime])->latest()->first();
        }
        
        
        
        if (!is_array($info)) {
            if (isset($lastInfo)) {
                $startElectric = $lastInfo->start_electric;
                $startWater = $lastInfo->start_water;
                $endElectric = $lastInfo->end_electric;
                $endWater = $lastInfo->end_water;
                
            } else {

                $checkContracts = ContractFee::where('contract_id', $contract->id)->get();

                foreach ($checkContracts as $checkContract) {
                    $fee = $checkContract->fee_id;
                    $feeItem = HostelFee::find($fee);
                    if ($feeItem) {
                        if ($feeItem->type == HostelFee::ELECTRIC || $feeItem->type == HostelFee::ELECTRIC_BY_CLOCK) {
                            $startElectric = $checkContract->qty;
                            $endElectric = $checkContract->qty;
                            // dd($checkContract);
                        } else if ($feeItem->type == HostelFee::WATER || $feeItem->type == HostelFee::WATER_BY_CLOCK) {
                            $startWater = $checkContract->qty;
                            $endWater = $checkContract->qty;
                        }
                    }
                }
            }

        }
        

        return [
            'start_electric' => $startElectric,
            'start_water' => $startWater,
            'end_electric' => $endElectric,
            'end_water' => $endWater
        ];

    }

    public static function getElectric(Hostel $hostel)
    {
        $electricArr = [
            HostelFee::ELECTRIC_BY_CLOCK,
            HostelFee::ELECTRIC,
            HostelFee::ELECTRIC_BY_PEOPLE,
            HostelFee::ELECTRIC_DYNAMIC
        ];

        $electric = HostelFee::where('hostel_id', $hostel->id)
            ->whereIn('type', $electricArr);
        $electricCnt = clone $electric;
        $electricCnt = $electricCnt->count();
        if ($electricCnt == 0) {
            return 'Thỏa thuận';
        }

        if ($electricCnt > 1) {
            return 'Nhiều giá';
        }

        $itemElectric = $electric->first();
        if ($itemElectric) {
            if ($itemElectric->type == HostelFee::ELECTRIC) {

                $quota = ElectricQuota::where('hostel_id', $hostel->id)
                    ->where('fee_id', $itemElectric->id)->first();

                if ($quota) {
                    if (!empty($quota->price_quota_1)) {
                        if (!empty($quota->price_quota_2)) {
                            return 'Giá nhà nước';
                        }
                    }

                    return number_format($quota->price_quota_1, 0, '.', '.') . ' đ/KwH';
                }

                return 'Giá nhà nước';
            }

            if ($itemElectric->type == HostelFee::ELECTRIC_BY_PEOPLE) {
                return number_format($itemElectric->fee, 0, '.', '.') . ' đ/người';
            }

            if ($itemElectric->type == HostelFee::ELECTRIC_BY_CLOCK) {
                return number_format($itemElectric->fee, 0, '.', '.') . ' đ/KwH';
            }

            return 'Biến động';
        }
    }

    public static function getWater(Hostel $hostel)
    {
        $electricArr = [
            HostelFee::WATER_BY_CLOCK,
            HostelFee::WATER,
            HostelFee::WATER_BY_PEOPLE,
            HostelFee::WATER_DYNAMIC
        ];

        $water = HostelFee::where('hostel_id', $hostel->id)
            ->whereIn('type', $electricArr);
        $waterCnt = clone $water;
        $waterCnt = $waterCnt->count();
        if ($waterCnt == 0) {
            return 'Thỏa thuận';
        }

        if ($waterCnt > 1) {
            return 'Nhiều giá';
        }

        $itemWater = $water->first();
        if ($itemWater) {
            if ($itemWater->type == HostelFee::WATER) {
                $quota = WaterQuota::where('hostel_id', $hostel->id)
                    ->where('fee_id', $itemWater->id)->first();

                if ($quota) {
                    if (!empty($quota->price_quota_1)) {
                        if (!empty($quota->price_quota_2)) {
                            return 'Giá nhà nước';
                        }
                    }

                    return number_format($quota->price_quota_1, 0, '.', '.') . ' đ/Khối';
                }

                return 'Giá nhà nước';
            }

            if ($itemWater->type == HostelFee::WATER_BY_PEOPLE) {
                return number_format($itemWater->fee, 0, '.', '.') . ' đ/người';
            }

            if ($itemWater->type == HostelFee::WATER_BY_CLOCK) {
                return number_format($itemWater->fee, 0, '.', '.') . ' đ/Khối';
            }

            return 'Biến động';
        }
    }

    public static function getLatestDateAvailable(Hostel $hostel)
    {
        $room = Room::where('hostel_id', $hostel->id)
            ->where('is_empty', true)
            ->orderBy('date_available')
            ->first();
        if ($room) {
            return $room->date_available;
        }

        return 'Có thể ở ngay';
    }

    public static function getPriceMin($min)
    {
        $priceMin = 0;
        if ($min == 1) {
            $priceMin = 0;
        }

        if ($min == 2) {
            $priceMin = 2000000;
        }

        if ($min == 3) {
            $priceMin = 4000000;
        }

        if ($min == 4) {
            $priceMin = 10000000;
        }

        if ($min == 5) {
            $priceMin = 15000000;
        }

        return $priceMin;
    }

    public static function getPriceMax($max)
    {
        $priceMax = 0;
        if ($max == 1) {
            $priceMax = 2000000;
        }

        if ($max == 2) {
            $priceMax = 4000000;
        }

        if ($max == 3) {
            $priceMax = 10000000;
        }

        if ($max == 4) {
            $priceMax = 15000000;
        }

        if ($max == 5) {
            $priceMax = 1500000000;
        }

        return $priceMax;
    }

    public static function pushNotification($accountId, $title, $notificationId, $token, $content, $isAndroid, $payload)
    {

        $optionBuiler = new OptionsBuilder();
        $optionBuiler->setTimeToLive(60 * 20);

        $notificationBuilder = new PayloadNotificationBuilder($title);

        $badge = Functions::countBadge($accountId);

        $notificationBuilder->setBody($content)
            ->setBadge($badge)
            ->setSound('default');

        $dataBuilder = new PayloadDataBuilder();

        if (!empty($payload)) {
            $payloadArr = json_decode($payload, true);
        }

        $payloadArr['notification_id'] = $notificationId;

        if (!empty($payloadArr)) {
            if ($isAndroid == 'yes') {
                $payloadArr['title'] = $title;
                $payloadArr['badge'] = $badge;
                $payloadArr['body'] = $content;
            }

            $dataBuilder->addData($payloadArr);
        } else {

            if ($isAndroid == 'yes') {

                $payloadArr['title'] = null;
                $payloadArr['badge'] = null;
                $payloadArr['body'] = null;

            }

            $dataBuilder->addData([
                'type' => null,
                'id' => null
            ]);
        }

        $option = $optionBuiler->build();
        $notification = $notificationBuilder->build();

        $data = $dataBuilder->build();

        if ($isAndroid == 'yes') {

            $downstreamResponse = FCM::sendTo($token, $option, $notification, $data);

        } else {
            $downstreamResponse = FCM::sendTo($token, $option, $notification, $data);
        }

        if (!empty($downstreamResponse)) {
            \App\Models\Notification::find($notificationId)->forceFill([
                'status' => \App\Models\Notification::PUSHED
            ])->save();

            $downstreamResponse->numberSuccess();
            $downstreamResponse->numberFailure();
            $downstreamResponse->numberModification();

//return Array - you must remove all this tokens in your database
            $deleteTokens = $downstreamResponse->tokensToDelete();

            if (is_array($deleteTokens)) {

                foreach ($deleteTokens as $deleteToken) {
                    User::where('android_token', $deleteToken)->update([
                        'android_token' => null
                    ]);

                    User::where('ios_token', $deleteToken)->update([
                        'ios_token' => null
                    ]);
                }
            }

            $modifyTokens = $downstreamResponse->tokensToModify();

            if (is_array($modifyTokens)) {

                foreach ($modifyTokens as $oldToken => $modifyToken) {
                    User::where('android_token', $oldToken)->update([
                        'android_token' => $modifyToken
                    ]);

                    User::where('ios_token', $oldToken)->update([
                        'ios_token' => $modifyToken
                    ]);
                }
            }
        }

        return;

    }

    public static function moneyUnit()
    {
        $sign = \Illuminate\Support\Facades\Config::get('constants.MONEY_UNIT');
        if (auth('backend')->check()) {
            $user_id = auth('backend')->user()->id;
            $money = UserMoney::where('user_id', $user_id)->join('money_unit', 'user_money_unit.money_unit', '=', 'money_unit.id')->first();

            if (!empty($money)) {
                $sign = $money->sign;
            }
        }

        return $sign;
    }

    public static function getPackageFindHostel($user)
    {
        $owner = $user;
        if ($user->type == User::STAFF) {
            $owner = $user->owner;
        }

        if ($owner) {
            $userPackage = UserPackageFindHostel::query()->where('user_id', $owner->id)->first();
            if ($userPackage) {
                $package = $userPackage->package;

                return [
                    'id' => $package->id,
                    'name' => $package->name,
                    'price' => $package->price,
                    'number_interacts' => $package->number_interact,
                    'transaction_fee' => $package->transaction_fee,
                ];
            }
        }

        return null;
    }

    public static function getChargeOwner($userId)
    {
        $charge = option('charge_owner', 300);
        $package = UserPackageFindHostel::query()
            ->where('user_id', $userId)
            ->first();
        if ($package) {
            $charge = $package->transaction_fee / config('constants.COIN_VND');
        }

        return $charge;
    }

    public static function getNumberContractAndRoom(Hostel $hostel)
    {
        return $hostel->contracts->count()
            + $hostel->rooms()->doesntHave('contracts')->count()
            + 1;
    }

    public static function generateDynamicLink($param)
    {
        $url = $param['url'];
        $desc = isset($param['desc']) ? $param['desc'] : null;
        $title = isset($param['title']) ? $param['title'] : null;
        $image = isset($param['image']) ? $param['image'] : null;
        $factory = (new Factory())->withServiceAccount(storage_path('itro-b9c1a-firebase-adminsdk-c8xth-9487184f83.json'));

        $dynamicLinksDomain = 'https://itro.page.link';
        $dynamicLinks = $factory->createDynamicLinksService($dynamicLinksDomain);

        $action = CreateDynamicLink::forUrl($url)
            ->withDynamicLinkDomain($dynamicLinksDomain)
            ->withIOSInfo(
                IOSInfo::new()
                    ->withAppStoreId('1500516141')
                    ->withBundleId('com.meboo.app.timtro')
            )
            ->withAndroidInfo(
                AndroidInfo::new()
                    ->withPackageName('com.itro.findroom')
            )->withSocialMetaTagInfo(
                SocialMetaTagInfo::new()
                    ->withDescription($desc)
                    ->withTitle($title)
                    ->withImageLink($image)
            );

        $link = $dynamicLinks->createDynamicLink($action);

        return $link;
    }

    public static function generateDynamicLinkHostelPostCrawl(HostelPostCrawl $hostel)
    {
        $title = $hostel->title;
        if (empty($title)) {
            $title = Str::words($hostel->content, 10);
        }
        $image = 'https://itro.vn/files/logo.png';
        $medias = $hostel->medias;
        if ($medias->count() > 0) {
            $image = $medias->first()->media;
        }
        $url = url('nha-tro-dang-tin/') . '/' . str_slug($title) . '-' . $hostel->id . '?hpclid=' . $hostel->id;
        $param = [
            'url' => $url,
            'title' => $title,
            'desc' => \Illuminate\Support\Str::words(strip_tags(html_entity_decode($hostel->content)), 100),
            'image' => $image
        ];

        $result = self::generateDynamicLink($param);
        $arr = $result->jsonSerialize();
        if (isset($arr['shortLink'])) {
            return $arr['shortLink'];
        }

        return null;

        //return $url;
    }

    public static function generateDynamicLinkHostel(Hostel $hostel)
    {
        $url = url('nha-tro/') . '/' . str_slug($hostel->name) . '-' . $hostel->id . '?hid=' . $hostel->id;
        $param = [
            'url' => $url,
            'title' => $hostel->name,
            'desc' => \Illuminate\Support\Str::words(strip_tags(html_entity_decode($hostel->desc)), 100),
            'image' => url($hostel->image)
        ];

        $result = self::generateDynamicLink($param);
        $arr = $result->jsonSerialize();
        if (isset($arr['shortLink'])) {

            return $arr['shortLink'];
        }

        return null;

        //return $url;
    }

    public static function generateDynamicLinkAff($user)
    {
        $url = 'https://itro.vn?ref=' . $user->refer_code;
        $param = [
            'url' => $url,
            'title' => 'itro.vn',
            'desc' => 'ITRO là một hệ sinh thái đầy đủ trong lĩnh vực nhà cho thuê bao gồm phần mềm quản lý, phần mềm tìm khách thuê dành cho chủ nhà và phần mềm tìm kiếm nhà dành cho khách có nhu cầu thuê.',
            'image' => 'https://itro.vn/ogimage_home.jpg'
        ];

        $result = self::generateDynamicLink($param);
        $arr = $result->jsonSerialize();
        if (isset($arr['shortLink'])) {

            return $arr['shortLink'];
        }

        return null;

        //return $url;
    }

    public static function getNotificationWhenStaffCollectText($collectSpendId)
    {
        $cp = CollectSpend::find($collectSpendId);

        if (!$cp) {
            return null;
        }

        $user = $cp->user;
        if (!$user) {
            return null;
        }

        if ($cp->type == CollectSpend::SPEND) {
            return $user->name_text . ' vừa lập phiếu chi ' . number_format($cp->amount, 0, '.', '.') . ' với nội dung: ' . $cp->note;
        } else {
            if ($cp->moneyInfo) {
                $moneyInfo = $cp->moneyInfo;
                $type = $moneyInfo->type;
                $typeText = null;
                if (in_array($type, [MoneyInfo::VOUCHER_CONTRACT, MoneyInfo::VOUCHER_ROOM_PRICE])) {
                    $typeText = 'phòng';
                } else if ($type == MoneyInfo::VOUCHER_SERVICE) {
                    $typeText = 'dịch vụ';
                } else if ($type == MoneyInfo::VOUCHER_DEPOSIT) {
                    $typeText = 'cọc';
                } else {
                    $typeText = 'dịch vụ khác';
                }

                return $user->name_text . ' vừa thu ' . number_format($cp->amount, 0, '.', '.') . ' đ tiền ' . $typeText . ' phòng ' . optional($moneyInfo->room)->name . ' nhà ' . optional($moneyInfo->hostel)->name;
            } else {
                return $user->name_text . ' vừa lập phiếu thu ' . number_format($cp->amount, 0, '.', '.') . ' với nội dung: ' . $cp->note;
            }
        }
    }

    public static function getNotificationSearchText($findSessionId, $districtName)
    {
        $findSession = FindSession::find($findSessionId);
        $minPrice = 0;
        $maxPrice = 0;

        if ($findSession) {
            $minPrice = $findSession->min_price;
            $maxPrice = $findSession->max_price;
        }

        if (!empty($minPrice) && !empty($maxPrice)) {
            return 'Có một khách thuê đang có nhu cầu tìm trọ quanh khu vực ' . $districtName . ', khoảng giá từ: ' . number_format($minPrice) . 'đ đến ' . number_format($maxPrice) . 'đ. Nếu bạn còn phòng trống quanh khu vực này hãy chat ngay để giới thiệu nhà trọ của bạn';
        }

        return 'Có một khách thuê đang có nhu cầu tìm trọ quanh khu vực ' . $districtName . ', nếu bạn còn phòng trống quanh khu vực này hãy chat ngay để giới thiệu nhà trọ của bạn';
    }

    public static function getNotificationConfirmText($hostel, $transaction)
    {
        $statusConfirm = $hostel->status_confirm;
        if ($statusConfirm == Hostel::WAIT_CONFIRM || $statusConfirm == Hostel::NOT_CONFIRM) {
            return 'Chúng tôi sẽ kiểm tra thông tin nhà của bạn trước khi khách tìm nhà có thể nhìn thấy nhà của bạn';
        }

        if ($statusConfirm == Hostel::CONFIRM_WRONG_DATA) {
            return 'Nhà của bạn cần cập nhật thêm một số thông tin nữa. Vui lòng cập nhật thông tin đầy đủ chính xác để khách thuê có thể tìm thấy nhà của bạn';
        }

        if ($statusConfirm == Hostel::CONFIRMED) {

            //dd($transaction);
            if (!empty($transaction)) {
                if ($transaction->achievement) {
                    return 'Chúng tôi đã xác nhận thông tin nhà ' . $hostel->name . ' của bạn, bạn được tặng ' . $transaction->achievement->credits . ' iCredits vào ví iCredits';
                }
            }

            return 'Chúng tôi đã xác nhận thông tin nhà ' . $hostel->name . ' của bạn';
        }
    }

    public static function encryptRSA(array $rawData, $publicKey)
    {
        $rawJson = json_encode($rawData);
        $rsa = new RSA();
        $rsa->loadKey($publicKey);
        $rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
        $cipher = $rsa->encrypt($rawJson);

        return base64_encode($cipher);

    }

    public static function HTTPPost($url, $payload)
    {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json; charset=UTF-8"));
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);

        $result = curl_exec($ch);

        $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        curl_close($ch);

        return $result;
    }

    public static function checkRoomBedStatus($bed)
    {
        $checkContract = Contract::query()->where('bed_id', $bed->id)
            ->where('status', '<>', Contract::LIQUIDATED)
            ->count();

        if ($checkContract > 0) {
            return RoomBed::UNAVAILABLE;
        }

        $checkReserve = RoomReservation::query()->where('bed_id', $bed->id)
            ->count();
        if ($checkReserve > 0) {
            return RoomBed::DEPOSIT;
        }

        return RoomBed::AVAILABLE;
    }

    public static function getInfoId($image)
    {
        $image = Image::make($image);
    }

    public static function getEwRoomContract(Room $room)
    {
        $item = ElectricWater::query()
            ->where('room_id', $room->id)
            ->orderBy('date_action', 'desc')
            ->first();
        $e = 1;
        $w = 1;
        if ($item) {
            $e = $item->end_electric;
            $w = $item->end_water;
        }
        return [
            'e' => $e,
            'w' => $w
        ];
    }

    public static function getCurrentUser()
    {
        $user = null;
        if (auth('backend')->check()) {
            $user = auth('backend')->user();
        } else {
            $token = \request()->header('authorization');
            if ($token) {
                $user = \JWTAuth::parseToken()->toUser();
            }
        }
        return $user;
    }

}
