<?php

namespace App\Http\Controllers\Backend;

use App\Components\Functions;
use App\Http\Requests\CreateHostelRequest;
use App\Models\Account;
use App\Models\Amenity;
use App\Models\Hostel;
use App\Models\HostelType;
use App\Models\RenterRoom;
use App\Models\Room;
use App\Models\RoomType;

use App\Models\Tag;
use App\Models\Wishlist;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Yajra\Datatables\Datatables;

class HostelController extends AdminController {
	//
	public function getMap() {
		$locations = Hostel::query()
		                   ->whereNotNull( 'lat' )
		                   ->whereNotNull( 'lng' )
		                   ->get()
		                   ->map( function ( $item ) {
			                   return [
				                   'lat'     => $item->lat,
				                   'lng'     => $item->lng,
				                   'name'    => ! empty( $item->name ) ? str_slug( $item->name ) : 'test',
				                   'o_name'  => $item->name,
				                   'id'      => $item->id,
				                   'address' => $item->address_text
			                   ];
		                   } );

		return view( 'admin.hostel.map', compact( 'locations' ) );
	}

	public function getHostelByAttributeView( Request $request ) {
		if ( auth( 'backend' )->user()->type == User::RENTER ) {
			abort( 403 );
		}

		if ( auth( 'backend' )->user()->type == User::EDITOR ) {
			return redirect()->to( url( 'admin/blog' ) );
		}

		return view( 'admin.hostel.list' );
	}

	public function getRenters( Request $request ) {
		$id      = $request->input( 'hostel_id' );
		$renters = RenterRoom::select( \DB::raw( 'users.name, users.image, users.address, users.phone, users.birthday, renter_rooms.created_at as date_joined' ) )
		                     ->join( 'users', 'renter_rooms.user_id', '=', 'users.id' )
		                     ->where( 'renter_rooms.hostel_id', $id )->orderBy( 'renter_rooms.contract_id', 'desc' )->orderBy( 'renter_rooms.created_at', 'desc' )->get();

		foreach ( $renters as $renter ) {
			if ( ! empty( $renter->image ) ) {
				$renter->image = '/files/' . $renter->image;
			}

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

			if ( ! empty( $renter->date_joined ) ) {
				$renter->date_joined = Carbon::createFromFormat( 'Y-m-d H:i:s', $renter->date_joined )->format( 'd/m/Y' );
			}
		}

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

	public function edit( $id ) {
		$hostel = Hostel::find( $id );
		if ( $hostel ) {
			$owners = User::where( 'type', User::OWNER )->get();

			$hostelTypes = HostelType::all();

			$roomTypes = RoomType::orderBy( 'id' );

			if ( auth( 'backend' )->check() ) {
				if ( auth( 'backend' )->user()->type == User::OWNER ) {
					$roomTypes = $roomTypes->where( 'owner_id', auth( 'backend' )->user()->id );
				}
			}

			$roomTypes = $roomTypes->get();

			return view( 'admin.hostel.edit', compact( 'hostel', 'owners', 'roomTypes', 'hostelTypes' ) );
		}

		return redirect()->back()->with( 'error', 'Dữ liệu không hợp lệ' );
	}

	public function getOwner( $id, Request $request ) {
		$hostel = Hostel::find( $id );
		if ( ! $hostel ) {
			return response( [
				'status'  => 0,
				'message' => 'Dữ liệu không hợp lệ'
			] );
		}

		$owner = $hostel->owner;
		if ( ! $owner ) {
			return response( [
				'status'  => 0,
				'message' => 'Dữ liệu không hợp lệ'
			] );
		}

		return response( [
			'status' => 1,
			'data'   => view( 'admin.hostel.owner', [
				'user' => $owner
			] )->render()
		] );
	}

	public function getHostelByAttribute( Request $request ) {
		$type       = $request->input( 'type' );
		$ownerId    = $request->input( 'owner_id' );
		$isOutStand = $request->input( 'is_outstand' );
		$tags       = $request->input( 'tags' );
		if ( $type != 'verify' ) {
			$items = Hostel::query()->where( 'source', '<>', Hostel::SOURCE_CRAWLER );
		} else {
			$items = Hostel::query()->where( 'source', Hostel::SOURCE_CRAWLER );
		}

		if ( auth( 'backend' )->check() ) {

			if ( in_array( auth( 'backend' )->user()->type, [ User::RENTER, User::OWNER, User::STAFF ] ) ) {
				abort( 403 );
			}
		}

		$items = $items->has( 'owner' )->when( ! empty( $ownerId ), function ( $q ) use ( $ownerId ) {
			$q->where( 'owner_id', $ownerId );
		} )->when( ! empty( $request->input( 'province_id' ) ), function ( $q ) {
			$q->where( 'province_id', \request()->input( 'province_id' ) );
		} )->when( ! empty( $request->input( 'tags' ) ), function ( $q ) use ( $tags ) {
			$q->whereHas( 'tags', function ( $q ) use ( $tags ) {
				$q->whereIn( 'tags.id', $tags );
			} );
		} )->when( ! empty( $request->input( 'district_id' ) ), function ( $q ) {
			$q->where( 'district_id', \request()->input( 'district_id' ) );
		} )->when( ! empty( $request->input( 'ward_id' ) ), function ( $q ) {
			$q->where( 'ward_id', \request()->input( 'ward_id' ) );
		} )->when( ! empty( $request->input( 'room_status' ) ), function ( $q ) {
			if ( \request()->input( 'room_status' ) == 'created' ) {
				$q->has( 'rooms' );
			} else {
				$q->doesntHave( 'rooms' );
			}
		} )->when( ! empty( $request->input( 'room_empty_status' ) ), function ( $q ) {
			if ( \request()->input( 'room_empty_status' ) == 'created' ) {
				$q->where( 'number_empty_rooms', '>', 0 );
			} else {
				$q->where( 'number_empty_rooms', '=', 0 );
			}
		} )->when( ! empty( $isOutStand ), function ( $q ) {
			$q->where( 'status_confirm', Hostel::CONFIRMED )
			  ->where( function ( $q ) {
				  $q->orWhereHas( 'owner', function ( $q ) {
					  $q->where( 'payment_status', User::PAYMENT_PAYING );
				  } );
				  $q->orWhereHas( 'owner.packageFindHostel', function ( $q ) {
					  $q->where( 'package_id', 3 );
				  } );
			  } );
		} );

		$items = $items->withCount( [ 'rooms', 'roomsEmpty' ] )
		               ->with( 'owner' );

		return Datatables::of( $items )
		                 ->addIndexColumn()
		                 ->filterColumn( 'owner_id', function ( $query, $keyword ) {
			                 $query->whereHas( 'owner', function ( $q ) use ( $keyword ) {
				                 $q->where( 'users.name', 'LIKE', '%' . $keyword . '%' );
			                 } );
		                 } )
		                 ->filterColumn( 'payment_status', function ( $query, $keyword ) {
			                 $query->whereHas( 'owner', function ( $q ) use ( $keyword ) {
				                 $q->where( 'users.payment_status', $keyword );
			                 } );
		                 } )
		                 ->filterColumn( 'rooms_count', function ( $query, $keyword ) {
			                 $query->has( 'rooms', $keyword );
		                 } )
		                 ->editColumn( 'rooms_count', function ( $item ) {
			                 return '<a target="_blank" href="' . url( 'admin/room?hostel_id=' . $item->id ) . '">' . $item->rooms_count . '</a>';
		                 } )
		                 ->editColumn( 'rooms_empty_count', function ( $item ) {
			                 return '<a target="_blank" href="' . url( 'admin/room?is_empty=1&hostel_id=' . $item->id ) . '">' . $item->rooms_empty_count . '</a>';
		                 } )
		                 ->editColumn( 'address', function ( $item ) {
			                 return $item->address_text;
		                 } )
		                 ->editColumn( 'status', function ( $item ) {
			                 return $item->status_text;

		                 } )
		                 ->addColumn( 'payment_status', function ( $item ) {
			                 return optional( $item->owner )->payment_status_text;
		                 } )
		                 ->editColumn( 'status_confirm', function ( $item ) {
			                 return '<div style="min-width: 100px"> <a data-source="' . url( 'admin/hostel/status-confirm' ) . '" href="javascript:;" data-type="select" data-pk="' . $item->id . '" data-placement="left" data-emptytext="Chưa xác định"
                                       data-name="status_confirm" data-value="' . $item->status_confirm . '"
                                       data-original-title="Nhập giá trị" id="status-' . $item->id . '"
                                       data-placeholder="Vui lòng chọn"
                                       class="editable editable-not-select2 editable-status editable-click editable-empty">' . $item->status_confirm_text . '</a></div>';
		                 } )
		                 ->addColumn( 'tags', function ( $item ) {
			                 if ( ! empty( $item->tags->count() ) ) {
				                 return '<a href="#edit-tag" data-id="' . $item->id . '" data-toggle="modal" class="btn-tags">' . implode( ', ', $item->tags->pluck( 'name' )->toArray() ) . '</a>';
			                 }

			                 return '<a href="#edit-tag" data-id="' . $item->id . '" data-toggle="modal" class="btn-tags">Gắn tags</a>';
		                 } )
		                 ->editColumn( 'name', function ( $item ) {
			                 return '<a href="' . url( 'nha-tro/' . str_slug( $item->name ) . '-' . $item->id ) . '" target="_blank">' . $item->name . '</a>';
		                 } )
		                 ->editColumn( 'owner_id', function ( $item ) {
			                 return '<a target="_blank" href="/admin/owner?owner_id=' . $item->owner->id . '" data-href="' . url( 'admin/hostel/owner', [ 'id' => $item->id ] ) . '" data-toggle="modal" class="btn-edit-owner">' . optional( $item->owner )->name_text . '</a>';
		                 } )
		                 ->editColumn( 'dynamic_link', function ( $item ) {
			                 return '<a target="_blank" href="' . $item->dynamic_link . '" >' . $item->dynamic_link . '</a>';
		                 } )
		                 ->editColumn( 'created_at', function ( $item ) {
			                 return $item->created_at->format( 'd/m/Y' );
		                 } )
		                 ->editColumn( 'type_rent', function ( $item ) {
			                 return $item->type_rent_text;
		                 } )
		                 ->addColumn( 'action', function ( $item ) {

			                 $retVal = '';

			                 if ( auth( 'backend' )->user()->type == User::ADMIN ) {
				                 $retVal = '<a data-hostel="' . $item->id . '" href="#edit-hostel" data-href="' . url( 'admin2/hostel/edit', [ 'id' => $item->id ] ) . '" data-toggle="modal" class="btn btn-sm btn-outline btn-editable btn-edit-hostel purple"><i class="fa fa-edit"></i> Sửa</a>'
				                           . '<a data-id="' . $item->id . '" data-href="' . url( 'admin2/hostel/delete', [ 'id' => $item->id ] ) . '" class="btn btn-sm btn-outline btn-editable btn-delete dark black"><i class="fa fa-trash"></i> Xóa</a>';
			                 } else {
				                 if ( auth( 'backend' )->user()->can( 'edit-hostel' ) ) {
					                 $retVal .= '<a data-hostel="' . $item->id . '" href="#edit-hostel" data-href="' . url( 'admin2/hostel/edit', [ 'id' => $item->id ] ) . '" data-toggle="modal" class="btn btn-sm btn-outline btn-editable btn-edit-hostel purple"><i class="fa fa-edit"></i> Sửa</a>';
				                 }

				                 if ( auth( 'backend' )->user()->can( 'delete-hostel' ) ) {
					                 $retVal .= '<a data-id="' . $item->id . '" data-href="' . url( 'admin2/hostel/delete', [ 'id' => $item->id ] ) . '" class="btn btn-sm btn-outline btn-editable btn-delete dark black"><i class="fa fa-trash"></i> Xóa</a>';
				                 }
			                 }

			                 return $retVal;

		                 } )
		                 ->make( true );
	}

	public function getTags( Request $request ) {
		$id     = $request->input( 'id' );
		$hostel = Hostel::find( $id );
		$tags   = Tag::all();

		return response( [
			'status' => 1,
			'data'   => view( 'admin.hostel.tags', compact( 'tags', 'hostel' ) )->render()
		] );
	}

	public function saveTag( Request $request ) {
		$tags   = $request->input( 'tags' );
		$id     = $request->input( 'id' );
		$hostel = Hostel::find( $id );
		if ( ! $hostel ) {
			return response( [
				'status'  => 0,
				'message' => 'Dữ liệu không hợp lệ'
			] );
		}

		$tagIds = [];
		if ( is_array( $tags ) ) {
			foreach ( $tags as $tag ) {
				$tagItem  = Tag::query()
				               ->updateOrCreate( [
					               'name' => $tag
				               ], [
					               'name' => $tag
				               ] );
				$tagIds[] = $tagItem->id;
			}

			$hostel->tags()->sync( $tagIds );
		}

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

	public function update( $id, Request $request ) {
		$hostel = Hostel::find( $id );

		if ( ! $hostel ) {
			return redirect()->back()->with( 'error', 'Dữ liệu không hợp lệ' );
		}

		$data = $request->all();

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

			if ( isset( $data['status'] ) && $data['status'] == 'on' ) {
				$data['status'] = true;
			} else {
				$data['status'] = false;
			}

			if ( isset( $data['status_confirm'] ) && $data['status_confirm'] == 'on' ) {
				$data['status_confirm'] = true;
			} else {
				$data['status_confirm'] = false;
			}

			if ( isset( $data['is_featured'] ) && $data['is_featured'] == 'on' ) {
				$data['is_featured'] = true;

				if ( empty( $data['expire_featured'] ) ) {
					return redirect()->back()->with( 'error', 'Không được bỏ trống ngày hết hạn nổi bật' );
				}

			} else {
				$data['is_featured'] = false;
			}

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

			$images = $request->file( 'images' );

			$imageData = [];
			if ( isset( $images ) ) {
				foreach ( $images as $image ) {
					$imageData[] = Functions::uploadImage( $image );
				}
			}

			if ( ! empty( $imageData ) ) {
				$data['images'] = json_encode( $imageData );
			}
			$data['status_confirm'] = Hostel::WAIT_CONFIRM;

			\DB::beginTransaction();

			if ( isset( $data['features'] ) ) {
				if ( is_array( $data['features'] ) ) {
					\DB::table( 'hostel_amenities' )->where( 'hostel_id', $id )->delete();
					foreach ( $data['features'] as $feature ) {
						\DB::table( 'hostel_amenities' )->insert( [
							'hostel_id'    => $id,
							'type'         => Amenity::AMENITY,
							'amenities_id' => $feature,
							'created_at'   => Carbon::now()->toDateTimeString(),
							'updated_at'   => Carbon::now()->toDateTimeString()
						] );
					}
				}
			}

			if ( isset( $data['policies'] ) ) {
				if ( is_array( $data['policies'] ) ) {
					// \DB::table('hostel_amenities')->where('hostel_id', $id)->delete();
					foreach ( $data['policies'] as $feature2 ) {
						\DB::table( 'hostel_amenities' )->insert( [
							'hostel_id'    => $id,
							'type'         => Amenity::POLICY,
							'amenities_id' => $feature2,
							'created_at'   => Carbon::now()->toDateTimeString(),
							'updated_at'   => Carbon::now()->toDateTimeString()
						] );
					}
				}
			}

			$hostel->update( $data );
			\DB::commit();
		} catch ( \Exception $exception ) {
			\DB::rollBack();

			return redirect()->back()->with( 'error', $exception->getMessage() );
		}

		return redirect()->back()->with( 'success', 'Thành công' );

	}

	public function store( CreateHostelRequest $request ) {
		$data = $request->except( [
			'room_name',
			'room_size',
			'room_floor',
			'room_type',
			'room_price'
		] );

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

		if ( empty( $data['electric_price'] ) ) {
			$data['electric_price'] = 0;
		}

		if ( empty( $data['water_price'] ) ) {
			$data['water_price'] = 0;
		}

		if ( empty( $data['number_rooms'] ) ) {
			$data['number_rooms'] = 1;
		}

		if ( isset( $data['status'] ) && $data['status'] == 'on' ) {
			$data['status'] = true;
		} else {
			$data['status'] = false;
		}

		if ( isset( $data['status_confirm'] ) && $data['status_confirm'] == 'on' ) {
			$data['status_confirm'] = true;
		} else {
			$data['status_confirm'] = false;
		}

		$images = $request->file( 'images' );

		$imageData = [];
		if ( isset( $images ) ) {
			foreach ( $images as $image ) {
				$imageData[] = Functions::uploadImage( $image );
			}
		}

		if ( isset( $data['is_featured'] ) && $data['is_featured'] == 'on' ) {
			$data['is_featured'] = true;

			if ( empty( $data['expire_featured'] ) ) {
				return redirect()->back()->with( 'error', 'Không được bỏ trống ngày hết hạn nổi bật' );
			}

		} else {
			$data['is_featured'] = false;
		}

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

		$data['images'] = json_encode( $imageData );

		if ( auth( 'backend' )->check() ) {
			$data['owner_id'] = auth( 'backend' )->user()->id;

			$currentNumberHostel                      = auth( 'backend' )->user()->number_hostels;
			auth( 'backend' )->user()->number_hostels = $currentNumberHostel + 1;
			auth( 'backend' )->user()->save();
		}

		$grs = $request->input( 'group-c' );


		try {
			\DB::beginTransaction();

			$hostel = Hostel::create( $data );


			if ( is_array( $grs ) ) {

				foreach ( $grs as $gr ) {
					$name   = $gr['room_name'];
					$size   = $gr['room_size'];
					$floor  = $gr['room_floor'];
					$type   = $gr['room_type'];
					$price  = $gr['room_price'];
					$status = $gr['room_status'];

					if ( empty( $name ) ) {
						break;
					}

					Room::create( [
						'floor'     => $floor,
						'size'      => $size,
						'type'      => $type,
						'name'      => $name,
						'price'     => $price,
						'status'    => $status,
						'hostel_id' => $hostel->id
					] );
				}
			}
			\DB::commit();
		} catch ( \Exception $ex ) {
			\DB::rollBack();
			dd( $ex->getMessage() );

			return redirect()->back()->with( 'error', 'Có lỗi xảy ra vui lòng thử lại sau' );
		}


		return redirect()->back()->with( 'success', 'Tạo thành công' );
	}

	public function createRoom( Request $request ) {
		$data = $request->all();

		Room::create( $data );

		if ( $request->ajax() ) {
			return response( [
				'status'  => 1,
				'message' => 'Thành công'
			] );
		}
	}

	public function createOwner( Request $request ) {
		$data = $request->all();

		$data['type'] = User::OWNER;
		$data['name'] = $data['owner-name'];

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

		if ( empty( $data['owner-phone'] ) ) {
			return response( [
				'status'  => 0,
				'message' => 'Không được bỏ trống số điện thoại',
			] );
		}

		$data['phone'] = $data['owner-phone'];

		$check = User::where( 'phone', trim( $data['phone'] ) )->count();

		if ( $check ) {
			if ( $request->ajax() ) {
				return response( [
					'status'  => 0,
					'message' => 'Số điện thoại đã tồn tại trên hệ thống',
				] );
			}
		}

		User::create( $data );

		$owners = User::where( 'type', User::OWNER )->get();

		if ( $request->ajax() ) {
			return response( [
				'status'  => 1,
				'message' => 'Thành công',
				'html'    => view( 'admin.hostel.owners_select', compact( 'owners' ) )->render()
			] );
		}
	}

	public function create( Request $request ) {
		$owners = User::where( 'type', User::OWNER )->get();

		$hostelTypes = HostelType::all();

		$roomTypes = RoomType::orderBy( 'id' );

		if ( auth( 'backend' )->check() ) {
			if ( auth( 'backend' )->user()->type == User::OWNER ) {
				$roomTypes = $roomTypes->where( 'owner_id', auth( 'backend' )->user()->id );
			}
		}

		$roomTypes = $roomTypes->get();

		return view( 'admin.hostel.create', compact( 'owners', 'hostelTypes', 'roomTypes' ) );
	}

	public function getRoomsByHostel( Request $request ) {
		$hostelId = $request->input( 'hostel_id' );
		$rooms    = Room::where( 'hostel_id', $hostelId )->get();
		if ( $rooms ) {
			return response( [
				'html' => view( 'admin.hostel.room_selects', compact( 'rooms' ) )->render()
			] );
		}
	}

	public function getFloorsByHostel( Request $request ) {
		$hostelId = $request->input( 'hostel_id' );
		$floors   = Room::where( 'hostel_id', $hostelId )->groupBy( 'floor' )->pluck( 'floor' );
		{
			return response( [
				'html' => view( 'admin.hostel.floor_selects', compact( 'floors' ) )->render()
			] );
		}
	}

	public function getRoomsByFloor( Request $request ) {
		$hostelId = $request->input( 'hostel_id' );
		$floor    = $request->input( 'floor' );
		$rooms    = Room::where( 'hostel_id', $hostelId )->where( 'floor', $floor )->get();
		if ( $rooms ) {
			return response( [
				'html' => view( 'admin.hostel.room_selects', compact( 'rooms' ) )->render()
			] );
		}
	}

	public function delete( $id ) {
		$hostel = Hostel::find( $id );

		if ( $hostel ) {
			$hostel->delete();

			return redirect()->back()->with( 'success', 'Xóa dữ liệu thành công' );
		}

		return redirect()->back()->with( 'error', 'Dữ liệu không hợp lệ' );
	}

	public function deleteImage( $id, Request $request ) {
		$hostel = Hostel::find( $id );
		if ( $hostel ) {
			$hostel->image = null;
			$hostel->save();
		}

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

	}

	public function deleteImages( $id, Request $request ) {
		$key    = $request->input( 'key' );
		$hostel = Hostel::find( $id );
		if ( $hostel ) {
			$images = $hostel->images;
			$images = json_decode( $images, true );
			unset( $images[ $key ] );
			$hostel->images = json_encode( $images );
			$hostel->save();
		}

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

	public function getStatusConfirm( Request $request ) {
		return response( [
			[
				'value' => Hostel::NOT_CONFIRM,
				'text'  => 'Chưa xác nhận'
			],
			[
				'value' => Hostel::WAIT_CONFIRM,
				'text'  => 'Chờ xác nhận'
			],
			[
				'value' => Hostel::CONFIRMED,
				'text'  => 'Đã xác nhận'
			],
			[
				'value' => Hostel::CONFIRM_WRONG_DATA,
				'text'  => 'Thông tin sai thiếu'
			],
		] );
	}

	public function updateAttribute( Request $request ) {
		$id     = $request->input( 'pk' );
		$value  = $request->input( 'value' );
		$hostel = Hostel::find( $id );
		$name   = $request->input( 'name' );

		$hostel->$name = $value;
		$hostel->save();

		return 1;
	}

}
