<?php

namespace App\Http\Controllers;

use App\DataTables\CruisesDataTable;
use App\Models\Cruise;
use App\Models\Room;
use App\Models\RoomType;
use App\Models\Service;
use App\Models\Ticket;
use App\Models\SegmentService;
use App\Models\TravelSegment;
use App\Models\User;
use App\Notifications\CruiseAdded;
use App\Traits\Currencies;
use Carbon\Carbon;
use Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Notification;

class CruiseController extends Controller
{
    use Currencies;
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(CruisesDataTable $dataTable)
    {
        return $dataTable->render('cruises.index');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $data = $this->validate($request, [
            'ship_id' => 'required|numeric',
            'cruise_number' => 'required|string|min:6|max:6',
            'name' => 'required|string|max:191',
            'departure_date' => 'required|date',
            'departure_time' => 'required|string',
            'arrival_date' => 'required|date',
            'arrival_time' => 'required|string',
            'origin_port' => 'required',
            'destination_port' => 'required',
            'weight' => 'required|numeric',
            'bags' => 'required|numeric',
            'enabled' => 'boolean'
        ]);
        $cruise =  Cruise::create([
            'ship_id' => $request->ship_id,
            'cruise_number' => $request->cruise_number,
            'name' => $request->name,
            'origin_port' => $request->origin_port,
            'destination_port' => $request->destination_port,
            'departure_date_time' => $request->departure_date . ' ' . $request->departure_time,
            'arrival_date_time' => $request->arrival_date . ' ' . $request->arrival_time,
            'weight' => $request->weight,
            'bags' => $request->bags,
        ]);

        Notification::send(User::all(), new CruiseAdded($cruise));
        return $cruise;
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show(Request $request,$id)
    {
        $cruise =  Cruise::findOrFail($id);
        if($request->ajax()){
            return [
                'id' => $cruise->id,
                'ship_id' => $cruise->ship,
                'cruise_number' => $cruise->cruise_number,
                'name' => $cruise->name,
                'departure_date' => $cruise->departure_date,
                'departure_time' => $cruise->departure_time,
                'arrival_date' => $cruise->arrival_date,
                'arrival_time' => $cruise->arrival_time,
                'origin_port' => $cruise->origin_port,
                'destination_port' => $cruise->destination_port,
                'weight' => $cruise->weight,
                'bags' => $cruise->bags,
                'status' => $cruise->status
            ];
        }
        return view('cruises.show',compact('cruise'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Cruise $cruise)
    {
        $data = $this->validate($request, [
            'cruise_number' => 'required|string|min:6|max:6',
            'name' => 'required|string|max:191',
            'departure_date' => 'required|date',
            'departure_time' => 'required|string',
            'arrival_date' => 'required|date',
            'arrival_time' => 'required|string',
            'origin_port' => 'required',
            'destination_port' => 'required',
            'weight' => 'required|numeric',
            'bags' => 'required|numeric',
            'status' => 'required|boolean'
        ]);

        $cruise->update([
            'cruise_number' => $request->cruise_number,
            'name' => $request->name,
            'origin_port_code' => $request->origin_port,
            'destination_port_code' => $request->destination_port,
            'departure_date_time' => $request->departure_date . ' ' . $request->departure_time,
            'arrival_date_time' => $request->arrival_date . ' ' . $request->arrival_time,
            'weight' => $request->weight,
            'bags' => $request->bags,
            'status' => $request->status
        ]);
        return $cruise;
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        return Cruise::findOrFail($id)->delete();
    }

    public function originPort()
    {
        return DB::table('ports')
            ->select('code', 'ports.name', 'country')
            ->join('cruises', 'ports.code', '=', 'cruises.origin_port')
            ->whereDate('cruises.departure_date_time', '>=', Carbon::now())
            ->groupBy('ports.code')
            ->paginate(25);
    }

    public function destinationPort()
    {
        return DB::table('ports')
            ->select('code', 'ports.name', 'country')
            ->join('cruises', 'ports.code', '=', 'cruises.destination_port')
            ->whereDate('cruises.departure_date_time', '>=', Carbon::now())
            ->groupBy('ports.code')
            ->paginate(25);
    }

    public function search(Request $request)
    {
        $qb = Cruise::where('status', '=', true);
        if ($request->id) {
            $cruise = Cruise::findOrFail($request->id);
            $request->merge([
                    "from"=>$cruise->origin_port,
                    "to"=>$cruise->destination_port,
            ]); 

        } 

        if ($request->departure_date) {
            $qb->where('departure_date_time', '>', $request->departure_date);
        }
        if ($request->from) {
            $qb->where('origin_port', '=', $request->from);
        }
        if ($request->to) {
            $qb->where('destination_port', '=', $request->to);
        }

        return $qb->get();
    }

    public function services(Cruise $cruise)
    {
     
      
     $quantity= SegmentService::whereHas('segment.cruise',function($q)use($cruise){
            $q->where('cruise_id',$cruise->id);
        })
        ->whereHas('ticket', function($query) {
            $query->where('ticket_status','=','O');
        })
        ->sum('quantity');
     
        Session::put('quantity', $quantity);

        
        return $cruise->services()->get()->map(function ($service) use($quantity) {
            return  $service->mix();
        });
        
    }
    public function carCapacity($car_id,$cruise_id){
       $quantity= SegmentService::where('car_id',$car_id)->whereHas('segment.cruise',function($q)use($cruise_id){
            $q->where('cruise_id',$cruise_id);
        })
        ->whereHas('ticket', function($query) {
            $query->where('ticket_status','=','O');
        })
        ->sum('quantity');
        
        return response()->json($quantity);
        
    }

    public function roomTypes(Request $request,Cruise $cruise)
    {
        return $cruise->roomTypes()
            ->get()
            ->map(function ($room_type) use($request) {
                return $room_type->mix($request->back=='true'?true:false);
            });
            
    }
}
