<?php

namespace App\Http\Controllers\Backend2;

use App\Components\Functions;
use App\Http\Controllers\Backend\AdminController;
use App\Models\Contract;
use App\Models\Hostel;
use App\Models\MoneyInfo;
use App\Models\OwnerMessage;
use App\Models\Package;
use App\Models\RenterRoom;
use App\Models\ReportBreak;
use App\Models\Room;
use App\Models\RoomBed;
use App\Models\UserPackage;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class DashboardController extends AdminController
{
    //
    public function index()
    {

        $hostels = Hostel::query()->where('owner_id', auth('backend')->user()->id)->get();

        $ownerId = auth('backend')->user()->id;

        if (auth('backend')->user()->type == User::STAFF) {
            if (auth('backend')->user()->cannot('view-statistic')) {
                return redirect()->to(url('admin2/room/list'));
            }
            $hostelArrs = Functions::getHostelArrStaff();
            $hostels = Hostel::whereIn('id', $hostelArrs)->get();
            $ownerId = auth('backend')->user()->staff_owner_id;
        }

        $numberOwnerMessage = OwnerMessage::where('owner_id', $ownerId)->where('status', OwnerMessage::NOT_PROCESS)->count();

        $package = null;
        $dateEndPackage = null;
        $userPackage = UserPackage::where('user_id', auth('backend')->user()->id)->first();
        if ($userPackage) {
            $packageId = $userPackage->package_id;
            $package = Package::find($packageId);
            $dateEndPackage = $userPackage->end_date;
            if ($dateEndPackage) {
                $dateEndPackage = $dateEndPackage->format('d/m/Y');
            }
        }

        return view('admin2.dashboard.index', compact('hostels', 'package', 'dateEndPackage', 'numberOwnerMessage', 'ownerId'));
    }

    public function statPayment(Request $request)
    {
        $month = $request->input('month');
        $year = $request->input('year');
        $hostelId = $request->input('hostel_id');
        $owner = auth('backend')->user();
        if($owner->type == User::STAFF)
        {
            $owner = auth('backend')->user()->owner;
        }

        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();

            $month = Carbon::createFromFormat('d/m/Y', '01/'.$month . '/' . $year);
        }

        $paids = MoneyInfo::where('remain', 0)
            ->when($owner->type_display_money_info == User::TYPE_DISPLAY_MONEY_INFO_PREVIOUS_MONTH, function ($q) use ($month) {
                $q->where(function ($q) use ($month) {
                    $q->orWhere(function ($q) use ($month) {
                        $q->whereBetween('date_action', [
                            $month->copy()->startOfMonth(),
                            $month->copy()->endOfMonth()
                        ]);
                        $q->whereIn('type', [
                            MoneyInfo::VOUCHER_CONTRACT,
                            MoneyInfo::VOUCHER_ROOM_PRICE
                        ]);
                    });

                    $q->orWhere(function ($q) use ($month) {
                        $q->whereBetween('date_action', [
                            $month->copy()->subMonth()->startOfMonth(),
                            $month->copy()->subMonth()->endOfMonth()
                        ]);
                        $q->where('type', MoneyInfo::VOUCHER_SERVICE);
                    });
                });

            }, function ($q) use ($month) {

                $q->whereBetween('date_action', [
                    $month->copy()->startOfMonth(),
                    $month->copy()->endOfMonth()
                ]);

            });
        $unpaids = MoneyInfo::where('remain', '>', 0)
            ->when($owner->type_display_money_info == User::TYPE_DISPLAY_MONEY_INFO_PREVIOUS_MONTH, function ($q) use ($month) {
                $q->where(function ($q) use ($month) {
                    $q->orWhere(function ($q) use ($month) {
                        $q->whereBetween('date_action', [
                            $month->copy()->startOfMonth(),
                            $month->copy()->endOfMonth()
                        ]);
                        $q->whereIn('type', [
                            MoneyInfo::VOUCHER_CONTRACT,
                            MoneyInfo::VOUCHER_ROOM_PRICE
                        ]);
                    });

                    $q->orWhere(function ($q) use ($month) {
                        $q->whereBetween('date_action', [
                            $month->copy()->subMonth()->startOfMonth(),
                            $month->copy()->subMonth()->endOfMonth()
                        ]);
                        $q->where('type', MoneyInfo::VOUCHER_SERVICE);
                    });
                });

            }, function ($q) use ($month) {

                $q->whereBetween('date_action', [
                    $month->copy()->startOfMonth(),
                    $month->copy()->endOfMonth()
                ]);

            });




        if (!empty($hostelId)) {
            $paids = $paids->where('hostel_id', $hostelId);
            $unpaids = $unpaids->where('hostel_id', $hostelId);
        } else {
            if (auth('backend')->user()->type == User::STAFF) {
                $hostels = Functions::getHostelArrStaff();
            } else {
                $hostels = Hostel::where('owner_id', auth('backend')->user()->id)->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('remain');

        return response([
            'status' => 1,
            'data' => view('admin2.dashboard.stat_payment', compact('paidCnt', 'unPaidCnt', 'paidAmount', 'unpaidAmount', 'hostelId'))->render()
        ]);

    }

    public function filter(Request $request)
    {
        $hostelId = $request->input('hostel_id');

        $startDate = Carbon::now()->startOfMonth()->toDateString();
        $endDate = Carbon::now()->endOfMonth()->toDateString();
        $month = Carbon::now();

        $ownerId = auth('backend')->user()->id;
        $dayRemind = auth('backend')->user()->day_remind_empty_room;
        $owner = auth('backend')->user();
        if (auth('backend')->user()->type == User::STAFF) {
            $ownerId = auth('backend')->user()->staff_owner_id;
            $owner = User::find($ownerId);
            $dayRemind = $owner->day_remind_empty_room;
        }


        if (empty($hostelId)) {
            $hostels = Hostel::where('owner_id', $ownerId)->get();

            if (auth('backend')->user()->type == User::STAFF) {
                $hostelArrs = Functions::getHostelArrStaff();
                $hostels = Hostel::whereIn('id', $hostelArrs)->get();
            }

            $hostelArrs = $hostels->pluck('id')->toArray();
            $paids = MoneyInfo::query()
                ->when($owner->type_display_money_info == User::TYPE_DISPLAY_MONEY_INFO_PREVIOUS_MONTH, function ($q) use ($month) {
                    $q->where(function ($q) use ($month) {
                        $q->orWhere(function ($q) use ($month) {
                            $q->whereBetween('date_action', [
                                $month->copy()->startOfMonth(),
                                $month->copy()->endOfMonth()
                            ]);
                            $q->whereIn('type', [
                                MoneyInfo::VOUCHER_CONTRACT,
                                MoneyInfo::VOUCHER_ROOM_PRICE
                            ]);
                        });

                        $q->orWhere(function ($q) use ($month) {
                            $q->whereBetween('date_action', [
                                $month->copy()->subMonth()->startOfMonth(),
                                $month->copy()->subMonth()->endOfMonth()
                            ]);
                            $q->where('type', MoneyInfo::VOUCHER_SERVICE);
                        });
                    });

                }, function ($q) use ($month) {

                    $q->whereBetween('date_action', [
                        $month->copy()->startOfMonth(),
                        $month->copy()->endOfMonth()
                    ]);

                })
                ->where(function ($q) {
                    $q->orWhereNull('contract_id');
                    $q->orWhereHas('contract', function ($q) {
                        $q->where('status', '<>', Contract::LIQUIDATED);
                    });

                })
                ->where('remain', 0)
                ->whereIn('hostel_id', $hostelArrs)
                ->count();
            $unpaids = MoneyInfo::query()
                ->when($owner->type_display_money_info == User::TYPE_DISPLAY_MONEY_INFO_PREVIOUS_MONTH, function ($q) use ($month) {
                    $q->where(function ($q) use ($month) {
                        $q->orWhere(function ($q) use ($month) {
                            $q->whereBetween('date_action', [
                                $month->copy()->startOfMonth(),
                                $month->copy()->endOfMonth()
                            ]);
                            $q->whereIn('type', [
                                MoneyInfo::VOUCHER_CONTRACT,
                                MoneyInfo::VOUCHER_ROOM_PRICE
                            ]);
                        });

                        $q->orWhere(function ($q) use ($month) {
                            $q->whereBetween('date_action', [
                                $month->copy()->subMonth()->startOfMonth(),
                                $month->copy()->subMonth()->endOfMonth()
                            ]);
                            $q->where('type', MoneyInfo::VOUCHER_SERVICE);
                        });
                    });

                }, function ($q) use ($month) {

                    $q->whereBetween('date_action', [
                        $month->copy()->startOfMonth(),
                        $month->copy()->endOfMonth()
                    ]);

                })
                ->where(function ($q) {
                    $q->orWhereNull('contract_id');
                    $q->orWhereHas('contract', function ($q) {
                        $q->where('status', '<>', Contract::LIQUIDATED);
                    });

                })
                ->where('remain', '>', 0)
                ->whereIn('hostel_id', $hostelArrs)
                ->count();

            $paidAmount = MoneyInfo::query()
                ->when($owner->type_display_money_info == User::TYPE_DISPLAY_MONEY_INFO_PREVIOUS_MONTH, function ($q) use ($month) {
                    $q->where(function ($q) use ($month) {
                        $q->orWhere(function ($q) use ($month) {
                            $q->whereBetween('date_action', [
                                $month->copy()->startOfMonth(),
                                $month->copy()->endOfMonth()
                            ]);
                            $q->whereIn('type', [
                                MoneyInfo::VOUCHER_CONTRACT,
                                MoneyInfo::VOUCHER_ROOM_PRICE
                            ]);
                        });

                        $q->orWhere(function ($q) use ($month) {
                            $q->whereBetween('date_action', [
                                $month->copy()->subMonth()->startOfMonth(),
                                $month->copy()->subMonth()->endOfMonth()
                            ]);
                            $q->where('type', MoneyInfo::VOUCHER_SERVICE);
                        });
                    });

                }, function ($q) use ($month) {

                    $q->whereBetween('date_action', [
                        $month->copy()->startOfMonth(),
                        $month->copy()->endOfMonth()
                    ]);

                })
                ->where('remain', 0)
                ->where(function ($q) {
                    $q->orWhereNull('contract_id');
                    $q->orWhereHas('contract', function ($q) {
                        $q->where('status', '<>', Contract::LIQUIDATED);
                    });

                })
                ->whereIn('hostel_id', $hostelArrs)
                ->sum('amount');
            $unpaidAmount = MoneyInfo::query()
                ->when($owner->type_display_money_info == User::TYPE_DISPLAY_MONEY_INFO_PREVIOUS_MONTH, function ($q) use ($month) {
                    $q->where(function ($q) use ($month) {
                        $q->orWhere(function ($q) use ($month) {
                            $q->whereBetween('date_action', [
                                $month->copy()->startOfMonth(),
                                $month->copy()->endOfMonth()
                            ]);
                            $q->whereIn('type', [
                                MoneyInfo::VOUCHER_CONTRACT,
                                MoneyInfo::VOUCHER_ROOM_PRICE
                            ]);
                        });

                        $q->orWhere(function ($q) use ($month) {
                            $q->whereBetween('date_action', [
                                $month->copy()->subMonth()->startOfMonth(),
                                $month->copy()->subMonth()->endOfMonth()
                            ]);
                            $q->where('type', MoneyInfo::VOUCHER_SERVICE);
                        });
                    });

                }, function ($q) use ($month) {

                    $q->whereBetween('date_action', [
                        $month->copy()->startOfMonth(),
                        $month->copy()->endOfMonth()
                    ]);

                })
                ->where(function ($q) {
                    $q->orWhereNull('contract_id');
                    $q->orWhereHas('contract', function ($q) {
                        $q->where('status', '<>', Contract::LIQUIDATED);
                    });

                })
                ->where('remain', '>', 0)
                ->whereIn('hostel_id', $hostelArrs)
                ->sum('remain');

            $numberRenters = RenterRoom::query()->whereIn('hostel_id', $hostelArrs)->count();

            $numberContracts30 = Contract::query()->whereIn('hostel_id', $hostelArrs)->where('status', '<>', Contract::LIQUIDATED)
                ->whereBetween('end_date', [Carbon::now()->toDateString(), Carbon::now()->addDay(30)->toDateString()])->count();
            $numberContracts60 = Contract::query()->whereIn('hostel_id', $hostelArrs)->where('status', '<>', Contract::LIQUIDATED)
                ->whereBetween('end_date', [Carbon::now()->toDateString(), Carbon::now()->addDay(60)->toDateString()])->count();
            $numberContracts90 = Contract::query()->whereIn('hostel_id', $hostelArrs)->where('status', '<>', Contract::LIQUIDATED)
                ->whereBetween('end_date', [Carbon::now()->toDateString(), Carbon::now()->addDay(90)->toDateString()])->count();

            $emptyRooms = 0;
            $numberRooms = 0;

            foreach ($hostels as $hostel) {

                if ($hostel->type_rent == Hostel::TYPE_RENT_ALL) {

                    $currentRooms = Room::where('hostel_id', $hostel->id)->count();
                    $numberRooms += $currentRooms;

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

                    $emptyRooms += ($currentRooms - $usedRooms);
                } else {

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

            $numberRoomBedEmpty = RoomBed::where('date_available', '>=', Carbon::now()->subDay($dayRemind))->whereIn('hostel_id', $hostelArrs)->count();
            $numberRoomsEmpty = Room::where('date_available', '>=', Carbon::now()->subDay($dayRemind))->whereIn('hostel_id', $hostelArrs)->count();

            $numberRoomsNearEmpty = $numberRoomsEmpty + $numberRoomBedEmpty;

            $numberRoomsNearEmpty = Contract::query()
                ->whereIn('hostel_id', $hostelArrs)
                ->where('status', '<>', Contract::LIQUIDATED)
                ->where('leave_day', '>=', Carbon::now()->subDay($dayRemind))
                ->count();
            //dd($numberRoomsNearEmpty);

            $rentersNotDeclareResidence = RenterRoom::where('residence_status', RenterRoom::RESIDENCE_NOT_DECLARE)->whereIn('hostel_id', $hostelArrs)->count();

            $date = Carbon::now()->addDay(30)->toDateString();
            $rentersResidenceWarning = RenterRoom::where('residence_status', RenterRoom::RESIDENCE_LIMIT)
                ->where('hostel_id', $hostelId)
                ->where('date_end_residence', '<', $date)->count();

            $pieChart = json_encode([
                [
                    'name' => 'Đang cho thuê',
                    'value' => $numberRooms - $emptyRooms - $numberRoomsNearEmpty,
                    'color' => '#4b77be'
                ],

                [
                    'name' => 'Sắp trống',
                    'value' => $numberRoomsNearEmpty,
                    'color' => '#E7505A'
                ],

                [
                    'name' => 'Đang trống',
                    'value' => $emptyRooms,
                    'color' => '#32C5D2'
                ]
            ]);

            $numberHostels = $hostels->count();


            //report break |sonmt
            $newReportBreak = ReportBreak::where('status', ReportBreak::NOT_PROCESS)->whereIn('hostel_id', $hostelArrs)->count();
            $processingReportBreak = ReportBreak::where('status', ReportBreak::PROCESSING)->whereIn('hostel_id', $hostelArrs)->count();
            $prosessedReportBreak = ReportBreak::where('status', ReportBreak::PROCESSED)->whereIn('hostel_id', $hostelArrs)->count();

            return response([
                'status' => 1,
                'data' => view('admin2.dashboard.filter', compact('paids', 'unpaids', 'hostelId',
                    'numberContracts30', 'numberContracts60', 'numberContracts90', 'numberRenters', 'pieChart',
                    'numberRooms', 'emptyRooms', 'numberHostels', 'paidAmount', 'unpaidAmount',
                    'rentersNotDeclareResidence', 'rentersResidenceWarning', 'numberRoomsNearEmpty',
                    'newReportBreak', 'processingReportBreak', 'prosessedReportBreak'))->render()
            ]);
        } else {
            $numberHostels = 1;
            $hostel = Hostel::find($hostelId);
            if (!$hostel) {
                return response([
                    'status' => 0,
                    'data' => null
                ]);
            }

            $paids = MoneyInfo::where('remain', 0)->where('hostel_id', $hostelId)->whereBetween('date_action', [$startDate, $endDate])->count();
            $unpaids = MoneyInfo::where('remain', '>', 0)->where('hostel_id', $hostelId)->whereBetween('date_action', [$startDate, $endDate])->count();

            $paidAmount = MoneyInfo::where('remain', 0)
                ->where(function ($q) {
                    $q->orWhereNull('contract_id');
                    $q->orWhereHas('contract', function ($q) {
                        $q->where('status', '<>', Contract::LIQUIDATED);
                    });

                })
                ->where('hostel_id', $hostelId)->whereBetween('date_action', [$startDate, $endDate])->sum('amount');
            $unpaidAmount = MoneyInfo::where('remain', '>', 0)
                ->where(function ($q) {
                    $q->orWhereNull('contract_id');
                    $q->orWhereHas('contract', function ($q) {
                        $q->where('status', '<>', Contract::LIQUIDATED);
                    });

                })
                ->where('hostel_id', $hostelId)->whereBetween('date_action', [$startDate, $endDate])->sum('amount');

            $numberRenters = RenterRoom::where('hostel_id', $hostelId)->count();

            $numberContracts30 = Contract::where('hostel_id', $hostelId)->where('status', '<>', Contract::LIQUIDATED)
                ->whereBetween('end_date', [Carbon::now()->toDateString(), Carbon::now()->addDay(30)->toDateString()])->count();
            $numberContracts60 = Contract::where('hostel_id', $hostelId)->where('status', '<>', Contract::LIQUIDATED)
                ->whereBetween('end_date', [Carbon::now()->toDateString(), Carbon::now()->addDay(60)->toDateString()])->count();
            $numberContracts90 = Contract::where('hostel_id', $hostelId)->where('status', '<>', Contract::LIQUIDATED)
                ->whereBetween('end_date', [Carbon::now()->toDateString(), Carbon::now()->addDay(90)->toDateString()])->count();
            $numberRooms = Room::where('hostel_id', $hostelId)->count();

            $emptyRooms = 0;

            if ($hostel->type_rent == Hostel::TYPE_RENT_ALL) {
                $numberRooms = Room::where('hostel_id', $hostel->id)->count();
                $usedRooms = RenterRoom::where('hostel_id', $hostel->id)
                    ->whereNotNull('user_id')->groupBy('room_id')
                    ->get()
                    ->count();

                $emptyRooms += ($numberRooms - $usedRooms);
            } elseif ($hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
                $numberBeds = Room::where('hostel_id', $hostel->id)->sum('max_renters');
                $numberRooms = $numberBeds;
                $usedBeds = RenterRoom::where('hostel_id', $hostel->id)
                    ->count();
                $remain = $numberBeds - $usedBeds;
                if ($remain < 0) {
                    $remain = 0;
                }
                $emptyRooms += $remain;
            }


            $rentersNotDeclareResidence = RenterRoom::query()->where('residence_status', RenterRoom::RESIDENCE_NOT_DECLARE)->where('hostel_id', $hostelId)->count();
            $date = Carbon::now()->addDay(30)->toDateString();
            $rentersResidenceWarning = RenterRoom::where('residence_status', RenterRoom::RESIDENCE_LIMIT)
                ->where('hostel_id', $hostelId)
                ->where('date_end_residence', '<', $date)
                ->count();
            $numberRoomsNearEmpty = 0;
            if ($hostel->type_rent == Hostel::TYPE_RENT_ALL) {
                $numberRoomsNearEmpty = Room::where('date_available', '>=', Carbon::now()->subDay($dayRemind))->where('hostel_id', $hostelId)->count();
            } elseif ($hostel->type_rent == Hostel::TYPE_RENT_EVERY) {
                $numberRoomsNearEmpty = RoomBed::where('date_available', '>=', Carbon::now()->subDay($dayRemind))->where('hostel_id', $hostelId)->count();
            }

            $numberRoomsNearEmpty = Contract::query()
                ->where('hostel_id', $hostelId)
                ->where('status', '<>', Contract::LIQUIDATED)
                ->where('leave_day', '>=', Carbon::now()->subDay($dayRemind))
                ->count();


            $pieChart = json_encode([
                [
                    'name' => 'Đang cho thuê',
                    'value' => $numberRooms - $emptyRooms - $numberRoomsNearEmpty,
                    'color' => '#4b77be'
                ],

                [
                    'name' => 'Sắp trống',
                    'value' => $numberRoomsNearEmpty,
                    'color' => '#E7505A'
                ],

                [
                    'name' => 'Phòng trống',
                    'value' => $emptyRooms,
                    'color' => '#32C5D2'
                ]
            ]);

            //report break |sonmt
            $newReportBreak = ReportBreak::query()->where('status', ReportBreak::NOT_PROCESS)->where('hostel_id', $hostelId)->count();
            $processingReportBreak = ReportBreak::query()->where('status', ReportBreak::PROCESSING)->where('hostel_id', $hostelId)->count();
            $prosessedReportBreak = ReportBreak::query()->where('status', ReportBreak::PROCESSED)->where('hostel_id', $hostelId)->count();

            return response([
                'status' => 1,
                'data' => view('admin2.dashboard.filter', compact('paids', 'unpaids', 'hostelId', 'hostel',
                    'numberContracts30', 'numberContracts60', 'numberContracts90', 'numberRenters', 'pieChart',
                    'numberRooms', 'emptyRooms', 'numberHostels', 'paidAmount',
                    'unpaidAmount', 'rentersNotDeclareResidence', 'rentersResidenceWarning', 'numberRoomsNearEmpty',
                    'newReportBreak', 'processingReportBreak', 'prosessedReportBreak'))->render()
            ]);

        }


    }
}
