<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models;
use App\Models\User;
use App\Models\Language;
use App\Models\Role;
use App\Models\UserProfile;
use App\Models\RoleUser;
use App\Models\AssociateCharitableOrganizationUser;
use App\Models\CharitableOrganization;
use App\Models\AssociateRestaurantUser;
use App\Models\Restaurant;
use App\Models\Badge;
use App\Models\TemporaryTable;
use Auth;
use App\Services\UserService;
use DB;
use Session;
use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\ImageManagerStatic as Image;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Validator;
use Exception;
use App\Services\DefaultServices;
use App\Services\RestaurantServices;
use App\Services\ZomatoApiServices;
use Mail;
use App\Http\Requests\AdminRestaurantEditRequest;
use Illuminate\Database\Eloquent\Collection;
use DataTables;
use App\Mail\Restaurant\RestaurantRegistrationForm;
use App\Exports\RestaurantExport;
use Maatwebsite\Excel\Facades\Excel;
use PDF;


class AdminRestaurantController extends Controller
{

    protected $userService;
    protected $request;
    protected $defaultServices;
    protected $restaurantServices;
    protected $zomatoApiServices;    

    public function __construct(UserService $userService, Request $request, DefaultServices $defaultServices, RestaurantServices $restaurantServices, ZomatoApiServices $zomatoApiServices)
    {
        $this->userService = $userService;
        $this->request     = $request;
        $this->defaultServices = $defaultServices;
        $this->restaurantServices = $restaurantServices;
        $this->zomatoApiServices = $zomatoApiServices;        
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show all schools
     */    

    public function allRestaurant()
    {
        if($this->request->ajax()) {

            $is_active  = $this->request->is_active;
            $is_school  = $this->request->is_school;
            $filters    = [];

            if($is_active != '') { 
                $filters['is_active']  = $is_active;  
            }

            if($is_school != '') { 
                $filters['is_school']  = $is_school;  
            }

            $allData = Restaurant::with(['restaurantUser', 
                    'restaurantBadge' => function($query) {
                        $query->where([                    
                            ['is_active', '=', '1'],
                        ]);
                    },
                    'restaurantAssociateUser.associateUsers' => function($query) {
                        $query->where([                    
                           // ['is_active', '=', '1'],
                        ]);
                    }])
                    ->where($filters);                        

            return datatables($allData)->make(true);
        }

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

    public function changeStatus(Request $request)
    {
        $school_id     = trim($this->request->id);
        $school_status = trim($this->request->is_active)=='active'?"1":"0";
        
        $data['id']        = $school_id;
        $data['is_active'] = $school_status;

        Restaurant::where('id', $school_id)->update($data);
    }

    public function showCharitableOrganization($id)
    {
        // $allData = Restaurant::find(trim($id));
        // return view('admin.charitableOrganizations.charitable-organization-show')->with(['recordDetails' => $allData ]);
    }

    public function editRestaurant($id)
    {
        $allData = User::with(['userRoles'])
                    ->whereHas('userRoles', function ($query) {
                        $query->where([
                            ['slug', '=', 'restaurant-owner'],
                            ['roles.is_active', '=', '1'],                            
                        ]);
                    })
                    ->whereDoesntHave('userAssociateRestaurant')
                    ->orWhereHas('userAssociateRestaurant', function ($query) use($id) {
                        $query->where([
                            ['associate_restaurant_users.restaurant_id', '=', $id],
                        ]);
                    })
                    ->get()->toArray();

        $filters['id']  = $id; 

        $restaurantDetails = Restaurant::with([
                    'restaurantBadge' => function($query) {
                        $query->where([                    
                            ['is_active', '=', '1'],
                        ]);
                    },
                    'restaurantAssociateUser' => function($query) {
                        $query->where([                    
                            ['is_active', '=', '1'],
                        ]);
                    }])
                    ->where($filters)
                    ->first();  

        if($restaurantDetails) {
            $restaurantDetails = objectToArray($restaurantDetails);

            if($restaurantDetails['restaurant_associate_user']){
                $restaurantDetails['restaurant_associate_user'] = array_reduce($restaurantDetails['restaurant_associate_user'], function($carry, $item){
                        $carry[] = $item['user_id'];         
                        return $carry;
                    });
            }
        }
        
        return view('admin.restaurants.edit')->with(['users' => $allData, 'restaurantDetails' => $restaurantDetails ]);
    }

    public function updateRestaurant(AdminRestaurantEditRequest $req)
    {
        try {
            $req->validated();
            if ($req->isMethod('post')) {

                $inputs = $req->all();
                $inputs = $this->defaultServices->getTrimmedValue($inputs);

                $id               = $inputs['id']; 
                $data['restaurant_name'] = $inputs['restaurant_name'];
                $data['slug']     = Str::slug($data['restaurant_name']." ".$id, '-');
                $data['phone']    = $inputs['phone'];
                $data['address']  = $inputs['address'];
                $data['zip_code'] = $inputs['zip_code'];
                $data['is_individual_commission'] = $inputs['is_individual_commission']=="yes"?1:0;
                
                if(isset($inputs['admin_commission']) && is_numeric($inputs['admin_commission'])){
                    $data['admin_commission'] = $inputs['admin_commission'];
                }

                if($data['is_individual_commission'] == 0) {
                    $data['admin_commission'] = 0;
                }

                if(isset($inputs['latitude']) && $inputs['latitude']){
                    $data['latitude'] = $inputs['latitude'];
                }

                if(isset($inputs['longitude']) && $inputs['longitude']){
                    $data['longitude'] = $inputs['longitude'];
                }

                $restaurantDetails = Restaurant::find($id);
                $is_individual_commission = $restaurantDetails->is_individual_commission;
                $admin_commission = $restaurantDetails->admin_commission;
                $restaurantDetails->update($data);

                if($is_individual_commission != $restaurantDetails->is_individual_commission || 
                    ($restaurantDetails->is_individual_commission == 1 && $restaurantDetails->admin_commission != $admin_commission) ) {

                    $admin_commission = 0;

                    if($restaurantDetails->is_individual_commission == 1){
                        $admin_commission = $restaurantDetails->admin_commission;
                    }
                    else {
                        $admin_commission = get_setting('admin-commissions');
                    }

                    $menuAddOnMenu = $this->restaurantServices->getAllMenuAndAddOnItems($restaurantDetails->id);

                    if(objectToArray($menuAddOnMenu->getMenuItems)) {                        
                        $this->restaurantServices->updateAllMenuItemPrice($menuAddOnMenu->getMenuItems, $restaurantDetails->id, $admin_commission);
                    }

                    if(objectToArray($menuAddOnMenu->getMenuAddOnItems)) {                        
                        $this->restaurantServices->updateAllMenuAddOnItemPrice($menuAddOnMenu->getMenuAddOnItems, $restaurantDetails->id, $admin_commission);
                    }
                }

                $data = [];
                AssociateRestaurantUser::where('restaurant_id', $id)->delete();

                if($inputs['user_id'] && count($inputs['user_id'])) {
                    foreach ($inputs['user_id'] as $key => $user_id) {
                        $associate_data['restaurant_id'] = $id;
                        $associate_data['user_id'] = $user_id;
                        $associate_data['is_active'] = 1;
                        $associate_data['created_at'] = date('Y-m-d H:i:s');
                        $associate_data['updated_at'] = date('Y-m-d H:i:s');

                        $data[] = $associate_data;
                    }

                    AssociateRestaurantUser::insert($data);
                }

                $badge = Badge::where('restaurant_id', $id)->first();
                $where = [];

                // store logo image
                if($this->request->logo)
                {
                    $rootFolderPath = public_path('/storage/images/restaurants/badges/');                   

                    if(objectToArray($badge) && $badge->logo){
                        $this->defaultServices->unlinkImg($rootFolderPath, $badge->logo);
                    }

                    $logo_image    = $this->request->file('logo');
                    $where['logo'] = $this->defaultServices->bannerLogoUpload($rootFolderPath, $logo_image);
                }

                // store banner image
                if($this->request->banner_image)
                {
                    $rootFolderPath = public_path('/storage/images/restaurants/banner/');

                    if(objectToArray($restaurantDetails) && $restaurantDetails->banner_image){
                        $this->defaultServices->unlinkImg($rootFolderPath, $restaurantDetails->banner_image);
                    }

                    $restaurant_image = $this->request->file('banner_image');
                    $restaurantDetails->banner_image = $this->defaultServices->bannerLogoUpload($rootFolderPath, $restaurant_image);

                    $restaurantDetails->save();
                }

                if($inputs['discount']) {
                    $where['discount'] = $inputs['discount'];
                }

                if($where) {
                    Badge::updateOrCreate(
                        ['restaurant_id' => $id],
                        $where
                    );
                }                

                $req->session()->flash('success-message', 'Restaurant updated successfully');
            }
            return redirect()->back();
        } catch (Exception $ex) {
            return redirect()->back()->withErrors(['error-messsage' => [$ex->getMessage()]]); 
        }
    }

    public function associateCharitableOrganization($id){
        try 
        {
            $filters['id']  = $id;
            $restaurantDetails = Restaurant::find($id);

            if($this->request->ajax()) {

                $inputs = $this->request->all();                
                $filters    = [];

                if($inputs['is_active'] != '') { 
                    $filters['co.is_active']  = $inputs['is_active'];  
                }

                if($inputs['is_school'] != '') { 
                    $filters['co.is_school']  = $inputs['is_school'];  
                }

                $allData = $this->restaurantServices->restaurantAssociatedCharitableOrganizations($id, $filters);               

                return datatables($allData)->make(true);
            }       

            return view('admin.restaurants.organizations')->with(['recordDetails' => $restaurantDetails ]);

        } catch (Exception $ex) {
            return redirect()->back()->withErrors(['error-messsage' => [$ex->getMessage()]]); 
        }
    }

    public function sendRegistrationFormLink()
    {
        try 
        {
            if($this->request->isMethod('post')) {
                $filters = [];
                $inputs = $this->request->all();
                $inputs = $this->defaultServices->getTrimmedValue($inputs);                

                $validator = Validator::make($inputs, [
                    'email' => 'required|email',
                ]);

                if($validator->fails()) {
                    return redirect()->back()->withErrors(['error-messsage' => ["Please enter valid email id"]]);
                    exit(0);
                }
                
                $filters['email'] = $inputs['email'];                
                $allData = User::with(['userRoles'])->where($filters)->first();

                if(objectToArray($allData)){
                    $allData = $allData->toArray();

                    $roles = array_reduce($allData['user_roles'], function($carry, $item){
                        $carry[] = $item['name'];         
                        return $carry;
                    });

                    return redirect()->back()->withErrors(['error-messsage' => ["Email id exists as ".implode(" and ", $roles)]]);
                    exit(0);                    
                }
                else
                {
                    $filters = [];
                    if($inputs['email']) { 
                        $filters['purpose_value']  = $inputs['email'];  
                    }

                    $tempTable = new TemporaryTable;
                    $tempTable->purpose_name = "Send Restaurant Registration Form";
                    $tempTable->purpose_slug = Str::slug($tempTable->purpose_name, '-');
                    $tempTable->purpose_value = $inputs['email'];
                    $tempTable->description = '';
                    $tempTable->update_to_table = 0;
                    $tempTable->is_active = 1;

                    $tempTable->save();

                    $tempTable->description = url('restaurantOwner/registration/'.encript_decript_data( $tempTable->id, 'encript', 2 ));
                    $tempTable->save();

                    $to = $inputs['email'];
                    $mail_body = new \stdClass();
                    $mail_body->subject = "Restaurant Registration Form";
                    $mail_body->name = "User";
                    $mail_body->email = $to;
                    $mail_body->reg_link = $tempTable->description;

                    $email_content = Mail::to($to)->send(new RestaurantRegistrationForm($mail_body));

                    if (Mail::failures()) {
                        $this->request->session()->flash('error-message', 'Mail not sent');
                    }
                    else{
                        $this->request->session()->flash('success-message', 'Mail sent successfully.');
                    }

                    return redirect()->back();
                }                
            }
            
            return view('admin.restaurants.regForm');

        } catch (Exception $ex) {
            return redirect()->back()->withErrors(['error-messsage' => [$ex->getMessage()]]); 
        }
    }

    public function isExistOwnerEmailinTemp(){

        if($this->request->ajax()) {
            $inputs = $this->request->all();
            $inputs = $this->defaultServices->getTrimmedValue($inputs);  

            $filters = [];            
            $filters['purpose_value']  = $inputs['data_value'];                                   

            $details = $this->defaultServices->checkValueInTemp($filters);

            if($details['status']){
                $details['message'] = "Already sent.";
            }

            return response()->json($details);
        }        
    }

    public function fetchAllRestaurants()
    {
        try 
        {
            if($this->request->isMethod('post')) {
                $filters = [];
                $inputs = $this->request->all();
                $inputs = $this->defaultServices->getTrimmedValue($inputs);              

                $validator = Validator::make($inputs, [
                    'address' => 'required',
                ]);

                if($validator->fails()) {
                    return redirect()->back()->withErrors(['error-messsage' => ["Please enter valid address"]]);
                    exit(0);
                }

                session(['newResCount' => 0]);
                $allRestaurants = Restaurant::all()->toArray();

                $inputs['offset'] = 0;
                $inputs['limit']  = 20; 
                $inputs['radius'] = $inputs['range'];
                $inputs['sort']   = 'real_distance';
                $inputs['order']  = 'asc';

                while(1) {
                    $allData = $this->zomatoApiServices->fetchRestaurants($inputs);                   

                    if(isset($allData['results_found']) && $allData['results_found'] > 0) {
                        
                        if(count($allData['restaurants']) > 0) {
                            $this->storingZomatoRestaurants($allData['restaurants'], $allRestaurants);
                            $inputs['offset'] = $inputs['offset']+20;
                        }
                        else {
                            break;
                        }
                    }
                    else {
                        break;
                    }

                    sleep(2);
                }

                if(session('newResCount') > 0){
                    Session::flash('success-message', session('newResCount').' records has been added');
                }
                else {
                    Session::flash('error-message', 'No new records found');
                }

                $this->request->session()->forget('newResCount');                            
            }
            
            return view('admin.restaurants.fetchRegApi');

        } catch (Exception $ex) {
            return redirect()->back()->withErrors(['error-messsage' => [$ex->getMessage()]]); 
        }
    }

    public function storingZomatoRestaurants($zomatoRestaurants = [], $allRestaurants)
    {
        try 
        {
            foreach ($zomatoRestaurants as $key => $restaurant) {
                              
                $data['restaurant_name'] = $restaurant['restaurant']['name']??NULL;
                $data['address'] = $restaurant['restaurant']['location']['address']??NULL;
                $data['latitude'] = $restaurant['restaurant']['location']['latitude']??NULL;
                $data['longitude'] = $restaurant['restaurant']['location']['longitude']??NULL;                
                $data['is_active'] = 0;
                $data['zip_code'] = $restaurant['restaurant']['location']['zipcode']??NULL;                
                $data['is_from_api'] = 1;
                $data['zomato_restaurant_id'] = $restaurant['restaurant']['id']??NULL;

                if(isset($restaurant['restaurant']['phone_numbers']) && $restaurant['restaurant']['phone_numbers'] && ($restaurant['restaurant']['phone_numbers'] != 'Not available for this place')) {
                    $data['phone'] = $restaurant['restaurant']['phone_numbers']??NULL;
                }

                $restaurant = [];

                if(!is_null($data['zomato_restaurant_id']) && $data['zomato_restaurant_id']) {
                    $restaurant = Restaurant::updateOrCreate(
                                    ['zomato_restaurant_id' => $data['zomato_restaurant_id']],
                                    $data
                                );

                    if ($restaurant->wasRecentlyCreated) {
                        session(['newResCount' => (session('newResCount')+1)]);
                    }
                }

                if($restaurant) {                    
                    $restaurant['slug'] = Str::slug($restaurant['restaurant_name']." ".$restaurant['id'], '-');
                    $restaurant->save();

                    $badge = [];

                    //$badge['logo'] = NULL;
                    $badge['restaurant_id'] = $restaurant['id'];                
                    //$badge['discount'] = 0;
                    $badge['is_active'] = 1;

                    $badge = Badge::updateOrCreate(
                        ['restaurant_id' => $restaurant['id']],
                        $badge
                    );

                    array_push($allRestaurants, $restaurant->toArray());
                }

                unset($data);
            }

        } catch (Exception $ex) {
            return redirect()->back()->withErrors(['error-messsage' => [$ex->getMessage()]]); 
        }
    }

    public function exportRestaurant(){

        try 
        {
            return Excel::download(new RestaurantExport, 'Restaurants'.date('d-m-Y').'.xlsx');

        } catch (Exception $ex) {
            return redirect()->back()->withErrors(['error-messsage' => [$ex->getMessage()]]); 
        }
    }

    public function getMenu(Request $req) 
    {
        try 
        {
            $user_type = "admin";
            $restaurant_id = trim($req->restaurant_id);
            $restaurantDetails = Restaurant::find($restaurant_id);
            $menu = $this->restaurantServices->getFullMenuDetailsByRestaurantId($restaurant_id, $user_type);

            $is_individual_commission = $restaurantDetails->is_individual_commission;
            $admin_commission = $restaurantDetails->admin_commission;

            if($is_individual_commission == 0) {
                $admin_commission = get_setting('admin-commissions');
            }                

            if(empty(objectToArray($menu))) {
                return "No menu found";
            }

            $menu = json_decode(json_encode($menu), FALSE);            
            return view('admin.restaurants.menu')->with(['menu' => $menu, "restaurantDetails" => $restaurantDetails, "user_type" => $user_type, "admin_commission" => $admin_commission]);

        } catch (Exception $ex) {
            return redirect()->back()->withErrors(['error-messsage' => [$ex->getMessage()]]); 
        }
    }

    public function downloadMenu(Request $req) 
    {
        try 
        {
            $user_type = "admin";
            $restaurant_id = trim($req->restaurant_id);
            $restaurantDetails = Restaurant::find($restaurant_id);
            $menu = $this->restaurantServices->getFullMenuDetailsByRestaurantId($restaurant_id, $user_type);
            $menu = json_decode(json_encode($menu), FALSE);

            $is_individual_commission = $restaurantDetails->is_individual_commission;
            $admin_commission = $restaurantDetails->admin_commission;

            if($is_individual_commission == 0) {
                $admin_commission = get_setting('admin-commissions');
            }

            $pdf = PDF::loadView('admin.restaurants.menu',['menu'=>$menu, "restaurantDetails" => $restaurantDetails, "user_type" => $user_type, "admin_commission" => $admin_commission]);
            return $pdf->download(time().'.pdf');

        } catch (Exception $ex) {
            return redirect()->back()->withErrors(['error-messsage' => [$ex->getMessage()]]); 
        }
    }

}
