<?php

namespace App;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Laravel\Scout\Searchable;
use Spatie\Image\Manipulations;
use Spatie\MediaLibrary\HasMedia\HasMedia;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
use Spatie\MediaLibrary\Models\Media;

/**
 * Class ResidentialComplex
 *
 * @package App
 * @property string $name
 * @property string $code
 * @property tinyInteger $enabled
 * @property string $developer
 * @property tinyInteger $is_repair
 * @property tinyInteger $is_credit
 * @property tinyInteger $show_bank
 * @property tinyInteger $is_transport_hub
 * @property string $site_link
 * @property string $site_utm
 * @property string $phone
 * @property integer $main_page_priority
 * @property integer $res_com_page_priority
 * @property decimal $min_price
 * @property decimal $average
 * @property string $plajka
 * @property string $color_picker
 * @property string $preview
 * @property string $preview_color_picker
 * @property string $date_putting_into_operation
 * @property string $building_put_into_operation
 * @property string $quarterly_putting_into_operation_id
 * @property integer $building_count
 * @property integer $room_count
 * @property string $room_count_date
 * @property string $city
 * @property string $district
 * @property string $street_name
 * @property tinyInteger $customer_rating_count

 * @property string $email
 * @property string $presentation
 * @property string $telegram
 * @property string $viber
 * @property string $skype
 * @property string $whatsapp
 * @property string $consultation_description
 * @property string $consultation_button_color
 * @property tinyInteger $is_show_consultation
 * @property tinyInteger $is_show_presentation
 * @property tinyInteger $is_show_telegram
 * @property tinyInteger $is_show_viber
 * @property tinyInteger $is_show_skype
 * @property tinyInteger $is_show_whatsapp
 * @property tinyInteger $is_show_planning
 * @property tinyInteger $is_show_price
 * @property tinyInteger $is_show_terms_of_payments

 * @property string $street_number
 * @property double $location_latitude
 * @property double $center_distance
 * @property double $location_longitude
 * @property string $location
 * @property string $building_status_info
 * @property string $price_info
 * @property string $document_info
 * @property string $planning_info
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Bank[] $bank
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\ClassHousing[] $class
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\RoomCount[] $count_of_room_per_flat
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\CourseOfConstruction[] $courseOfConstruction
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\CustomerRating[] $customerRating
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Document[] $document
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Heating[] $heating
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\ResidentalComplexIcon[] $icon
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Marker[] $markers
 * @property-read \Illuminate\Database\Eloquent\Collection|\Spatie\MediaLibrary\Models\Media[] $media
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\OtherOption[] $other_option
 * @property-read \App\Quarterly $quarterly_putting_into_operation
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\ResidentialComplex[] $recomended_residental_complex_id
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\ResidentialComplexCharacter[] $residential_complex_characters
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\ResidentialComplexSeo[] $residential_complex_seos
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\RoomType[] $room_type
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\SecretBuyerRating[] $secretBuyerRating
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Section[] $sections
 * @property-write mixed $city_id
 * @property-write mixed $developer_id
 * @property-write mixed $district_id
 * @property-write mixed $latitude
 * @property-write mixed $longitude
 * @property-write mixed $street_name_id
 * @property-read \App\StageOfConstruction $stageOfConstruction
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\StageOfConstruction[] $stage_of_construction
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\TechnologyBuilding[] $technology_building
 * @method static bool|null forceDelete()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\ResidentialComplex newModelQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\ResidentialComplex newQuery()
 * @method static \Illuminate\Database\Query\Builder|\App\ResidentialComplex onlyTrashed()
 * @method static \Illuminate\Database\Eloquent\Builder|\App\ResidentialComplex query()
 * @method static bool|null restore()
 * @method static \Illuminate\Database\Query\Builder|\App\ResidentialComplex withTrashed()
 * @method static \Illuminate\Database\Query\Builder|\App\ResidentialComplex withoutTrashed()
 * @mixin \Eloquent
 */
class ResidentialComplex extends Model implements HasMedia
{
    use SoftDeletes, HasMediaTrait, Searchable;

    const CACHE_KEY_MAIN_PAGE_RESULT = "residential_complexes_main_page_result";
    const CACHE_KEY_MAIN_PAGE_COUNT = "residential_complexes_main_page_count";
    protected $fillable = [
        'name',
        'code',
        'enabled',
        'is_repair',
        'is_credit',
        'show_bank',
        'is_transport_hub',
        'site_link',
        'site_utm',
        'main_page_priority',
        'res_com_page_priority',
        'min_price',
        'phone',
        'date_putting_into_operation',
        'building_count',
        'building_put_into_operation',
        'room_count',
        'room_count_date',
        'street_number',
        'latitude',
        'longitude',
        'location_address',
        'location_latitude',
        'location_longitude',
        'developer_id',
        'city_id',
        'district_id',
        'street_name_id',
        'stage_of_construction_id',
        'start_of_sale',
        'average',
        'quarterly_putting_into_operation_id',
        'center_distance',
        'price_info',
        'building_status_info',
        'planning_info',
        'document_info',
        'is_show_consultation',
        'consultation_description',
        'consultation_button_text',
        'consultation_button_color',
        'is_show_presentation',
        'is_show_telegram',
        'is_show_viber',
        'is_show_skype',
        'is_show_whatsapp',
        'is_show_planning',
        'is_show_price',
        'is_show_terms_of_payments',
        'email',
        'presentation',
        'telegram',
        'viber',
        'skype',
        'whatsapp',
        'customer_rating_count',
        'color_picker',
        'plajka',
        'preview_color_picker',
        'preview'
    ];
    protected $hidden = [];

    /**
     * Set to null if empty
     * @param $input
     */
    public function setDeveloperIdAttribute($input)
    {
        $this->attributes['developer_id'] = $input ? $input : null;
    }

    /**
     * Set attribute to money format
     * @param $input
     */
    public function setMainPagePriorityAttribute($input)
    {
        $this->attributes['main_page_priority'] = $input ? $input : null;
    }

    /**
     * Set attribute to money format
     * @param $input
     */
    public function setResComPagePriorityAttribute($input)
    {
        $this->attributes['res_com_page_priority'] = $input ? $input : null;
    }

    /**
     * Set attribute to money format
     * @param $input
     */
    public function setMinPriceAttribute($input)
    {
        $this->attributes['min_price'] = $input ? $input : null;
    }

    /**
     * Set attribute to date format
     * @param $input
     */
    public function setDatePuttingIntoOperationAttribute($input)
    {
        if ($input != null && $input != '') {
            $this->attributes['date_putting_into_operation'] = Carbon::createFromFormat(config('app.date_format'),
                '01.01.' . $input)->format('Y-m-d');
        } else {
            $this->attributes['date_putting_into_operation'] = null;
        }
    }

    /**
     * Get attribute from date format
     * @param $input
     *
     * @return string
     */
    public function getDatePuttingIntoOperationAttribute($input)
    {
        $zeroDate = str_replace(['Y', 'm', 'd'], ['0000', '00', '00'], config('app.date_format'));
        if ($input != $zeroDate && $input != null) {
            return Carbon::createFromFormat('Y-m-d', $input)->format(config('app.date_year_format'));
        } else {
            return '';
        }
    }

    /**
     * Set attribute to money format
     * @param $input
     */
    public function setBuildingCountAttribute($input)
    {
        $this->attributes['building_count'] = $input ? $input : null;
    }

    /**
     * Set attribute to money format
     * @param $input
     */
    public function setRoomCountAttribute($input)
    {
        $this->attributes['room_count'] = $input ? $input : null;
    }

    /**
     * Set attribute to date format
     * @param $input
     */
    public function setRoomCountDateAttribute($input)
    {
        if ($input != null && $input != '') {
            $this->attributes['room_count_date'] = Carbon::createFromFormat(config('app.date_format'),
                $input)->format('Y-m-d');
        } else {
            $this->attributes['room_count_date'] = null;
        }
    }

    /**
     * Get attribute from date format
     * @param $input
     *
     * @return string
     */
    public function getRoomCountDateAttribute($input)
    {
        $zeroDate = str_replace(['Y', 'm', 'd'], ['0000', '00', '00'], config('app.date_format'));
        if ($input != $zeroDate && $input != null) {
            return Carbon::createFromFormat('Y-m-d', $input)->format(config('app.date_format'));
        } else {
            return '';
        }
    }

    /**
     * Set to null if empty
     * @param $input
     */
    public function setCityIdAttribute($input)
    {
        $this->attributes['city_id'] = $input ? $input : null;
    }

    /**
     * Set to null if empty
     * @param $input
     */
    public function setDistrictIdAttribute($input)
    {
        $this->attributes['district_id'] = $input ? $input : null;
    }

    /**
     * Set to null if empty
     * @param $input
     */
    public function setStreetNameIdAttribute($input)
    {
        $this->attributes['street_name_id'] = $input ? $input : null;
    }

    /**
     * Set attribute to date format
     * @param $input
     */
    public function setLatitudeAttribute($input)
    {
        if ($input != '') {
            $this->attributes['latitude'] = $input;
        } else {
            $this->attributes['latitude'] = null;
        }
    }

    /**
     * Set attribute to date format
     * @param $input
     */
    public function setLongitudeAttribute($input)
    {
        if ($input != '') {
            $this->attributes['longitude'] = $input;
        } else {
            $this->attributes['longitude'] = null;
        }
    }

    public function developer()
    {
        return $this->belongsTo(Developer::class, 'developer_id')->withTrashed();
    }

    public function count_of_room_per_flat()
    {
        return $this->belongsToMany(RoomCount::class, 'residential_complex_room_count')->withTrashed();
    }

    public function room_type()
    {
        return $this->belongsToMany(RoomType::class, 'residential_complex_room_type')->withTrashed();
    }

    public function city()
    {
        return $this->belongsTo(City::class, 'city_id')->withTrashed();
    }

    public function district()
    {
        return $this->belongsTo(District::class, 'district_id')->withTrashed();
    }

    public function stageOfConstruction()
    {
        return $this->belongsTo(StageOfConstruction::class, 'stage_of_construction_id')->withTrashed();
    }

    public function street_name()
    {
        return $this->belongsTo(StreetName::class, 'street_name_id')->withTrashed();
    }

    public function class()
    {
        return $this->belongsToMany(ClassHousing::class, 'class_housing_residential_complex')->withTrashed();
    }

    public function heating()
    {
        return $this->belongsToMany(Heating::class, 'heating_residential_complex')->withTrashed();
    }

    public function technology_building()
    {
        return $this->belongsToMany(TechnologyBuilding::class,
            'residential_complex_technology_building')->withTrashed();
    }

    public function other_option()
    {
        return $this->belongsToMany(OtherOption::class, 'other_option_residential_complex')->withTrashed();
    }

    public function icon()
    {
        return $this->belongsToMany(ResidentalComplexIcon::class,
            'residental_complex_icon_residential_complex')->withTrashed();
    }

    public function recomended_residental_complex_id()
    {
        return $this->belongsToMany(ResidentialComplex::class, 'residential_complex_residential_complex',
            "residential_complex_id", "residential_complex_recommended_id");
    }

    public function residential_complex_characters()
    {
        return $this->hasMany(ResidentialComplexCharacter::class, 'residental_complex_id');
    }

    public function bank()
    {
        return $this->belongsToMany(Bank::class, 'bank_residential_complex')->withTrashed();
    }

    public function residential_complex_seos()
    {
        return $this->hasMany(ResidentialComplexSeo::class, 'residential_complex_id');
    }

    public function courseOfConstruction()
    {
        return $this->hasMany(CourseOfConstruction::class, 'residental_complex_id')->withTrashed();
    }

    public function sections()
    {
        return $this->hasMany(Section::class, 'residental_complex_id')->withTrashed();
    }

    public function customerRating()
    {
        return $this->hasMany(CustomerRating::class, 'residental_complex_id')->withTrashed();
    }

    public function secretBuyerRating()
    {
        return $this->hasMany(SecretBuyerRating::class, 'residental_complex_id')->withTrashed();
    }

    public function document()
    {
        return $this->hasMany(Document::class, 'residental_complex_id');
    }

    public function quarterly_putting_into_operation()
    {
        return $this->belongsTo(Quarterly::class, 'quarterly_putting_into_operation_id')->withTrashed();
    }

    public function prices()
    {
        return $this->hasMany(Price::class, 'residential_complex_id');
    }

    public function planning_prices()
    {
        return $this->hasMany(PlanningPrice::class, 'residential_complex_id');
    }

    public function term_of_paymentes()
    {
        return $this->hasMany(TermsOfPayment::class, 'residential_complex_id');
    }

    public function registerMediaConversions(Media $media = null)
    {
        // Landscape image format
        $this->addMediaConversion('developer')
            ->fit(Manipulations::FIT_STRETCH, 160, 160)
            ->performOnCollections('landscape_photo')
            ->optimize();

        $this->addMediaConversion('developer_webp')
            ->fit(Manipulations::FIT_STRETCH, 160, 160)
            ->performOnCollections('landscape_photo')
            ->optimize();

        $this->addMediaConversion('list')
            ->fit(Manipulations::FIT_STRETCH, 360, 251)
            ->performOnCollections('landscape_photo')
            ->optimize();

        $this->addMediaConversion('list_webp')->format('webp')
            ->fit(Manipulations::FIT_STRETCH, 360, 251)
            ->performOnCollections('landscape_photo')
            ->optimize();

        $this->addMediaConversion('residential_complex_big')
//            ->fit(Manipulations::FIT_STRETCH, 800, 650)
//            ->fit(Manipulations::FIT_STRETCH, 1418, 1200)
//            ->crop(Manipulations::CROP_LEFT, 1418, 1200)
            ->performOnCollections('photo', 'landscape_photo')
            ->optimize();

        $this->addMediaConversion('residential_complex_big_webp')->format('webp')
            ->performOnCollections('landscape_photo')
            ->optimize();

        // Main pageformat
        $this->addMediaConversion('main_small')
            ->fit(Manipulations::FIT_STRETCH, 225, 268)
            ->performOnCollections('photo')
            ->optimize();

        $this->addMediaConversion('main_small_webp')->format('webp')
            ->fit(Manipulations::FIT_STRETCH, 225, 268)
            ->performOnCollections('photo')
            ->optimize();

        $this->addMediaConversion('main_big')
//            ->crop(Manipulations::CROP_RIGHT, 1218, 1200)
//            ->crop(Manipulations::CROP_CENTER, 1015, 1200)
//            ->fit(Manipulations::FIT_STRETCH, 1200, 1418)
            ->performOnCollections('photo')
            ->optimize();

        $this->addMediaConversion('main_big_webp')
            ->format('webp')
//            ->crop(Manipulations::CROP_RIGHT, 1218, 1200)
//            ->crop(Manipulations::CROP_CENTER, 1015, 1200)
            //            ->fit(Manipulations::FIT_STRETCH, 1200, 1418)
            ->performOnCollections('photo')
              ->optimize();


    }

    public function markers()
    {
        return $this->belongsToMany(Marker::class, 'residential_complex_markers')->withTrashed();
    }

    /**
     * Get the index name for the model.
     *
     * @return string
     */
    public function searchableAs()
    {
        return config("scout.rc_index");
    }

    /**
     * Get the indexable data array for the model.
     *
     * @return array
     */
    public function toSearchableArray()
    {
        $array = [
            'id' => $this->id,
            'name' => $this->name,
            'enabled' => (int)$this->enabled,
            'city' => $this->city ? $this->city->name : "",
            'street_name' => $this->street_name ? $this->street_name->name : "",
            'street_type' => $this->street_name && $this->street_name->type ? $this->street_name->type->short_name : "",
            'street_number' => $this->street_number,
        ];

        return $array;
    }

    public function shouldBeSearchable()
    {
        return $this->enabled == 1 ? true : false;
    }
}
