MOON
Server: Apache
System: Linux e2e-78-16.ssdcloudindia.net 3.10.0-1160.45.1.el7.x86_64 #1 SMP Wed Oct 13 17:20:51 UTC 2021 x86_64
User: imensosw (1005)
PHP: 7.4.33
Disabled: exec,passthru,shell_exec,system
Upload Files
File: /home/imensosw/www/mpl.imenso.co/app/Models/User.php
<?php

namespace App\Models;

use App\Events\ArtistRecommendsArtist;
use App\Events\ArtistUnrecommendsArtist;
use App\Events\FanAcceptsFriendRequest;
use App\Events\FanFriendRequestsFan;
use App\Events\FanMarksArtistAsLikeToSeeLive;
use App\Events\FanMarksArtistAsSeenLive;
use App\Events\FanUnfriendRequestsFan;
use App\Events\FanUnmarksArtistAsSeenLive;
use App\Events\VenueMarkedAsApproved;
use App\Library\UserConnectionsProvider;
use App\Mail\BandWelcomeEmail;
use App\Mail\FanWelcomeEmail;
use App\Mail\GlobalPromoterRequestEmail;
use App\Mail\PromoterWelcomeEmail;
use App\Mail\UserPasswordResetEmail;
use App\Mail\VenueWelcomeEmail;
use App\Traits\GrantsImpersonationAuthorisation;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Http\Request;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\MessageBag;
use Illuminate\Support\Str;
use Intervention\Image\Facades\Image as ImageLibrary;
use Laravel\Scout\Searchable;
use Lab404\Impersonate\Models\Impersonate;

class User extends Authenticatable
{
    use HasFactory, Notifiable, Impersonate, GrantsImpersonationAuthorisation;

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
        'password_reset_code',
        'ip',
    ];

    protected $casts = [
        'last_online_at' => 'datetime',
    ];

    protected $appends = [
        'full_name',
    ];

   /* public function toSearchableArray()
    {
        $array = [
            'id'              => $this->id,
            'first_name'      => $this->first_name,
            'last_name'       => $this->last_name,
            'email'           => $this->email,
            'venue_name'      => $this->venue_name,
            'contact_name'    => $this->contact_name,
            'contact_email'   => $this->contact_email,
            'city'            => $this->city,
            'postcode'        => $this->postcode,
            'website'         => $this->website,
            'artist_name'     => $this->artist_name,
            'promoter_name'   => $this->promoter_name,
            'type_id'         => $this->type_id,
            'allow_enquiries' => $this->allow_enquiries,
            'venue_claimed'   => $this->venue_claimed,
        ];

        return $array;
    }*/

    public function type()
    {
        return $this->belongsTo(\App\Models\UserType::class, 'type_id');
    }

    public function enquiries($orderByPencilOrder = false)
    {
        if ($this->isBand()) {
            $query = $this
                ->artistEnquiries()
                ->whereNull('closed')
                ->orderByDesc('enquiry_at');
        }

        if ($this->isPromoter()) {
            $query = Enquiry::whereNull('closed')
                ->where('promoter_id', $this->id)
                ->orderByDesc('enquiry_at');
        }

        if ($this->isVenue()) {
            $query = Enquiry::whereNull('closed')
                ->where('venue_id', $this->id);

            if ($orderByPencilOrder == true) {
                $query->orderBy('pencil_order', 'ASC');
            }

            $query->orderByDesc('enquiry_at');
        }

        return $query;
    }

    public function artistEnquiries()
    {
        return $this->belongsToMany(Enquiry::class, 'enquiry_artists', 'artist_id', 'enquiry_id');
    }

    public function country()
    {
        return $this->belongsTo(\App\Models\Country::class, 'country_id');
    }

    public function arcampaigns()
    {
        return $this->hasMany(ARCampaign::class);
    }

    public function images()
    {
        return $this->morphMany(\App\Models\Image::class, 'imageable');
    }

    public function files()
    {
        return $this->morphMany(\App\Models\File::class, 'fileable');
    }

    public function videos()
    {
        return $this->morphMany(\App\Models\Video::class, 'videoable');
    }

    public function galleries()
    {
        return $this->morphMany(\App\Models\Gallery::class, 'galleryable');
    }

    public function news()
    {
        return $this->hasMany(\App\Models\News::class);
    }

    public function unfilteredReferals()
    {
        return $this->hasMany(self::class, 'referer_id');
    }

    public function referals()
    {
        return $this->unfilteredReferals()->where('country_id', 74)->where('type_id', 3)->get();
    }

    public function isTeamerReady()
    {
        return $this->teamer_ready;
    }

    public function defaultAvailability()
    {
        return $this->availability()->where('is_default', 1)->first();
    }

    public function teamers()
    {
        $fans = new Collection;

        foreach (FanArtistTeamConnection::where('artist_id', $this->id)->get() as $connection) {
            $temp_fan = self::findOrFail($connection->fan_id);
            $fans->push($temp_fan);
        }

        return $fans;
    }

    public function futureEvents($announced_only = false)
    {
        return $this->unsortedEvents($announced_only)
            ->where('event_at', '>', \Carbon\Carbon::now())
            ->orderBy('event_at')
            ->get();
    }

    public function pastEvents($announced_only = false)
    {
        return $this->unsortedEvents($announced_only)
            ->where('event_at', '<', \Carbon\Carbon::now())
            ->orderBy('event_at')
            ->get();
    }

    public function futureNonTourEvents($announced_only = false)
    {
        return $this
            ->events($announced_only)
            ->whereDoesntHave('tours')
            ->where('event_at', '>', \Carbon\Carbon::now())
            ->get();
    }

    public function promoterlessEvents($announced_only = false)
    {
        return $this
            ->events($announced_only)
            ->whereNull('promoter_id')
            ->orderBy('event_at', 'DESC');
    }

    // Escape hatch to use queries where the rest of the code uses collections.
    public function unsortedEvents($announced_only = false)
    {
        if ($this->isBand()) {
            $query = $this->belongsToMany(Event::class, 'event_artists', 'artist_id', 'event_id');

            if ($announced_only) {
                $query->where('events.status_id', 3);
            }

            return $query;
        } 
        
        if ($this->isVenue()) {
            $query = $this->hasMany(Event::class, 'venue_id');

            if ($announced_only) {
                $query->where('status_id', 3);
            }

            return $query;
        } 
        
        if ($this->isPromoter()) {
            $query = $this
                ->hasMany(Event::class, 'promoter_id')
                ->union(
                    $this
                        ->hasMany(Event::class, 'agent_id')
                );

            if ($announced_only) {
                $query->where('status_id', 3);
            }

            return $query;
        }
    }

    public function events($announced_only = false, $order = 'DESC')
    {
        if ($this->isBand()) {
            $query = $this->belongsToMany(Event::class, 'event_artists', 'artist_id', 'event_id');

            if ($announced_only) {
                $query->where('events.status_id', 3);
            }

            return $query
                ->orderBy('events.event_at', $order)
                ->orderBy('events.id', $order);
        } elseif ($this->isVenue()) {
            $query = $this->hasMany(Event::class, 'venue_id');

            if ($announced_only) {
                $query->where('status_id', 3);
            }

            return $query
                ->orderBy('event_at', $order)
                ->orderBy('id', $order);
        } elseif ($this->isPromoter()) {
            $query = $this->hasMany(Event::class, 'promoter_id');

            if ($announced_only) {
                $query->where('status_id', 3);
            }

            return $query
                ->orderBy('event_at', $order)
                ->orderBy('id', $order);
        }
    }

    public function venue_events()
    {
        return $this->hasMany(\App\Models\Event::class, 'venue_id');
    }

    public function checkoutIgnores()
    {
        if ($this->isFan()) {
            return $this->hasMany(\App\Models\FanArtistCheckoutIgnore::class, 'fan_id');
        } elseif ($this->isArtist()) {
            return $this->hasMany(\App\Models\ArtistArtistCheckoutIgnore::class, 'artist1_id');
        } elseif ($this->isPromoter()) {
            return $this->hasMany(\App\Models\PromoterArtistCheckoutIgnore::class, 'promoter_id');
        }
    }

    public function hasIgnoredCheckoutArtist($artist_id)
    {
        if ($this->isArtist()) {
            if ($this->checkoutIgnores()->where('artist2_id', $artist_id)->count() > 0) {
                return true;
            }
        } else {
            if ($this->checkoutIgnores()->where('artist_id', $artist_id)->count() > 0) {
                return true;
            }
        }

        return false;
    }

    public function albums()
    {
        return $this->hasMany(\App\Models\Album::class, 'artist_id');
    }

    public function comments()
    {
        return $this->hasMany(\App\Models\Comment::class);
    }

    public function likes()
    {
        return $this->hasMany(\App\Models\Like::class);
    }

    public function notifications()
    {
        return $this->hasMany(\App\Models\Notification::class)->orderByDesc('created_at');
    }

    public function notification_preferences()
    {
        return $this->hasMany(\App\Models\UserNotificationPreference::class);
    }

    public function messaging_preferences()
    {
        return $this->hasMany(\App\Models\UserMessagingPreference::class);
    }

    public function genres()
    {
        return $this->belongsToMany(\App\Models\Genre::class, 'user_genres');
    }

    public function devices()
    {
        return $this->hasMany(\App\Models\Device::class);
    }

    public function tickets()
    {
        return $this->hasMany(\App\Models\Ticket::class);
    }

    public function point_adjustments()
    {
        return $this->hasMany(\App\Models\PointAdjustment::class);
    }

    public function tours()
    {
        return $this->hasMany(\App\Models\Tour::class, 'creator_id');
    }

    public function announcedTours()
    {
        return $this->tours()->where('status_id', 2)->get();
    }

    public function teamersDisabled()
    {
        return $this->teamers_disabled;
    }

    public function announcedFutureTours()
    {
        $announcedTours = $this->announcedTours();

        if ($this->isBand()) {
            $headliner_tour_ids = DB::table('tour_artists')->select('tour_id')->where('artist_id',
                $this->id)->where('slot_type_id', 1)->pluck('tour_id');
            $headliner_tours = Tour::whereIn('id', $headliner_tour_ids)->where('status_id', 2)->get();

            foreach ($headliner_tours as $ht) {
                $announcedTours->push($ht);
            }
        }

        $futureTours = new Collection;

        if ($announcedTours->count() > 0) {
            foreach ($announcedTours as $tour) {
                if ($tour->isFutureTour()) {
                    $futureTours->push($tour);
                }
            }
        }

        return $futureTours;
    }

    public function availability()
    {
        if ($this->isVenue()) {
            return $this->hasMany(\App\Models\VenueAvailability::class, 'venue_id')->orderBy('availability_at');
        } elseif ($this->isBand()) {
            return $this->hasMany(\App\Models\ArtistAvailability::class, 'artist_id')->orderBy('availability_at');
        }
    }

    public function futureAvailabilities()
    {
        return $this->availability()->whereDate('availability_at', '>=', Carbon::now());
    }

    public function message_threads()
    {
        $thread_ids = DB::table('message_thread_participants')
            ->select('message_thread_participants.thread_id')
            ->join('message_threads', 'message_thread_participants.thread_id', '=', 'message_threads.id')
            ->leftJoin('messages', function ($join) {
                $join->on('messages.thread_id', '=', 'message_thread_participants.thread_id')
                ->on('messages.id', '=', DB::raw('(SELECT `m2`.`id` FROM `messages` `m2` WHERE `m2`.`thread_id` = `message_thread_participants`.`thread_id` ORDER BY `m2`.`created_at` DESC LIMIT 1)'));
            })
            ->where('user_id', $this->id)
            ->where('message_threads.enquiry_id', 0)
            ->orderByDesc('messages.created_at')
            ->groupBy('message_thread_participants.thread_id')
            ->get();

        $threads = new Collection;

        foreach ($thread_ids as $id) {
            $threads->push(MessageThread::findOrFail($id->thread_id));
        }

        return $threads;
    }

    public function newNotifications()
    {
        return $this->notifications()
            ->where('dismissed', 0)
            ->orderByDesc('created_at')
            ->get();
    }

    public function newNotificationCount($max = 99)
    {
        $count = $this->newNotifications()->count();

        if ($count > $max) {
            return $max.'+';
        } else {
            return $count;
        }
    }

    public function getFullNameAttribute()
    {
        if ($this->isBand()) {
            return $this->artist_name;
        } elseif ($this->isVenue()) {
            return $this->venue_name;
        } elseif ($this->isFan()) {
            return $this->first_name.' '.$this->last_name;
        } elseif ($this->isPromoter()) {
            return $this->promoter_name;
        } elseif ($this->isAdmin()) {
            return $this->first_name.' '.$this->last_name;
        }
    }

    public function recommendedByBands()
    {
        return $this->belongsToMany(User::class, 'artist_artist_connections', 'artist2_id', 'artist1_id')->get();
    }

    public function bands()
    {
        return $this->getConnections('artist');
    }

    public function getDreamLineup($type)
    {
        $band_collection = new Collection;
        $bands = $this->getConnections('artist');
        $bands_seen = $this->bandsSeen();

        foreach ($bands as $band) {
            $band_collection->push($band);
        }

        foreach ($bands_seen as $band) {
            $band_collection->push($band);
        }

        $dream_lineup = new Collection;
        foreach ($band_collection as $band) {
            if ($type == 'artist') {
                $connections = DB::table('artist_artist_connections')->where('artist1_id', $this->id)->where('artist2_id', $band->id)->where('order', '!=', 0)->get();
            } elseif ($type == 'fan') {
                $connections = new Collection;
                $follows = DB::table('fan_artist_follows')->where('fan_id', $this->id)->where('artist_id', $band->id)->where('order', '!=', 0)->get();
                $seen = DB::table('fan_artist_seen')->where('fan_id', $this->id)->where('artist_id', $band->id)->where('order', '!=', 0)->get();
                foreach ($follows as $follow) {
                    $connections->push($follow);
                }
                foreach ($seen as $s) {
                    $connections->push($s);
                }
            }
            if ($connections->count() > 0) {
                foreach ($connections as $connection) {
                    $band->order = $connection->order;
                    $dream_lineup->push($band);
                }
            }
        }

        $dream_lineup = $dream_lineup->unique('order');
        $dream_lineup = $dream_lineup->sortBy('order');

        return $dream_lineup;
    }

    public function checkoutBandsRecommends($mpl_artist_spacing = 5)
    {
        return Cache::remember("{$this->id}_band_recomendations", 1000, function () use ($mpl_artist_spacing) {
            $connections = [];
            $band_ids = [];

            $existing_connections = [];

            foreach ($this->getConnections('artist', 'SeeLive') as $artist) {
                $existing_connections[] = $artist->id;
            }

            foreach ($this->getConnections('artist', 'SeenLive') as $artist) {
                $existing_connections[] = $artist->id;
            }

            $existing_connections = array_unique($existing_connections);

            $ignored_checkout_artists = DB::table('fan_artist_checkout_ignores')
                ->where('fan_id', $this->id)
                ->pluck('artist_id');

            //Grab all artist recommended connections

            $fan_follows = DB::table('fan_artist_follows')
                ->where('fan_id', $this->id)
                ->pluck('artist_id');

            $artist_follows = DB::table('artist_artist_connections')
                ->whereIn('artist1_id', $fan_follows)
                ->whereNotIn('artist2_id', $fan_follows)
                ->whereNotIn('artist2_id', $existing_connections)
                ->whereNotIn('artist2_id', $ignored_checkout_artists)
                ->get();

            foreach ($artist_follows as $checkout_band) {
                $band_ids[] =
                    [
                        'recommender' => $checkout_band->artist1_id,
                        'recommendee' => $checkout_band->artist2_id,
                        'timestamp'   => Carbon::parse($checkout_band->created_at),
                    ];
            }

            $mpl_artists = new Collection;
            $mpl_artists_unsubscribed = new Collection;

            $genres_to_search = new Collection;
            $genres_to_search_ids = [];

            foreach ($this->genres as $genre) {
                $genres_to_search_ids[] = $genre->id;
                if ($genre->parent_id && ! in_array($genre->parent_id, $genres_to_search_ids)) {
                    $genres_to_search_ids[] = $genre->parent_id;
                }
            }

            $genres_to_search = Genre::whereIn('id', $genres_to_search_ids)->get();

            $mpl_artist_ids = [];

            //Loop through all genres
            foreach ($genres_to_search as $genre) {
                $mpl_artists_ids = DB::table('user_genres')
                    ->select('user_genres.user_id')
                    ->join('users', 'users.id', '=', 'user_genres.user_id')
                    ->where('users.artist_subscribed', 1)
                    ->whereNotIn('user_genres.user_id', $existing_connections)
                    ->whereNotIn('user_genres.user_id', $ignored_checkout_artists)
                    ->where('users.type_id', 2)
                    ->take(20)
                    ->get();

                foreach ($mpl_artists_ids as $id) {
                    if (self::where('id', $id->user_id)->count() > 0) {
                        $mpl_artist_ids[] = $id->user_id;
                    }
                }

                $mpl_artists = self::whereIn('id', $mpl_artist_ids)->get();

                $mpl_artists_unsubscribed_ids = DB::table('user_genres')
                    ->select('user_genres.user_id')
                    ->join('users', 'users.id', '=', 'user_genres.user_id')
                    ->where('users.artist_subscribed', 0)
                    ->whereNotIn('user_genres.user_id', $existing_connections)
                    ->whereNotIn('user_genres.user_id', $ignored_checkout_artists)
                    ->where('users.type_id', 2)
                    ->take(20)
                    ->get();

                $mpl_artist_unsubscribed_ids = [];

                foreach ($mpl_artists_unsubscribed_ids as $id) {
                    if (self::where('id', $id->user_id)->count() > 0) {
                        $mpl_artist_unsubscribed_ids[] = $id->user_id;
                    }
                }

                $mpl_artists_unsubscribed = self::whereIn('id', $mpl_artist_unsubscribed_ids)->get();
            }

            //Shuffle both subscribed and unsubscribed artists seperatley
            $mpl_artists = $mpl_artists->shuffle();
            $mpl_artists_unsubscribed = $mpl_artists_unsubscribed->shuffle();

            //Append unsubscribed artists to subscribed artists
            $mpl_artists = $mpl_artists->toBase()->merge($mpl_artists_unsubscribed);

            $i = 0;
            $j = 0;

            //loop through artist recommended connections
            foreach ($band_ids as $checkout) {
                $i++;

                if ($i == 1) {
                    //If it is the first item in the carousel
                    if (isset($mpl_artists[$j])) {
                        //Add the next suggested connection from the list of mpl_recommended artists - then remove from our collection of all mpl recommended artists.
                        $connections[] =
                            [
                                'recommendee' => $mpl_artists[$j],
                                'recommender' => 'Music Planet Live',
                                'timestamp'   => '-',
                                'type'        => 'mpl',
                            ];

                        $mpl_artists->forget($j);

                        $j++;
                    }
                }

                if ($i == $mpl_artist_spacing) {
                    $i = 0;
                }

                //If it is NOT the first item in the carousel
                //Add suggested connection from list of artist recommended connections
                $connections[] =
                    [
                        'recommendee' => self::findOrFail($checkout['recommendee']),
                        'recommender' => self::findOrFail($checkout['recommender']),
                        'timestamp'   => $checkout['timestamp'],
                        'type'        => 'standard',
                    ];
            }

            //When we've run out of artist recommended connections
            //Add the rest of the MPL Recommended connections to the list of suggested connections
            if (isset($mpl_artists) && ! empty($connections)) {
                foreach ($mpl_artists as $g_artist) {
                    $connections[] =
                        [
                            'recommendee' => $g_artist,
                            'recommender' => 'Music Planet Live',
                            'timestamp'   => '-',
                            'type'        => 'mpl',
                        ];
                }
            }

            //If there are no artist recommended connections for a user then just return the list of MPL Recommended artists
            if (empty($connections)) {
                foreach ($mpl_artists as $temp_artist) {
                    $connections[] =
                        [
                            'recommendee' => $temp_artist,
                            'recommender' => 'Music Planet Live',
                            'timestamp'   => '-',
                            'type'        => 'mpl',
                        ];
                }

                foreach ($mpl_artists_unsubscribed as $temp_artist) {
                    $connections[] =
                        [
                            'recommendee' => $temp_artist,
                            'recommender' => 'Music Planet Live',
                            'timestamp'   => '-',
                            'type'        => 'mpl',
                        ];
                }
            }

            $connections = array_slice($connections, 0, 32);

            return $connections;
        });
    }

    public function bandsSeen()
    {
        return $this->getConnections('artist', 'SeenLive');
    }

    public function fans($includeSentRequests = true)
    {
        if ($this->type_id == 3 && ! $includeSentRequests) {
            return $this->getConnections('fan', '', 1);
        } else {
            return $this->getConnections('fan');
        }
    }

    public function friends()
    {
        return $this->getConnections('fan', '', 1);
    }

    public function friendRequests()
    {
        return $this->getConnections('fan', '', 0);
    }

    public function venues()
    {
        return $this->getConnections('venue');
    }

    public function promoters()
    {
        return $this->getConnections('promoter');
    }

    public function isSubscribedArtist()
    {
        if ($this->isBand() && $this->artist_subscribed == 1) {
            return true;
        }

        return false;
    }

    public function removeArtistSubscription()
    {
        $thread = MessageThread::where('teamer_artist_id', $this->id)->first();
        if (isset($thread) && $thread != null) {
            $thread->remove();
        }

        $this->artist_subscribed = 0;
        $this->save();

        return true;
    }

    public function addArtistSubscription()
    {
        if ($this->affiliate_token == '') {
            $this->affiliate_token = Str::random(16);
        }

        $this->artist_subscribed = 1;
        $this->save();

        return true;
    }

    public function isArtist()
    {
        return $this->isBand();
    }

    public function isBand()
    {
        if ($this->type_id == 2) {
            return true;
        }

        return false;
    }

    public function isVenue()
    {
        if ($this->type_id == 1) {
            return true;
        }

        return false;
    }

    public function isFan()
    {
        if ($this->type_id == 3) {
            return true;
        }

        return false;
    }

    public function isPromoter()
    {
        if ($this->type_id == 4) {
            return true;
        }

        return false;
    }

    public function isAdmin()
    {
        if ($this->type_id == 5) {
            return true;
        }

        return false;
    }

    public function genreIds()
    {
        return $this
            ->genres()
            ->pluck('id')
            ->toArray();
    }

    public static function signIn(Request $request)
    {
        if (Auth::attempt(['email' => $request->email, 'password' => $request->password,'type_id' => 3], $request->remember)) {
            return true;
        }

        return false;
    }

    public function challenges($date = null)
    {
        if ($date != null) {
            return $this->enquiries()->get()->where('challenge', 1)->where('enquiry_at', '>=', $date->format('Y-m-d').' 00:00:00')->where('enquiry_at', '<=', $date->format('Y-m-d').' 23:59:59');
        } else {
            return $this->enquiries()->get()->where('challenge', 1);
        }
    }

    public function pencils($date = null)
    {
        if ($date != null) {
            return $this->enquiries(true)
                ->where('pencilled', 1)
                ->where('enquiry_at', '>=', $date->format('Y-m-d').' 00:00:00')
                ->where('enquiry_at', '<=', $date->format('Y-m-d').' 23:59:59')
                ->get();
        } else {
            return $this->enquiries(true)
                ->where('pencilled', 1)
                ->get();
        }
    }

    public function hasChallenge($date)
    {
        if ($this->enquiries()->get()->where('challenge', 1)->where('closed', '!=', 1)->where('enquiry_at', '>=', $date->format('Y-m-d').' 00:00:00')->where('enquiry_at', '<=', $date->format('Y-m-d').' 23:59:59')->count() > 0) {
            return true;
        }

        return false;
    }

    public function hasPencil($date)
    {
        return $this->enquiries(true)->where('pencilled', 1)->where('enquiry_at', '>=',
            $date->format('Y-m-d') . ' 00:00:00')->where('enquiry_at', '<=',
            $date->format('Y-m-d') . ' 23:59:59')->count();
    }

    public function hasConfirmedPencil($date)
    {
        return $this
            ->enquiries(true)
            ->get()
            ->where('pencilled', 1)
            ->where('enquiry_at', '>=', $date->format('Y-m-d').' 00:00:00')
            ->where('enquiry_at', '<=', $date->format('Y-m-d').' 23:59:59')
            ->where('confirmed', 1)
            ->count();
    }

    public function hasEvent($date)
    {
        return $this
            ->events(true)
            ->where('event_at', '>=', $date->format('Y-m-d') . ' 00:00:00')
            ->where('event_at', '<=', $date->format('Y-m-d') . ' 23:59:59')
            ->exists();
    }

    public static function addNew($data, $type)
    {
        $user = new self;

        foreach ($data->except([
            '_token',
            'g-recaptcha-response',
            'password',
            'confirm_password',
            'genre_id',
            'genres',
            'genre',
            'country',
            'location',
            'return_url',
            'raw',
            'app',
            'checked_genres',
        ]) as $field => $value) {
            $user->{$field} = $value;
        }


        $user->contact_email = $user->email;

        $ipaddress = '';

        if (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } elseif (isset($_SERVER['HTTP_X_FORWARDED'])) {
            $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
        } elseif (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
            $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
        } elseif (isset($_SERVER['HTTP_FORWARDED'])) {
            $ipaddress = $_SERVER['HTTP_FORWARDED'];
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ipaddress = $_SERVER['REMOTE_ADDR'];
        } else {
            $ipaddress = 'UNKNOWN';
        }

        $user->ip = $ipaddress;

        if (Session::has('affiliate_token')) {
            if (self::where('affiliate_token', session('affiliate_token'))->count() > 0) {
                $referer = self::where('affiliate_token', session('affiliate_token'))->first();
                if ($referer->isSubscribedArtist()) {
                    $user->referer_id = $referer->id;
                }
            }
        }

        $user->save();
        $user->setType($type);
        $user->setPassword($data->password);
        $user->generateCleanURL();

        if (isset($data->app) && $data->app == 'social') {
            $genres = '';
            $i = 0;
            foreach (json_decode($data->checked_genres) as $g) {
                if ($g->checked == true) {
                    if ($i == 0) {
                        $genres .= $g->id;
                    } else {
                        $genres .= ', '.$g->id;
                    }

                    $i++;
                }
            }
          //  $user->sendFanWelcomeEmail();
            $user->approve();
            $user->setGenres(explode(',', $genres));
        } else {
            if ($type == 1) {
                $user->setCountryId($data->country);
               // $user->sendVenueWelcomeEmail();
                $user->setGenres(explode(',', $data->genres));
            } elseif ($type == 2) {
                $user->setCountryId($data->country);
                //$user->sendBandWelcomeEmail();
                $user->approve();
                $user->setGenres(json_decode($data->genre_id));
            } elseif ($type == 3) {
                $user->contact_name = $user->first_name.' '.$user->last_name;
              //  $user->sendFanWelcomeEmail();
                $user->setCountryId($data->country);
                $user->approve();
                $user->setGenres(explode(',', $data->genres));
            } elseif ($type == 4) {
                $user->setCountryId($data->country);
              //  $user->sendPromoterWelcomeEmail();
                $user->approve();
                $user->setGenres(explode(',', $data->genres));
            }
        }

        return $user;
    }

    public function setCountryId($country)
    {
        if (is_int($country)) {
            $country_id = $country;
        } else {
            if (Country::where('name', $country)->count() > 0) {
                $country = Country::where('name', $country)->first();
                $country_id = $country->id;
            } else {
                $country_id = '0';
            }
        }

        $this->country_id = $country_id;
        $this->save();
    }

    public function approve()
    {
        if ($this->isVenue()) {
            event(new VenueMarkedAsApproved($this));
        }

        $this->approved = 1;
        $this->save();
    }

    public function unapprove()
    {
        $this->approved = 0;
        $this->save();
    }

    public function setGenres($genre_ids)
    {
        if (is_array($genre_ids)) {
            DB::table('user_genres')->where('user_id', $this->id)->delete();
            foreach ($genre_ids as $genre_id) {
                if ($genre_id) {
                    $query = DB::table('user_genres')->insert([
                        'user_id'  => $this->id,
                        'genre_id' => $genre_id,
                    ]);
                }
            }
        }
    }

    public function removeArtistVenueLinks()
    {
        DB::table('artist_venue_connections')->where('artist_id', $this->id)->delete();
    }

    public function removePromoterVenueLinks()
    {
        DB::table('promoter_venue_connections')->where('promoter_id', $this->id)->delete();
    }

    public function edit($data)
    {
        if ($this->type->id == 2) {
            if (isset($data['lat']) && isset($data['lng']) && ($this->lat != $data['lat'] || $this->lng != $data['lng'])) {
                $this->removeArtistVenueLinks();
            }
        }

        if ($this->isPromoter()) {
            if (isset($data['lat']) && isset($data['lng']) && ($this->lat != $data['lat'] || $this->lng != $data['lng'])) {
                $this->removePromoterVenueLinks();
            }
        }

        if (isset($data['address_1']) && $data['address_1'] != '' && ($data['address_1'] != $this->address_1)) {
            $country = Country::findOrFail($data['country_id']);

            $query = urlencode($data['address_1'].', '.$data['address_2'].', '.$data['city'].', '.$data['county'].', '.$data['postcode'].', '.$country['name']);
            $endpoint = 'http://api.opencagedata.com/geocode/v1/json?q='.$query.'&key='.config('services.opencagedata.api_key');

            $ch = curl_init($endpoint);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

            $response = curl_exec($ch);
            curl_close($ch);

            $responseData = json_decode($response);

            if (isset($responseData->results[0]) && $responseData->status->code == 200) {
                $data['lat'] = $responseData->results[0]->geometry->lat;
                $data['lng'] = $responseData->results[0]->geometry->lng;
            } else {
                $errors = new MessageBag();
                $errors->add(1, "We weren't able to find the selected location - please try again.");

                return redirect()->back()->with('errors', $errors);
            }
        }

        if ($this->type->id == 2 || $this->isPromoter() || $this->isFan()) {
            if (isset($data['country'])) {
                if (Country::where('name', $data['country'])->count() > 0) {
                    $country = Country::where('name', $data['country'])->first();

                    $data['country_id'] = $country->id;
                }
            }

            if (isset($data['genres'])) {
                $this->setGenres(explode(':', $data['genres']));
            }
        }

        $data = Arr::except($data, [
            'venue_id', 'fan_id', 'artist_id', 'bio', 'age_restriction', 'gigs', 'venue_hire', 'facilities', 'additional_info', 'country', 'location', 'genres', 'genre',
        ]);

        foreach ($data as $key => $value) {
            $this->{$key} = $value;
        }

        $this->save();
    }

    public function heroImageSrc()
    {
        return $this->heroImage()->full_url;
    }

    public function setType($type)
    {
        if (UserType::findOrFail($type)) {
            $this->type_id = $type;
            $this->save();
        } else {
            die('An error has occured.');
        }
    }

    public function setPassword($password)
    {
        $this->password = Hash::make($password);
        $this->save();
    }

    public function profileImage()
    {
        if ($this->type_id == 1) {
            return $this->image(1);
        } elseif ($this->type_id == 2) {
            return $this->image(3);
        } elseif ($this->type_id == 3) {
            return $this->image(10);
        } elseif ($this->type_id == 4) {
            return $this->image(12);
        } elseif ($this->type_id == 5) {
            return $this->image(16);
        }
    }

    public function profileImageSrc()
    {
        return $this->profileImage()->full_url;
    }

    public function heroImage()
    {
        if ($this->type->id == 1) {
            return $this->image(2);
        } elseif ($this->type->id == 2) {
            return $this->image(4);
        } elseif ($this->type->id == 3) {
            return $this->image(11);
        } elseif ($this->type->id == 4) {
            return $this->image(13);
        }
    }

    public function image($image_type_id = 0)
    {
        $image = $this->images()->where('type_id', $image_type_id)->first();

        if (!$image) {
            $image = new Image;
            $image->src = ImageType::findOrFail($image_type_id)->default_image;
        }

        return $image;
    }

    public function location()
    {
        $location = '';

        if ($this->city) {
            $location .= $this->city.', ';
        }

        if ($this->country) {
            $location .= $this->country->short_name;
        }

        return $location;
    }

    public function address($line_break = true)
    {
        $address = '';
        if ($this->address_1) : $address .= $this->address_1.($line_break ? ',<br>' : ', ');
        endif;
        if ($this->address_2) : $address .= $this->address_2.($line_break ? ',<br>' : ', ');
        endif;
        if ($this->city) : $address .= $this->city.($line_break ? ',<br>' : ', ');
        endif;
        if ($this->county) : $address .= $this->county.($line_break ? ',<br>' : ', ');
        endif;
        if ($this->postcode) : $address .= $this->postcode;
        endif;

        return $address;
    }

    public function updateVenueInfo(array $data)
    {
        $fields = [
            'bio', 'age_restriction', 'gigs', 'venue_hire', 'facilities', 'additional_info',
        ];

        foreach ($data as $key => $value) {
            if (in_array($key, $fields)) {
                $this->updateVenueInfoByKey($key, $value);
            }
        }
    }

    public function updateVenueInfoByKey($key, $value)
    {
        if (DB::table('venue_info')->where('venue_id', $this->id)->where('field_name', $key)->count() > 0) {
            DB::table('venue_info')
            ->where('field_name', $key)
            ->where('venue_id', $this->id)
            ->update([
                'value' => $value,
            ]);
        } else {
            DB::table('venue_info')->insert([
                'venue_id'   => $this->id,
                'field_name' => $key,
                'value'      => $value,
            ]);
        }
    }

    public function venueInfo($key, $nl2br = true, $html = true)
    {
        if (VenueInfo::where('field_name', $key)->where('venue_id', $this->id)->count() > 0) {
            $value = VenueInfo::where('field_name', $key)->where('venue_id', $this->id)->first()->value;
            $full_value = VenueInfo::where('field_name', $key)->where('venue_id', $this->id)->first()->value;

            if (strlen($value) > 200) {
                if ($html) {
                    $value = '<div class="truncated-info">'.substr(strip_tags($value), 0, 200).'...</div>';
                    $value .= '<div class="btn primary read-more-btn" onclick="openBasicDialog(\''.str_replace('_', ' ', ucwords($key)).'\', \''.htmlspecialchars($full_value).'\')">More Info</div>';
                } else {
                    $value = strip_tags($value);
                }
            }

            if ($nl2br) {
                return preg_replace('/(\r\n|\n|\r)/', '<br>', $value);
            } else {
                return $value;
            }
        }
    }

    public function specificationPdf()
    {
        return $this->file(1);
    }

    public function seatingPlanPdf()
    {
        return $this->file(2);
    }

    public function file($file_type_id = 0)
    {
        if ($this->files()->where('type_id', $file_type_id)->count() > 0) {
            return $this->files()->where('type_id', $file_type_id)->first();
        } else {
            $file = new File;
            $file->src = '';

            return $file;
        }
    }

    public function uploadHeroBanner($image)
    {
        $filename = $this->id.'-'.time().'-hero.'.$image->getClientOriginalExtension();

        if ($this->type->id == 1) {
            $web_location = 'venue/'.$filename;
        } elseif ($this->type->id == 2) {
            $web_location = 'artist/'.$filename;
        } elseif ($this->type->id == 3) {
            $web_location = 'member/'.$filename;
        } elseif ($this->type->id == 4) {
            $web_location = 'promoter/'.$filename;
        }

        $processed_image = ImageLibrary::make($image->getRealPath());

        $processed_image->resize(1920, 626, function ($constraint) {
            $constraint->aspectRatio();
            $constraint->upsize();
        });

        $save = $processed_image->save();

        Storage::disk('s3')->put($web_location, $save->__toString());

        if ($this->type->id == 1) {
            $this->deleteImage(2);
            $this->setImage(2, $web_location);
        } elseif ($this->type->id == 2) {
            $this->deleteImage(4);
            $this->setImage(4, $web_location);
        } elseif ($this->type->id == 3) {
            $this->deleteImage(11);
            $this->setImage(11, $web_location);
        } elseif ($this->type->id == 4) {
            $this->deleteImage(13);
            $this->setImage(13, $web_location);
        }
    }

    public function uploadProfileImage($image)
    {
        $filename = $this->id.'-'.time().'-profile.'.$image->getClientOriginalExtension();

        if ($this->type->id == 1) {
            $web_location = 'venue/'.$filename;
        } elseif ($this->type->id == 2) {
            $web_location = 'artist/'.$filename;
        } elseif ($this->type->id == 3) {
            $web_location = 'member/'.$filename;
        } elseif ($this->type->id == 4) {
            $web_location = 'promoter/'.$filename;
        }

        $processed_image = ImageLibrary::make($image->getRealPath());

        $processed_image->resize(254, 254, function ($constraint) {
            $constraint->aspectRatio();
            $constraint->upsize();
        });

        $save = $processed_image->save();

        Storage::disk('s3')->put($web_location, $save->__toString());

        if ($this->type->id == 1) {
            $this->deleteImage(1);
            $this->setImage(1, $web_location);
        } elseif ($this->type->id == 2) {
            $this->deleteImage(3);
            $this->setImage(3, $web_location);
        } elseif ($this->type->id == 3) {
            $this->deleteImage(10);
            $this->setImage(10, $web_location);
        } elseif ($this->type->id == 4) {
            $this->deleteImage(12);
            $this->setImage(12, $web_location);
        }
    }

    public function setImage($type_id, $location)
    {
        $image = new Image;
        $image->src = $location;
        $image->imageable_id = $this->id;
        $image->imageable_type = self::class;
        $image->type_id = $type_id;
        $image->save();
    }

    public function setFile($type_id, $location)
    {
        $image = new File;
        $image->src = $location;
        $image->fileable_id = $this->id;
        $image->fileable_type = self::class;
        $image->type_id = $type_id;
        $image->save();
    }

    public function uploadTechSpecPDF($pdf)
    {
        $filename = $this->id.'-'.time().'-tech-spec.'.$pdf->getClientOriginalExtension();

        $web_location = 'images/uploads/venue/'.$filename;
        $server_location = public_path('images/uploads/venue/');

        $pdf->move($server_location, $filename);
        $this->deleteFile(1);
        $this->setFile(1, $web_location);
    }

    public function uploadSeatingPlanPDF($pdf)
    {
        $filename = $this->id.'-'.time().'-seating-plan.'.$pdf->getClientOriginalExtension();

        $web_location = 'images/uploads/venue/'.$filename;
        $server_location = public_path('images/uploads/venue/');

        $pdf->move($server_location, $filename);
        $this->deleteFile(2);
        $this->setFile(2, $web_location);
    }

    public function deleteFile($type_id)
    {
        if ($this->files()->where('type_id', $type_id)->count() > 0) {
            $this->files()->where('type_id', $type_id)->first()->remove();
        }
    }

    public function deleteImage($type_id)
    {
        if ($this->images()->where('type_id', $type_id)->count() > 0) {
            foreach ($this->images()->where('type_id', $type_id)->get() as $image) {
                $image->remove();
            }
        }
    }

    public function getLongLat()
    {
        $query = urlencode($this->postcode.', '.$this->country->name);
        $endpoint = 'http://api.opencagedata.com/geocode/v1/json?q='.$query.'&key='.config('services.opencagedata.api_key');

        $ch = curl_init($endpoint);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        $response = curl_exec($ch);
        curl_close($ch);

        $data = json_decode($response);
        $final_data = [];

        foreach ($data->results as $item) {
            if ($item->components->country == $this->country->name) {
                $final_data[] = $item;
            }
        }

        if ($data->status->code == 200) {
            if (! isset($final_data[0])) {
                $this->lat = $data->results[0]->geometry->lat;
                $this->lng = $data->results[0]->geometry->lng;
            } else {
                $this->lat = $final_data[0]->geometry->lat;
                $this->lng = $final_data[0]->geometry->lng;
            }
            $this->save();
        }
    }

    public function getPasswordResetCode()
    {
        if ($this->password_reset_code == '') {
            $this->password_reset_code = Str::random(32);
            $this->save();
        }

        return $this->password_reset_code;
    }

    public function sendForgotPassword()
    {
        $user = $this;
        Mail::to($this->email)->send(new UserPasswordResetEmail($user));
    }

    public function sendVenueWelcomeEmail()
    {
        if ($this->type_id == 1) {
            $user = $this;
            Mail::to($this->email)->send(new VenueWelcomeEmail($user));
        }
    }

    public function sendBandWelcomeEmail()
    {
        if ($this->type_id == 2) {
            $user = $this;
            Mail::to($this->email)->send(new BandWelcomeEmail($user));
        }
    }

    public function sendFanWelcomeEmail()
    {
        if ($this->type_id == 3) {
            $user = $this;
            Mail::to($this->email)->send(new FanWelcomeEmail($user));
        }
    }

    public function sendPromoterWelcomeEmail()
    {
        if ($this->type_id == 4) {
            $user = $this;
            Mail::to($this->email)->send(new PromoterWelcomeEmail($user));
        }
    }

    public function cleanSocialLink($link)
    {
        $string = str_replace('http://', '', str_replace('https://', '', str_replace('www.', '', str_replace('.com', '', str_replace('.com/', '', str_replace('facebook', '', str_replace('twitter', '', str_replace('youtube', '', str_replace('pinterest', '', str_replace('linkedin', '', str_replace('/in/', '', str_replace('instagram', '', str_replace('tumblr', '', $link)))))))))))));

        if (substr($string, -1) == '/') {
            $string = substr($string, 0, -1);
        }

        return $string;
    }

    public function socialLink($type)
    {
        switch ($type) {
            case 'facebook':
                return 'http://www.facebook.com/'.$this->cleanSocialLink($this->facebook_link);
            break;

            case 'twitter':
                return 'http://www.twitter.com/'.$this->cleanSocialLink($this->twitter_link);
            break;

            case 'youtube':
                return 'http://www.youtube.com/'.$this->cleanSocialLink($this->youtube_link);
            break;

            case 'pinterest':
                return 'http://www.pinterest.com/'.$this->cleanSocialLink($this->pinterest_link);
            break;

            case 'linkedin':
                return 'http://www.linkedin.com/in/'.$this->cleanSocialLink($this->linkedin_link);
            break;

            case 'instagram':
                return 'http://www.instagram.com/'.$this->cleanSocialLink($this->instagram_link);
            break;

            case 'tumblr':
                return 'http://'.$this->cleanSocialLink($this->tumblr_link).'.tumblr.com';
            break;
        }
    }

    public function genreString()
    {
        if ($this->genres()->count() > 0) {
            $genres = [];

            foreach ($this->genres as $genre) {
                $genres[] = $genre->name;
            }

            return implode(', ', $genres);
        } else {
            return 'Not set';
        }
    }

    public function singleGenreString()
    {
        if ($this->genres()->count() > 0) {
            return $this->genres()->first()->name;
        } else {
            return 'Not set';
        }
    }

    public static function getSurroundingVenues(
        $location,
        $radius,
        $venue_types = [],
        $with_unclaimed = false,
        $mvt_only = false
    ) {
        $venue_type_where = '';

        if (count($venue_types) > 0) {
            $venue_type_where = ' (';
            $i = 0;
            foreach ($venue_types as $type_id) {
                $venue_type_where .= 'u.venue_type_id = '.$type_id;

                if (count($venue_types) - 1 != $i) {
                    $venue_type_where .= ' OR ';
                }

                $i++;
            }
            $venue_type_where .= ') ';
        }

        $venue_data = DB::select('SELECT
		id,
		COUNT(l.venue_id),
		(
		   3959 *
		   acos(cos(radians('.$location['lat'].')) *
		   cos(radians(u.lat)) *
		   cos(radians(u.lng) -
		   radians('.$location['lng'].')) +
		   sin(radians('.$location['lat'].')) *
		   sin(radians(u.lat)))
		) AS `distance`
		FROM users u
		LEFT JOIN artist_venue_connections l ON l.venue_id = u.id
        WHERE (
           3959 *
           acos(cos(radians('.$location['lat'].')) *
           cos(radians(u.lat)) *
           cos(radians(u.lng) -
           radians('.$location['lng'].')) +
           sin(radians('.$location['lat'].')) *
           sin(radians(u.lat)))
        ) <= '.$radius."
		AND u.type_id = 1
		AND u.lat != ''
		AND u.lng != ''
		AND u.approved = 1 ".
            ($with_unclaimed ? '' : ' AND venue_claimed = 1 ').
            ($mvt_only ? ' AND mvt_venue = 1 ' : '').
            ($venue_type_where ? ' AND '.$venue_type_where : '').
            ' GROUP BY u.id, u.lat, u.lng ORDER BY COUNT(l.venue_id) DESC, distance');

        $venue_ids = [];
        foreach ($venue_data as $data) {
            $venue_ids[] = $data->id;
        }
        $venues = self::whereIn('id', $venue_ids)->get();

        return $venues;
    }

    public function linkedToArtist($id)
    {
        return $this->isConnected(self::findOrFail($id), 'SeeLive');
    }

    public function seenArtist($id)
    {
        return $this->isConnected(self::findOrFail($id), 'SeenLive');
    }

    public function linkedToVenue($venue_id)
    {
        return $this->isConnected(self::findOrFail($venue_id));
    }

    public function linkedToFan($fan_id)
    {
        return $this->isConnected(self::findOrFail($fan_id), '', 1);
    }

    public function requestedLinkToFan($fan_id)
    {
        return $this->getConnections('fan', '', 0)->where('id', $fan_id)->count();
    }

    public function beingRequestedByFan($fan_id)
    {
        return $this->getConnections('fan', '', 0)->where('id', $fan_id)->count();
    }

    public function updatePassword($password)
    {
        $this->password = Hash::make($password);
        $this->save();
    }

    public function updateEmail($email)
    {
        $this->email = $email;
        $this->save();
    }

    public function removeResetPasswordToken()
    {
        $this->password_reset_code = '';
        $this->save();
    }

    public function remove()
    {
        if ($this->type_id == 1) {
            DB::table('artist_venue_connections')->where('venue_id', $this->id)->delete();
            DB::table('fan_venue_connections')->where('venue_id', $this->id)->delete();
            DB::table('venue_votes')->where('venue_id', $this->id)->delete();
            DB::table('venue_info')->where('venue_id', $this->id)->delete();
            DB::table('promoter_venue_connections')->where('venue_id', $this->id)->delete();
        } elseif ($this->type_id == 2) {
            DB::table('artist_venue_connections')->where('artist_id', $this->id)->delete();
            DB::table('artist_artist_connections')->where('artist1_id', $this->id)->delete();
            DB::table('artist_artist_connections')->where('artist2_id', $this->id)->delete();
            DB::table('artist_promoter_connections')->where('artist_id', $this->id)->delete();
            DB::table('promoter_artist_connections')->where('artist_id', $this->id)->delete();
            DB::table('fan_artist_follows')->where('artist_id', $this->id)->delete();
            DB::table('fan_artist_seen')->where('artist_id', $this->id)->delete();
            DB::table('event_artists')->where('artist_id', $this->id)->delete();
        } elseif ($this->type_id == 3) {
            DB::table('fan_artist_follows')->where('fan_id', $this->id)->delete();
            DB::table('fan_artist_seen')->where('fan_id', $this->id)->delete();
            DB::table('fan_venue_connections')->where('fan_id', $this->id)->delete();
            DB::table('fan_promoter_connections')->where('fan_id', $this->id)->delete();
        } elseif ($this->type_id == 4) {
            DB::table('fan_promoter_connections')->where('promoter_id', $this->id)->delete();
            DB::table('artist_promoter_connections')->where('promoter_id', $this->id)->delete();
            DB::table('promoter_artist_connections')->where('promoter_id', $this->id)->delete();
            DB::table('promoter_venue_connections')->where('promoter_id', $this->id)->delete();
        }

        if ($this->videos()->count() > 0) {
            foreach ($this->videos as $video) {
                $video->remove();
            }
        }

        if ($this->albums()->count() > 0) {
            foreach ($this->albums as $album) {
                $album->remove();
            }
        }

        if ($this->files()->count() > 0) {
            foreach ($this->files as $file) {
                $file->remove();
            }
        }

        if ($this->images()->count() > 0) {
            foreach ($this->images as $image) {
                $image->remove();
            }
        }

        if ($this->news()->count() > 0) {
            foreach ($this->news as $article) {
                $article->remove();
            }
        }

        if ($this->comments()->count() > 0) {
            foreach ($this->comments as $comment) {
                $comment->remove();
            }
        }

        if ($this->likes()->count() > 0) {
            foreach ($this->likes as $like) {
                $like->remove();
            }
        }

        if ($this->galleries()->count() > 0) {
            foreach ($this->galleries as $gallery) {
                $gallery->remove();
            }
        }

        DB::table('user_genres')->where('user_id', $this->id)->delete();
        DB::table('venue_votes')->where('user_id', $this->id)->delete();

        DB::table('users')->where('id', $this->id)->delete();
    }

    public function isCloseEnough(self $user, $distance = 50)
    {
        if ($user->lat == '' || $user->lng == '' || $this->lat == '' || $this->lng == '') {
            return false;
        }

        if (self::distance($user->lat, $user->lng, $this->lat, $this->lng) > $distance) {
            return false;
        }

        return true;
    }

    public function isNewsCloseEnough(News $news, $distance = 50)
    {
        if ($news->geo_lat == '' || $news->geo_lng == '' || $this->lat == '' || $this->lng == '') {
            return false;
        }

        if (self::distance($news->geo_lat, $news->geo_lng, $this->lat, $this->lng) > $distance) {
            return false;
        }

        return true;
    }

    public static function distance($lat1, $lon1, $lat2, $lon2)
    {
        $theta = $lon1 - $lon2;
        $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
        $dist = acos($dist);
        $dist = rad2deg($dist);
        $miles = $dist * 60 * 1.1515;

        return $miles;
    }

    public function getArtistBio()
    {
        if (strlen($this->artist_bio) > 300) {
            $bio = substr($this->artist_bio, 0, 300).'...';
            $bio = nl2br($bio);
            $bio .= '<br><br><div class="btn-row"><a href="javascript: void(0)" class="btn primary" onclick="openBasicDialog(\'Artist Biography\', \''.preg_replace('/(\r\n|\n|\r)/', '<br/>', addslashes(htmlspecialchars($this->artist_bio))).'\')">Read More</a></div>';
        } else {
            $bio = nl2br($this->artist_bio);
        }

        return $bio;
    }

    public function getTopSongs()
    {
        $songs = new Collection;

        foreach ($this->albums as $album) {
            foreach ($album->songs as $song) {
                $songs->push([
                    'id'    => $song->id,
                    'likes' => $song->likes()->count(),
                ]);
            }
        }

        $songs = $songs->sortByDesc('likes')->take(5);

        $songs_final = new Collection;

        foreach ($songs as $song) {
            $songs_final->push(Song::findOrFail($song['id']));
        }

        return $songs_final;
    }

    public function updateExternalLink($type, $value)
    {
        $this->{$type} = $value;
        $this->save();
    }

    public function getFansFollowedIds()
    {
        $fanArtistSeeLiveQuery = FanArtistSeeLiveConnection::where('fan_id', $this->id)
            ->pluck('artist_id')
            ->toArray();

        $fanArtistSeenLiveQuery = FanArtistSeenLiveConnection::where('fan_id', $this->id)
            ->pluck('artist_id')
            ->toArray();

        $fanVenueQuery = FanVenueConnection::where('fan_id', $this->id)
            ->pluck('venue_id')
            ->toArray();

        $fanPromoterQuery = FanPromoterConnection::where('fan_id', $this->id)
            ->pluck('promoter_id')
            ->toArray();

        $followedIds = collect($fanArtistSeeLiveQuery)
            ->merge($fanArtistSeenLiveQuery)
            ->merge($fanVenueQuery)
            ->merge($fanPromoterQuery)
            ->unique()
            ->values()
            ->toArray();

        return $followedIds;
    }

    public function getArtistFollowedIds()
    {
        $ids = [];

        foreach ($this->getConnections('artist', 'SeeLive') as $artist) {
            $ids[] = $artist->id;
        }

        foreach ($this->getConnections('artist', 'SeenLive') as $artist) {
            $ids[] = $artist->id;
        }

        foreach ($this->getConnections('promoter', 'SeenLive') as $promoter) {
            $ids[] = $promoter->id;
        }

        foreach ($this->getConnections('venue') as $venue) {
            $ids[] = $venue->id;
        }

        $ids = array_unique($ids);

        return $ids;
    }

    public function getFansFollowedArtistIds()
    {
        $ids = [];

        foreach ($this->getConnections('artist', 'SeeLive') as $artist) {
            $ids[] = $artist->id;
        }

        foreach ($this->getConnections('artist', 'SeenLive') as $artist) {
            $ids[] = $artist->id;
        }

        $ids = array_unique($ids);

        return $ids;
    }

    public function getPromoterFollowedIds()
    {
        $ids = [];

        foreach ($this->getConnections('artist', 'SeeLive') as $artist) {
            $ids[] = $artist->id;
        }

        foreach ($this->getConnections('venue') as $venue) {
            $ids[] = $venue->id;
        }

        $ids[] = $this->id;

        $ids = array_unique($ids);

        return $ids;
    }

    public function getFansFollowedArtistsCount()
    {
        return count($this->getFansFollowedArtistIds());
    }

    public function getFansFollowedVenues()
    {
        return $this->getConnections('venue');
    }

    public function setYouTubeChannelID($youtube_channel_id)
    {
        $this->youtube_channel_id = $youtube_channel_id;
        $this->save();
    }

    //List of fans who have seen this artist live
    public function seenLive()
    {
        $seen_by = DB::table('fan_artist_seen')->where('artist_id', $this->id)->pluck('fan_id');

        return $seen_by;
    }

    //List of fans who like to see this artist live
    public function likedToSeeLive()
    {
        $like_to = DB::table('fan_artist_follows')->where('artist_id', $this->id)->pluck('fan_id');

        return $like_to;
    }

    public function allFollowingFans()
    {
        $arr1 = $this->getConnections('fan', 'SeenLive');
        $arr2 = $this->getConnections('fan', 'SeeLive');

        $fans = $arr1->merge($arr2);

        return $fans->unique();
    }

    public function fanCount()
    {
        return $this->allFollowingFans()->count();
    }

    //For a fan... have they seen an artist
    public function hasSeenLive(self $artist)
    {
        return DB::table('fan_artist_seen')->where('fan_id', $this->id)->where('artist_id', $artist->id)->count();
    }

    public function shouldReceiveNotificationType($type_id)
    {
        if ($this->notification_preferences()->where('notification_type_id', $type_id)->count() > 0) {
            return $this->notification_preferences()->where('notification_type_id', $type_id)->first()->allow;
        } else {
            return NotificationType::findOrFail($type_id)->default_preference;
        }
    }

    public function addToFanFavourites($artist_id)
    {
        $follows = FanArtistFollows::where('fan_id', $this->id)->get();
        $seen = FanArtistSeen::where('fan_id', $this->id)->get();
        $favourite_count = 0;
        $all_records = new Collection;

        foreach ($follows as $follow) {
            $all_records->push($follow);
        }

        foreach ($seen as $s) {
            $all_records->push($s);
        }

        foreach ($all_records as $record) {
            if ($record->order > $favourite_count) {
                $favourite_count = $record->order;
            }
        }

        if ($favourite_count >= 5) {
            return 'You can only have up to 5 artists in your favourite artists';
        } else {
            if (FanArtistFollows::where('fan_id', $this->id)->where('artist_id', $artist_id)->first() && FanArtistSeen::where('fan_id', $this->id)->where('artist_id', $artist_id)->first()) {
                $favourite = FanArtistFollows::where('fan_id', $this->id)->where('artist_id', $artist_id)->first();
            } elseif (FanArtistFollows::where('fan_id', $this->id)->where('artist_id', $artist_id)->first()) {
                $favourite = FanArtistFollows::where('fan_id', $this->id)->where('artist_id', $artist_id)->first();
            } elseif (FanArtistSeen::where('fan_id', $this->id)->where('artist_id', $artist_id)->first()) {
                $favourite = FanArtistSeen::where('fan_id', $this->id)->where('artist_id', $artist_id)->first();
            }

            if ($favourite->order == 0) {
                $favourite->order = $favourite_count + 1;
                $favourite->save();

                return true;
            } else {
                return 'This artist is already in your favourites list';
            }
        }
    }

    public function checkIfFanFavourite($artist_id)
    {
        $follows = FanArtistFollows::where('fan_id', $this->id)->get();
        $seen = FanArtistSeen::where('fan_id', $this->id)->get();
        $favourite_count = 0;
        $all_records = new Collection;

        foreach ($follows as $follow) {
            $all_records->push($follow);
        }

        foreach ($seen as $s) {
            $all_records->push($s);
        }

        foreach ($all_records as $record) {
            if ($record->artist_id == $artist_id) {
                if ($record->order != 0) {
                    return true;
                }
            }
        }

        return false;
    }

    public function checkIfDreamLineupItem($artist_id)
    {
        $dream_artist = ArtistArtistConnection::where('artist1_id', $this->id)->where('artist2_id', $artist_id)->first();
        if ($dream_artist->order != 0) {
            return true;
        }

        return false;
    }

    public function addToDreamLineup($artist_id)
    {
        $connections = ArtistArtistConnection::where('artist1_id', $this->id)->get();
        $dream_count = 0;

        foreach ($connections as $connection) {
            if ($connection->order > $dream_count) {
                $dream_count = $connection->order;
            }
        }

        if ($dream_count >= 5) {
            return 'You can only have up to 5 artists in your dream lineup';
        } else {
            $dream_artist = ArtistArtistConnection::where('artist1_id', $this->id)->where('artist2_id', $artist_id)->first();
            if ($dream_artist->order == 0) {
                $dream_artist->order = $dream_count + 1;
                $dream_artist->save();

                return true;
            } else {
                return 'This artist is already in your dream lineup';
            }
        }
    }

    public function reorderDreamLineupItemUp($order, $type)
    {
        if ($type == 'artist') {
            $lineup = ArtistArtistConnection::where('artist1_id', $this->id)->where('order', '!=', 0)->get();

            foreach ($lineup as $item) {
                if ($item->order == $order) {
                    $item->order = $item->order - 1;
                    $item->save();
                } elseif ($item->order == ($order - 1)) {
                    $item->order = $order;
                    $item->save();
                }
            }
        } elseif ($type == 'fan') {
            if (FanArtistFollows::where('fan_id', $this->id)->where('order', '=', $order)->first()) {
                $current = FanArtistFollows::where('fan_id', $this->id)->where('order', '=', $order)->first();
            } else {
                $current = FanArtistSeen::where('fan_id', $this->id)->where('order', '=', $order)->first();
            }

            if (FanArtistFollows::where('fan_id', $this->id)->where('order', '=', $order - 1)->first()) {
                $next = FanArtistFollows::where('fan_id', $this->id)->where('order', '=', $order - 1)->first();
            } else {
                $next = FanArtistSeen::where('fan_id', $this->id)->where('order', '=', $order - 1)->first();
            }

            $current->order = $order - 1;
            $next->order = $order;
            $current->save();
            $next->save();
        }
    }

    public function reorderDreamLineupItemDown($order, $type)
    {
        if ($type == 'artist') {
            $lineup = ArtistArtistConnection::where('artist1_id', $this->id)->where('order', '!=', 0)->get();

            foreach ($lineup as $item) {
                if ($item->order == $order) {
                    $item->order = $item->order + 1;
                    $item->save();
                } elseif ($item->order == ($order + 1)) {
                    $item->order = $order;
                    $item->save();
                }
            }
        } elseif ($type == 'fan') {
            if (FanArtistFollows::where('fan_id', $this->id)->where('order', '=', $order)->first()) {
                $current = FanArtistFollows::where('fan_id', $this->id)->where('order', '=', $order)->first();
            } else {
                $current = FanArtistSeen::where('fan_id', $this->id)->where('order', '=', $order)->first();
            }

            if (FanArtistFollows::where('fan_id', $this->id)->where('order', '=', $order + 1)->first()) {
                $next = FanArtistFollows::where('fan_id', $this->id)->where('order', '=', $order + 1)->first();
            } else {
                $next = FanArtistSeen::where('fan_id', $this->id)->where('order', '=', $order + 1)->first();
            }

            $current->order = $order + 1;
            $next->order = $order;
            $current->save();
            $next->save();
        }
    }

    public function removeDreamLineupItem($type, $order)
    {
        if ($type == 'artist') {
            $lineup = ArtistArtistConnection::where('artist1_id', $this->id)->where('order', '!=', 0)->get();

            foreach ($lineup as $item) {
                if ($item->order == $order) {
                    $item->order = 0;
                    $item->save();
                } elseif ($item->order >= $order + 1) {
                    $item->order = $item->order - 1;
                    $item->save();
                }
            }
        } elseif ($type == 'fan') {
            if (FanArtistFollows::where('fan_id', $this->id)->where('order', $order)->first() && FanArtistSeen::where('fan_id', $this->id)->where('order', $order)->first()) {
                $favourite = FanArtistFollows::where('fan_id', $this->id)->where('order', $order)->first();
            } elseif (FanArtistFollows::where('fan_id', $this->id)->where('order', $order)->first()) {
                $favourite = FanArtistFollows::where('fan_id', $this->id)->where('order', $order)->first();
            } elseif (FanArtistSeen::where('fan_id', $this->id)->where('order', $order)->first()) {
                $favourite = FanArtistSeen::where('fan_id', $this->id)->where('order', $order)->first();
            }

            $higher_follows = FanArtistFollows::where('fan_id', $this->id)->where('order', '>', $order)->get();
            $higher_seen = FanArtistSeen::where('fan_id', $this->id)->where('order', '>', $order)->get();

            if ($higher_follows->count() > 0) {
                foreach ($higher_follows as $follow) {
                    $follow->order = $follow->order - 1;
                    $follow->save();
                }
            }

            if ($higher_seen->count() > 0) {
                foreach ($higher_seen as $follow) {
                    $follow->order = $follow->order - 1;
                    $follow->save();
                }
            }

            $favourite->order = 0;
            $favourite->save();
        }
    }

    public function addNotification($type_id, $content, $data)
    {
        if ($this->shouldReceiveNotificationType($type_id)) {
            $notification = Notification::addNew([
                'type_id' => $type_id,
                'content' => $content,
                'user_id' => $this->id,
            ]);

            $notification->addData($data);

            return $notification;
        } else {
            return false;
        }
    }

    public function removeNotification($type_id, $data)
    {
        foreach ($this->notifications()->where('type_id', $type_id)->get() as $notification) {
            $match = true;

            foreach ($data as $key => $value) {
                if ($notification->getData($key) != $value) {
                    $match = false;
                }
            }

            if ($match) {
                $notification->remove();
            }
        }
    }

    public function isRequesteeOfFriendship($user)
    {
        if (FanFanConnection::where([
            'fan_id1' => $user->id,
            'fan_id2' => $this->id,
            'approved' => 0,
        ])->count() > 0) {
            return true;
        }

        return false;
    }

    public function addConnection(self $connectee, $type = 'SeeLive')
    {
        if (! $this->isConnected($connectee, $type)) {
            switch ($this->type_id) {
                //Venue
                case 1:

                    //Venue
                    //Venue cannot connect to a Venue

                    //Artist
                    if ($connectee->type_id == 2) {
                        ArtistVenueConnection::addNew([
                            'venue_id'  => $this->id,
                            'artist_id' => $connectee->id,
                        ]);
                    }

                    //Fan
                    if ($connectee->type_id == 3) {
                        FanVenueConnection::addNew([
                            'venue_id'  => $this->id,
                            'artist_id' => $connectee->id,
                        ]);
                    }

                    //Promoter
                    if ($connectee->type_id == 4) {
                        PromoterVenueConnection::addNew([
                            'venue_id'    => $this->id,
                            'promoter_id' => $connectee->id,
                        ]);
                    }

                break;

                //Artist
                case 2:

                    //Venue
                    if ($connectee->type_id == 1) {
                        ArtistVenueConnection::addNew([
                            'artist_id' => $this->id,
                            'venue_id'  => $connectee->id,
                        ]);
                    }

                    //Artist
                    if ($connectee->type_id == 2) {
                        ArtistArtistConnection::addNew([
                            'artist1_id' => $this->id,
                            'artist2_id' => $connectee->id,
                        ]);

                        event(new ArtistRecommendsArtist($this, $connectee));
                    }

                    //Fan
                    if ($connectee->type_id == 3) {
                        if ($type == 'SeeLive') {
                            FanArtistSeeLiveConnection::addNew([
                                'artist_id' => $this->id,
                                'fan_id'    => $connectee->id,
                            ]);
                        } elseif ($type == 'SeenLive') {
                            FanArtistSeenLiveConnection::addNew([
                                'artist_id' => $this->id,
                                'fan_id'    => $connectee->id,
                            ]);
                        }
                    }

                    //Promoter
                    if ($connectee->type_id == 4) {
                        ArtistPromoterConnection::addNew([
                            'artist_id'   => $this->id,
                            'promoter_id' => $connectee->id,
                        ]);
                    }

                break;

                //Fan
                case 3:

                    //Venue
                    if ($connectee->type_id == 1) {
                        FanVenueConnection::addNew([
                            'fan_id'   => $this->id,
                            'venue_id' => $connectee->id,
                        ]);
                    }

                    //Artist
                    if ($connectee->type_id == 2) {
                        if ($type == 'SeeLive') {
                            FanArtistSeeLiveConnection::addNew([
                                'fan_id'    => $this->id,
                                'artist_id' => $connectee->id,
                            ]);

                            event(new FanMarksArtistAsLikeToSeeLive($this, $connectee));
                        } elseif ($type == 'SeenLive') {
                            FanArtistSeenLiveConnection::addNew([
                                'fan_id'    => $this->id,
                                'artist_id' => $connectee->id,
                            ]);

                            event(new FanMarksArtistAsSeenLive($this, $connectee));
                        } elseif ($type == 'Team') {
                            FanArtistTeamConnection::addNew([
                                'fan_id'    => $this->id,
                                'artist_id' => $connectee->id,
                            ]);

                            $add_artist = false;

                            if (! MessageThread::teamerThreadExists($connectee->id)) {
                                MessageThread::addNew(0, $connectee->id);
                                $add_artist = true;
                            }
                            $thread = MessageThread::where('teamer_artist_id', $connectee->id)->first();

                            if ($add_artist == true) {
                                $thread->addParticipant($connectee);
                            }
                            $thread->addParticipant(Auth::user());
                        }
                    }

                    //Fan
                    if ($connectee->type_id == 3) {
                        FanFanConnection::addNew([
                            'fan_id1' => $this->id,
                            'fan_id2' => $connectee->id,
                        ]);

                        event(new FanFriendRequestsFan($this, $connectee));
                    }

                    //Promoter
                    if ($connectee->type_id == 4) {
                        FanPromoterConnection::addNew([
                            'fan_id'      => $this->id,
                            'promoter_id' => $connectee->id,
                        ]);
                    }

                break;

                //Promoter
                case 4:

                    //Venue
                    if ($connectee->type_id == 1) {
                        PromoterVenueConnection::addNew([
                            'promoter_id' => $this->id,
                            'venue_id'    => $connectee->id,
                        ]);
                    }

                    //Artist
                    if ($connectee->type_id == 2) {
                        PromoterArtistConnection::addNew([
                            'promoter_id' => $this->id,
                            'artist_id'   => $connectee->id,
                        ]);
                    }

                    //Fan
                    //Promoter cannot connect to a fan

                    //Promoter
                    //Promoter cannot connect to a promoter

                break;
            }
        }
    }

    public function updateConnection(self $connectee, $data = [])
    {
        if ($this->isConnected($connectee)) {
            switch ($this->type_id) {
                //Fan
                case 3:

                    //Fan
                    if ($connectee->type_id == 3) {
                        if (FanFanConnection::where([
                            'fan_id1' => $this->id,
                            'fan_id2' => $connectee->id,
                        ])->count() > 0) {
                            FanFanConnection::where([
                                'fan_id1' => $this->id,
                                'fan_id2' => $connectee->id,
                            ])->update($data);
                        }

                        if (FanFanConnection::where([
                            'fan_id1' => $connectee->id,
                            'fan_id2' => $this->id,
                        ])->count() > 0) {
                            FanFanConnection::where([
                                'fan_id1' => $connectee->id,
                                'fan_id2' => $this->id,
                            ])->update($data);
                        }

                        event(new FanAcceptsFriendRequest($this, $connectee));
                    }

                break;
            }
        }
    }

    public function deleteConnection(self $connectee, $type = 'SeenLive')
    {
        if ($this->isConnected($connectee, $type)) {
            switch ($this->type_id) {
                //Venue
                case 1:

                    //Venue
                    //Venue cannot connect to a Venue

                    //Artist
                    if ($connectee->type_id == 2) {
                        ArtistVenueConnection::where([
                            'venue_id'  => $this->id,
                            'artist_id' => $connectee->id,
                        ])->delete();
                    }

                    //Fan
                    if ($connectee->type_id == 3) {
                        FanVenueConnection::where([
                            'venue_id'  => $this->id,
                            'artist_id' => $connectee->id,
                        ])->delete();
                    }

                    //Promoter
                    if ($connectee->type_id == 4) {
                        PromoterVenueConnection::where([
                            'venue_id'    => $this->id,
                            'promoter_id' => $connectee->id,
                        ])->delete();
                    }

                break;

                //Artist
                case 2:

                    //Venue
                    if ($connectee->type_id == 1) {
                        ArtistVenueConnection::where([
                            'artist_id' => $this->id,
                            'venue_id'  => $connectee->id,
                        ])->delete();
                    }

                    //Artist
                    if ($connectee->type_id == 2) {
                        ArtistArtistConnection::where([
                            'artist1_id' => $this->id,
                            'artist2_id' => $connectee->id,
                        ])->delete();

                        $recommender = $this;
                        $recommendee = $connectee;

                        event(new ArtistUnrecommendsArtist($recommender, $recommendee));
                    }

                    //Fan
                    if ($connectee->type_id == 3) {
                        if ($type == 'SeeLive') {
                            FanArtistSeeLiveConnection::where([
                                'artist_id' => $this->id,
                                'fan_id'    => $connectee->id,
                            ])->delete();
                        } elseif ($type == 'SeenLive') {
                            FanArtistSeenLiveConnection::where([
                                'artist_id' => $this->id,
                                'fan_id'    => $connectee->id,
                            ])->delete();

                            event(new FanUnmarksArtistAsSeenLive($this, $connectee));
                        }
                    }

                    //Promoter
                    if ($connectee->type_id == 4) {
                        ArtistPromoterConnection::where([
                            'artist_id'   => $this->id,
                            'promoter_id' => $connectee->id,
                        ])->delete();
                    }

                break;

                //Fan
                case 3:

                    //Venue
                    if ($connectee->type_id == 1) {
                        FanVenueConnection::where([
                            'fan_id'   => $this->id,
                            'venue_id' => $connectee->id,
                        ])->delete();
                    }

                    //Artist
                    if ($connectee->type_id == 2) {
                        if ($type == 'SeeLive') {
                            FanArtistSeeLiveConnection::where([
                                'fan_id'    => $this->id,
                                'artist_id' => $connectee->id,
                            ])->delete();
                        } elseif ($type == 'SeenLive') {
                            FanArtistSeenLiveConnection::where([
                                'fan_id'    => $this->id,
                                'artist_id' => $connectee->id,
                            ])->delete();
                        } elseif ($type == 'Team') {
                            FanArtistTeamConnection::where([
                                'fan_id'    => $this->id,
                                'artist_id' => $connectee->id,
                            ])->delete();

                            $thread = MessageThread::where('teamer_artist_id', $connectee->id)->first();
                            $thread->removeParticipant(Auth::user());
                        }
                    }

                    //Fan
                    if ($connectee->type_id == 3) {
                        FanFanConnection::where([
                            'fan_id1' => $connectee->id,
                            'fan_id2' => $this->id,
                        ])->delete();

                        FanFanConnection::where([
                            'fan_id1' => $this->id,
                            'fan_id2' => $connectee->id,
                        ])->delete();

                        event(new FanUnfriendRequestsFan($this, $connectee));
                    }

                    //Promoter
                    if ($connectee->type_id == 4) {
                        FanPromoterConnection::where([
                            'fan_id'      => $this->id,
                            'promoter_id' => $connectee->id,
                        ])->delete();
                    }

                break;

                //Promoter
                case 4:

                    //Venue
                    if ($connectee->type_id == 1) {
                        PromoterVenueConnection::where([
                            'promoter_id' => $this->id,
                            'venue_id'    => $connectee->id,
                        ])->delete();
                    }

                    //Artist
                    if ($connectee->type_id == 2) {
                        PromoterArtistConnection::where([
                            'promoter_id' => $this->id,
                            'artist_id'   => $connectee->id,
                        ])->delete();
                    }

                    //Fan
                    //Promoter cannot connect to a fan

                    //Promoter
                    //Promoter cannot connect to a promoter

                break;
            }
        }
    }

    public function getConnections($type, $subtype = 'SeeLive', $approved = null)
    {
        return UserConnectionsProvider::getConnections($this, $type, $subtype, $approved);
    }

    public function isConnected(self $connectee, $type = 'SeeLive', $approved = null)
    {
        switch ($this->type_id) {
            //Venue
            case 1:

                //Venue
                //Venue cannot connect to a Venue

                //Artist
                if ($connectee->type_id == 2) {
                    if (ArtistVenueConnection::where([
                        'venue_id' => $this->id,
                        'artist_id' => $connectee->id,
                    ])->count() > 0) {
                        return true;
                    }
                }

                //Fan
                if ($connectee->type_id == 3) {
                    if (FanVenueConnection::where([
                        'venue_id' => $this->id,
                        'fan_id' => $connectee->id,
                    ])->count() > 0) {
                        return true;
                    }
                }

                //Promoter
                if ($connectee->type_id == 4) {
                    if (PromoterVenueConnection::where([
                        'venue_id' => $this->id,
                        'promoter_id' => $connectee->id,
                    ])->count() > 0) {
                        return true;
                    }
                }

            break;

            //Artist
            case 2:

                //Venue
                if ($connectee->type_id == 1) {
                    if (ArtistVenueConnection::where([
                        'artist_id' => $this->id,
                        'venue_id' => $connectee->id,
                    ])->count() > 0) {
                        return true;
                    }
                }

                //Artist
                if ($connectee->type_id == 2) {
                    if (ArtistArtistConnection::where([
                        'artist1_id' => $this->id,
                        'artist2_id' => $connectee->id,
                    ])->count() > 0) {
                        return true;
                    }
                }

                //Fan
                if ($connectee->type_id == 3) {
                    if ($type == 'SeeLive') {
                        if (FanArtistSeeLiveConnection::where([
                            'artist_id' => $this->id,
                            'fan_id' => $connectee->id,
                        ])->count() > 0) {
                            return true;
                        }
                    } elseif ($type == 'SeenLive') {
                        if (FanArtistSeenLiveConnection::where([
                            'artist_id' => $this->id,
                            'fan_id' => $connectee->id,
                        ])->count() > 0) {
                            return true;
                        }
                    }
                }

                //Promoter
                if ($connectee->type_id == 4) {
                    if (ArtistPromoterConnection::where([
                        'artist_id' => $this->id,
                        'promoter_id' => $connectee->id,
                    ])->count() > 0) {
                        return true;
                    }
                }

            break;

            //Fan
            case 3:
                //Venue
                if ($connectee->type_id == 1) {
                    if (FanVenueConnection::where([
                        'fan_id' => $this->id,
                        'venue_id' => $connectee->id,
                    ])->count() > 0) {
                        return true;
                    }
                }

                //Artist
                if ($connectee->type_id == 2) {
                    if ($type == 'SeeLive') {
                        if (FanArtistSeeLiveConnection::where([
                            'fan_id' => $this->id,
                            'artist_id' => $connectee->id,
                        ])->count() > 0) {
                            return true;
                        }
                    } elseif ($type == 'SeenLive') {
                        if (FanArtistSeenLiveConnection::where([
                            'fan_id' => $this->id,
                            'artist_id' => $connectee->id,
                        ])->count() > 0) {
                            return true;
                        }
                    } elseif ($type == 'Team') {
                        if (FanArtistTeamConnection::where([
                            'fan_id' => $this->id,
                            'artist_id' => $connectee->id,
                        ])->count() > 0) {
                            return true;
                        }
                    }
                }

                //Fan
                if ($connectee->type_id == 3) {
                    $row = FanFanConnection::where([
                        'fan_id1' => $this->id,
                        'fan_id2' => $connectee->id,
                    ])->orWhere([
                        'fan_id2' => $this->id,
                        'fan_id1' => $connectee->id,
                    ]);

                    // dd($this->id);
                    if ($row->count() > 0) {
                        if (is_null($approved) || $row->first()->approved == $approved) {
                            return true;
                        }
                    }
                }

                //Promoter
                if ($connectee->type_id == 4) {
                    if (FanPromoterConnection::where([
                        'fan_id' => $this->id,
                        'promoter_id' => $connectee->id,
                    ])->count() > 0) {
                        return true;
                    }
                }

            break;

            //Promoter
            case 4:

                //Venue
                if ($connectee->type_id == 1) {
                    if (PromoterVenueConnection::where([
                        'promoter_id' => $this->id,
                        'venue_id' => $connectee->id,
                    ])->count() > 0) {
                        return true;
                    }
                }

                //Artist
                if ($connectee->type_id == 2) {
                    if (PromoterArtistConnection::where([
                        'promoter_id' => $this->id,
                        'artist_id' => $connectee->id,
                    ])->count() > 0) {
                        return true;
                    }
                }

                //Fan
                //Promoter cannot connect to a fan

                //Promoter
                //Promoter cannot connect to a promoter

            break;
        }

        return false;
    }

    //------------------------------ Could do with refactor ----------------------------------------

    public function hasVoted($venueid)
    {
        if (Auth::check()) {
            if (DB::table('venue_votes')->where('user_id', $this->id)->where('venue_id', $venueid)->count() > 0) {
                return true;
            }
        }

        return false;
    }

    public function addVote($venueid)
    {
        if (Auth::check()) {
            if (DB::table('venue_votes')->where('user_id', $this->id)->where('venue_id', $venueid)->count() == 0) {
                DB::table('venue_votes')->insert([
                    'user_id'  => $this->id,
                    'venue_id' => $venueid,
                ]);

                return true;
            }
        }

        return false;
    }

    public function getPoints()
    {
        $total_points = 0;

        foreach ($this->point_adjustments as $adjustment) {
            $total_points += $adjustment->amount;
        }

        return $total_points;
    }

    public function checkDevice($data)
    {
        if ($data['uuid']) {
            if (Device::where([
                    'uuid'    => $data['uuid'],
                    'user_id' => $this->id,
                ])->count() > 0) {
                $device = Device::where('uuid', $data['uuid'])->first();
                $device->update([
                    'model'        => $data['model'],
                    'platform'     => $data['platform'],
                    'version'      => $data['version'],
                    'manufacturer' => $data['manufacturer'],
                    'serial'       => $data['serial']
                ]);
            } else {
                $device = Device::addNew([
                    'uuid'         => $data['uuid'],
                    'model'        => $data['model'],
                    'platform'     => $data['platform'],
                    'version'      => $data['version'],
                    'manufacturer' => $data['manufacturer'],
                    'serial'       => $data['serial']
                ]);

                $device->setUser($this);
            }

            $device->updateLastLoginDate();
        }
    }

    public function getTicketsWithEventData()
    {
        $tickets = [];

        foreach ($this->tickets as $ticket) {
            $ticket->total_price = ($ticket->type->price * $ticket->quantity);
            $ticket->qr_code = url($ticket->getQRCode()->full_url);
            $ticket->type_data = $ticket->type;
            $ticket->event_data = $ticket->event;
            // $ticket->event_data->thumbnail_src = url($ticket->event->getThumbnail()->full_url);
            $ticket->event_data->thumbnail_src = url($ticket->event->getDefaultImage()->full_url);
            $ticket->event_data->local_date = [ "date" => $ticket->event->getLocalTime()->toDateTimeString()];
            $ticket->event_data->local_date_formatted = $ticket->event->getLocalTime()->format('d M, Y');
            $ticket->event_data->local_time_formatted = $ticket->event->getLocalTime()->format('H:i');
            if ($ticket->event->venue) {
                $ticket->venue_data = $ticket->event->venue;
                $ticket->venue_data->location_name = $ticket->event->venue->location();
                $ticket->venue_data->address = $ticket->event->venue->address(false);
                $ticket->venue_data->address_for_search = urlencode($ticket->event->venue->venue_name.' '.str_replace(',', '', $ticket->event->venue->address(false)));
            } else {
                $ticket->venue_data = new self;
                $ticket->venue_data->venue_name = '[Deleted]';
                $ticket->venue_data->location_name = '[Deleted]';
                $ticket->venue_data->address = '[Deleted]';
                $ticket->venue_data->address_for_search = '[Deleted]';
            }
            $tickets[] = $ticket;
        }

        usort($tickets, function ($a, $b) {
            $t1 = strtotime($a->event_data->event_at);
            $t2 = strtotime($b->event_data->event_at);

            return $t1 - $t2;
        });

        return $tickets;
    }

    public function safeData()
    {
        return [
            'name'  => $this->getName(),
            'email' => $this->email,
        ];
    }

    public function hasMessageThreadWith(self $user)
    {
        $threads = DB::table('message_thread_participants')->where('user_id', $this->id)->get();
        $thread_ids = [];

        foreach ($threads as $thread) {
            $thread_ids[] = $thread->thread_id;
        }

        $users = DB::table('message_thread_participants')
        ->join('message_threads', 'message_thread_participants.thread_id', '=', 'message_threads.id')
        ->where('message_threads.enquiry_id', 0)
        ->whereIn('thread_id', $thread_ids)
        ->where('user_id', '!=', $this->id)->get();

        $user_ids = [];

        foreach ($users as $v) {
            $user_ids[] = $v->user_id;
        }

        if (in_array($user->id, $user_ids)) {
            return true;
        } else {
            return false;
        }
    }

    public function getMessageThreadWith(self $user)
    {
        return MessageThread::findOrFail(
            DB::table('message_thread_participants AS u1')
            ->join('message_thread_participants AS u2', 'u1.thread_id', '=', 'u2.thread_id')
            ->join('message_threads', 'u1.thread_id', '=', 'message_threads.id')
            ->where(function ($query) use ($user) {
                $query->where('u2.user_id', $user->id)
                ->where('u1.user_id', $this->id);
            })->orWhere(function ($query) use ($user) {
                $query->where('u1.user_id', $user->id)
                ->where('u2.user_id', $this->id);
            })
            ->where('message_threads.enquiry_id', 0)
            ->first()
            ->thread_id
        );
    }

    public function hasUnreadMessages()
    {
        foreach ($this->message_threads() as $thread) {
            if ($thread->isUnread($this)) {
                return true;
            }
        }

        return false;
    }

    public function getEventsWithData()
    {
        $events = [];

        foreach ($this->venue_events as $event) {
            $event->type_data = $event->ticketTypes;
            foreach ($event->type_data as $k => $type) {
                $event->type_data[$k]->allocated = $type->scannedTotal();
            }
            $event->thumbnail_src = $event->getThumbnail()->full_url;
            $event->local_date = $event->getLocalTime();
            $event->local_date_formatted = $event->getLocalTime()->format('d M, Y');
            $event->local_time_formatted = $event->getLocalTime()->format('H:i');
            $event->venue_data = $event->venue;
            $events[] = $event;
        }

        usort($events, function ($a, $b) {
            $t1 = strtotime($a->event_at);
            $t2 = strtotime($b->event_at);

            return $t1 - $t2;
        });

        return $events;
    }

    public function doVenueScanTicket($event_id, $barcode)
    {
        $event = Event::findOrFail($event_id);

        if ($event->venue_id == $this->id) {
            if ($event->tickets()->where([
                'barcode' => $barcode,
                'scanned' => 0,
            ])->count() == 1) {
                $ticket = $event->tickets()->where([
                    'barcode' => $barcode,
                    'scanned' => 0,
                ])->first();

                $ticket->markAsScanned();

                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public function notificationTypeName()
    {
        if ($this->isVenue()) {
            return 'venue';
        } elseif ($this->isArtist()) {
            return 'artist';
        } elseif ($this->isFan()) {
            return 'fan';
        } elseif ($this->isPromoter()) {
            return 'promoter';
        }
    }

    public function updateNotificationPreference(NotificationType $notification_type, $on = 1)
    {
        if ($this->notification_preferences()->where('notification_type_id', $notification_type->id)->count() > 0) {
            $pref = $this->notification_preferences()->where('notification_type_id', $notification_type->id)->first();
            $pref->setAllow($on);
        } else {
            $pref = UserNotificationPreference::create([
                'user_id'              => $this->id,
                'notification_type_id' => $notification_type->id,
                'allow'                => $on,
            ]);
        }
    }

    public function getMessagingPreference($id)
    {
        if ($this->messaging_preferences()->where('messaging_preference_id', $id)->count() > 0) {
            return $this->messaging_preferences()->where('messaging_preference_id', $id)->first()->value;
        } else {
            return MessagingPreference::findOrFail($id)->default_value;
        }
    }

    public function updateMessagingPreference(MessagingPreference $preference, $on = 1)
    {
        if ($this->messaging_preferences()->where('messaging_preference_id', $preference->id)->count() > 0) {
            $pref = $this->messaging_preferences()->where('messaging_preference_id', $preference->id)->first();
            $pref->setValue($on);
        } else {
            $pref = UserMessagingPreference::create([
                'user_id'                 => $this->id,
                'messaging_preference_id' => $preference->id,
                'value'                   => $on,
            ]);
        }
    }

    public function updateEnquiriesPreference($value)
    {
        $this->allow_enquiries = $value;
        $this->save();
    }

    public function updateVenueEnquiriesPreference($value)
    {
        $this->allow_unavail_enquiries = $value;
        $this->save();
    }

    public function getMessagingThread(self $user)
    {
        foreach ($this->message_threads() as $thread) {
            if ($thread->getRecipient()->id == $user->id) {
                return $thread;
            }
        }
    }

    public function eventInterests()
    {
        return EventInterest::where(['user_id' => $this->id])->get();
    }

    public function isInterestedInEvent($event_id)
    {
        if (EventInterest::where(['user_id' => $this->id, 'event_id' => $event_id])->count() == 0) {
            return false;
        } else {
            return true;
        }
    }

    public function isNotInterestedInEvent($event_id)
    {
        if (EventNonInterest::where(['user_id' => $this->id, 'event_id' => $event_id])->count() == 0) {
            return false;
        } else {
            return true;
        }
    }

    public function isInterestedInTour($tour_id)
    {
        if (TourInterest::where(['user_id' => $this->id, 'tour_id' => $tour_id])->count() == 0) {
            return false;
        } else {
            return true;
        }
    }

    public function futureTickets()
    {
        $tickets = new Collection;

        foreach ($this->tickets as $ticket) {
            if ($ticket->event->event_at->isFuture()) {
                $tickets->push($ticket);
            }
        }

        return $tickets;
    }

    public function pastTickets()
    {
        $tickets = new Collection;

        foreach ($this->tickets as $ticket) {
            if ($ticket->event->event_at->isPast()) {
                $tickets->push($ticket);
            }
        }

        return $tickets;
    }

    public function canUseTicketing()
    {
        if (! $this->isVenue()) {
            return false;
        } else {
            // 74 = UK
            if ($this->country_id == 74) {
                return true;
            }
        }

        return false;
    }

    public function isGlobalPromoter()
    {
        if ($this->isPromoter() && $this->global_promoter == 1) {
            return true;
        }

        return false;
    }

    public function sendGlobalPromoterRequest()
    {
        Mail::to('contact@musicplanetlive.com')->send(new GlobalPromoterRequestEmail($this));
    }

    public function removeLocalPromoterRestriction()
    {
        $this->global_promoter = 1;
        $this->save();
    }

    public function addLocalPromoterRestriction()
    {
        $this->global_promoter = 0;
        $this->save();
    }

    public function eventInvites()
    {
        $events = new Collection;

        $artists = $this->getConnections('artist', 'SeenLive')
            ->merge($this->getConnections('artist', 'SeeLive'))
            ->unique()
            ->pluck('id');

        $events = \DB::table('event_artists')->whereIn('artist_id', $artists)->select('event_id')->pluck('event_id');            

        return Event::whereIn('id', $events)
            ->where('events.status_id', 3)
            ->where('event_at', '>', \Carbon\Carbon::now())
            ->orderBy('event_at')
            ->get();
    }

    public function hasSavedAvailPreferences()
    {
        $preferences = VenueAvailabilityPreference::where('venue_id', $this->id)->first();

        if ($preferences != null) {
            return true;
        } else {
            return false;
        }
    }

    public function getSavedAvailPreference($name)
    {
        $preference = VenueAvailabilityPreference::where('venue_id', $this->id)->pluck($name);

        if ($preference != null) {
            return $preference->first();
        } else {
            return false;
        }
    }

    public function avail_preference_genres()
    {
        $pref_id = $this->getSavedAvailPreference('id');

        if ($pref_id) {
            $links = VenueAvailabilityPreferenceGenre::where('preference_id', $pref_id)->get();
            $genres = new Collection;

            foreach ($links as $link) {
                $genres->push(Genre::findOrFail($link->genre_id));
            }
        } else {
            $genres = new Collection;
        }

        return $genres;
    }

    public function hasPromoterAsDefault($promoter_id)
    {
        $pref_id = $this->getSavedAvailPreference('id');

        if ($pref_id) {
            $links = VenueAvailabilityPreferencePromoter::where('preference_id', $pref_id)->get();

            foreach ($links as $link) {
                if ($link->promoter_id == $promoter_id) {
                    return true;
                }
            }
        }

        return false;
    }

    public function isChallenged($date)
    {
        $date = Carbon::parse($date);

        if ($this->enquiries()->get()->where('challenge', 1)->where('enquiry_at', '>=', $date->setTime(00, 00, 00))->where('enquiry_at', '<=', $date->setTime(23, 59, 59))->count() > 0) {
            return true;
        } else {
            return false;
        }
    }

    public function futureTours($filter = '')
    {
        if ($filter != '') {
            $tours = Tour::search($filter)->where('creator_id', $this->id)->get();
        } else {
            $tours = $this->tours;
        }

        if ($this->isBand()) {
            $headliner_tour_ids = DB::table('tour_artists')
                ->select('tour_id')
                ->where('artist_id', $this->id)
                ->where('slot_type_id', 1)
                ->pluck('tour_id');

            $headliner_tours = Tour::whereIn('id', $headliner_tour_ids)->get();

            foreach ($headliner_tours as $ht) {
                $tours->push($ht);
            }
        }

        $futureTours = [];

        if ($tours->count() > 0) {
            foreach ($tours as $tour) {
                if ($tour->isFutureTour()) {
                    $futureTours[] = $tour->id;
                }
            }
        }

        return Tour::whereIn('id', $futureTours);
    }

    public function futureCancelledTours($filter)
    {
        if ($filter != '') {
            $tours = Tour::search($filter)->where('creator_id', $this->id)->onlyTrashed()->get();
        } else {
            $tours = $this->tours()->onlyTrashed()->get();
        }

        if ($this->isBand()) {
            $headliner_tour_ids = DB::table('tour_artists')->select('tour_id')->where('artist_id',
                $this->id)->where('slot_type_id', 1)->pluck('tour_id');
            $headliner_tours = Tour::whereIn('id', $headliner_tour_ids)->onlyTrashed()->get();

            foreach ($headliner_tours as $ht) {
                $tours->push($ht);
            }
        }

        $futureTours = [];

        if ($tours->count() > 0) {
            foreach ($tours as $tour) {
                if ($tour->isFutureTour()) {
                    $futureTours[] = $tour->id;
                }
            }
        }

        return Tour::withTrashed()->whereIn('id', $futureTours);
    }

    public function pastTours($filter = '')
    {
        if ($filter != '') {
            $tours = Tour::search($filter)->where('creator_id', $this->id)->get();
        } else {
            $tours = $this->tours;
        }

        if ($this->isBand()) {
            $headliner_tour_ids = DB::table('tour_artists')->select('tour_id')->where('artist_id',
                $this->id)->where('slot_type_id', 1)->pluck('tour_id');
            $headliner_tours = Tour::whereIn('id', $headliner_tour_ids)->get();

            foreach ($headliner_tours as $ht) {
                $tours->push($ht);
            }
        }

        $pastTours = [];

        if ($tours->count() > 0) {
            foreach ($tours as $tour) {
                if (! $tour->isFutureTour()) {
                    $pastTours[] = $tour->id;
                }
            }
        }

        return Tour::whereIn('id', $pastTours);
    }

    public function pastCancelledTours($filter = '')
    {
        if ($filter != '') {
            $tours = Tour::search($filter)->where('creator_id', $this->id)->onlyTrashed()->get();
        } else {
            $tours = $this->tours()->onlyTrashed()->get();
        }

        if ($this->isBand()) {
            $headliner_tour_ids = DB::table('tour_artists')->select('tour_id')->where('artist_id',
                $this->id)->where('slot_type_id', 1)->pluck('tour_id');
            $headliner_tours = Tour::whereIn('id', $headliner_tour_ids)->onlyTrashed()->get();

            foreach ($headliner_tours as $ht) {
                $tours->push($ht);
            }
        }

        $pastTours = [];

        if ($tours->count() > 0) {
            foreach ($tours as $tour) {
                if (! $tour->isFutureTour()) {
                    $pastTours[] = $tour->id;
                }
            }
        }

        return Tour::withTrashed()->whereIn('id', $pastTours);
    }

    public function isAvailable($date)
    {
        if ($this->availability()->where('availability_at', $date->setTime(00, 00, 00))->count() > 0) {
            return true;
        }

        return false;
    }

    public function getAvailability($date)
    {
        return $this->availability()->where('availability_at', $date->setTime(00, 00, 00))->first();
    }

    public function artistReach(self $artist)
    {
        $venue_fans = $this->allFollowingFans();
        $artist_fans = $artist->allFollowingFans();
        $i = 0;

        foreach ($venue_fans as $vf) {
            if ($artist_fans->contains('email', $vf->email)) {
                $i++;
            }
        }

        return $i;
    }

    public function getName($limit = 25)
    {
        if ($this->isBand()) {
            $name = $this->artist_name;
        } elseif ($this->isVenue()) {
            $name = $this->venue_name;
        } elseif ($this->isFan()) {
            $name = $this->first_name.' '.$this->last_name;
        } elseif ($this->isPromoter()) {
            $name = $this->promoter_name;
        } elseif ($this->isAdmin()) {
            $name = $this->first_name.' '.$this->last_name;
        } else {
            $name = '';
        }

        if ($limit > 0) {
            if (strlen($name) > $limit) {
                $name = substr($name, 0, $limit).'...';
            }
        }

        return $name;
    }

    public function getProfileLink()
    {
        if ($this->isVenue()) {
            return url('venue/'.$this->clean_url);
        } else {
            if ($this->isArtist()) {
                return url('artist/'.$this->clean_url);
            } else {
                if ($this->isPromoter()) {
                    return url('promoter/'.$this->clean_url);
                } else {
                    if ($this->isFan()) {
                        return url('member/'.$this->clean_url);
                    }
                }
            }
        }
    }

    public function getProfileLinkAttribute()
    {
        if ($this->isVenue()) {
            return url('venue/'.$this->clean_url);
        } else {
            if ($this->isArtist()) {
                return url('artist/'.$this->clean_url);
            } else {
                if ($this->isPromoter()) {
                    return url('promoter/'.$this->clean_url);
                } else {
                    if ($this->isFan()) {
                        return url('member/'.$this->clean_url);
                    }
                }
            }
        }
    }

    public function generateCleanURL()
    {
        //If it's a Venue
        if ($this->type->id == 1) {
            $string_to_use = $this->venue_name;
        } elseif ($this->type->id == 2) {
            $string_to_use = $this->artist_name;
        } elseif ($this->type->id == 3) {
            $string_to_use = $this->first_name.'-'.$this->last_name;
        } elseif ($this->type->id == 4) {
            $string_to_use = $this->promoter_name;
        } elseif ($this->type->id == 5) {
            $string_to_use = $this->first_name.'-'.$this->last_name;
        }

        $accents_regex = '~&([a-z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i';
        $special_cases = ['&' => 'and', "'" => ''];
        $string = mb_strtolower(trim($string_to_use), 'UTF-8');
        $string = str_replace(array_keys($special_cases), array_values($special_cases), $string);
        $string = preg_replace($accents_regex, '$1', htmlentities($string, ENT_QUOTES, 'UTF-8'));
        $string = preg_replace('/[^a-z0-9]/u', '-', $string);
        $string = preg_replace('/[-]+/u', '-', $string);

        if (self::where('clean_url', $string)->where('type_id', $this->type->id)->count() > 0) {
            $string .= '-'.\Illuminate\Support\Str::random(6);
        }

        $this->clean_url = $string;
        $this->save();
    }

    public function avail_preference_promoters()
    {
        $pref_id = $this->getSavedAvailPreference('id');

        if ($pref_id) {
            $links = VenueAvailabilityPreferencePromoter::where('preference_id', $pref_id)->get();
            $promoters = new Collection;

            foreach ($links as $link) {
                $promoters->push(self::findOrFail($link->promoter_id));
            }
        } else {
            $promoters = new Collection;
        }

        return $promoters;
    }

    public function isMvt()
    {
        return $this->mvt_venue;
    }

    public function toggleMvt()
    {
        if ($this->isMvt()) {
            $this->mvt_venue = 0;
        } else {
            $this->mvt_venue = 1;
        }
        $this->save();
    }

    public function getLatestNotification()
    {
        if ($this->notifications->count() == 0) {
            return false;
        }

        return $this->notifications()->latest()->first();
    }

    public function shouldShowPrivacySettingsPage()
    {
        if ($this->isPromoter()) {
            return true;
        }

        return false;
    }

    public function isVisibleToArtists()
    {
        return $this->visible_to_artists;
    }

    public function isVisibleToVenues()
    {
        return $this->visible_to_venues;
    }

    public function isVisibleToFans()
    {
        return $this->visible_to_fans;
    }

    public function isVisibleToPromoters()
    {
        return $this->visible_to_promoters;
    }

    public function isVisibleToGuests()
    {
        return $this->visible_to_guests;
    }

    public function isVisible()
    {
        if (! Auth::check() && ! $this->isVisibleToGuests()) {
            return false;
        }

        if (Auth::check() && Auth::user()->isArtist() && ! $this->isVisibleToArtists() && ! $this->isConnected(Auth::user())) {
            return false;
        }

        if (Auth::check() && Auth::user()->isPromoter() && ! $this->isVisibleToPromoters() && Auth::user()->id != $this->id) {
            return false;
        }

        if (Auth::check() && Auth::user()->isFan() && ! $this->isVisibleToFans()) {
            return false;
        }

        if (Auth::check() && Auth::user()->isVenue() && ! $this->isVisibleToVenues() && ! $this->isConnected(Auth::user())) {
            return false;
        }

        return true;
    }

    public function updateVisibleToArtists($value)
    {
        $this->visible_to_artists = $value;
        $this->save();
    }

    public function updateVisibleToVenues($value)
    {
        $this->visible_to_venues = $value;
        $this->save();
    }

    public function updateVisibleToFans($value)
    {
        $this->visible_to_fans = $value;
        $this->save();
    }

    public function updateVisibleToPromoters($value)
    {
        $this->visible_to_promoters = $value;
        $this->save();
    }

    public function updateVisibleToGuests($value)
    {
        $this->visible_to_guests = $value;
        $this->save();
    }

    /**
     * @return bool
     */
    public function canImpersonate()
    {
        return $this->type_id == 1;
    }

    /**
     * @return bool
     */
    public function canBeImpersonated()
    {
        return $this->type_id == 1;
    }
}