<?php

namespace Hilco\Models;

use Carbon\Carbon;
use Illuminate\Support\Facades\Storage;

/**
 * class Hilco\Models\WebAsset
 * @property-read int $id
 * @property string $date_created
 * @property string $date_modified
 * @property string $deleted_at
 * @property string $asset_key
 * @property string $asset_category
 * @property string $mime_type
 * @property string $name
 * @property string $description
 * @property string $original_filename
 * @property boolean $is_private
 */
class WebAsset extends WebModel {
    protected $table = 'WebAssets';
    protected $fillable = ['authorized_only', 'asset_key', 'asset_category', 'original_filename', 'mime_type', 'name', 'description'];
    protected $appends = ['full_key', 'url', 'urls'];

    protected static $morphMap = [
        'webPart' => WebPart::class,
        'webFamily' => WebFamily::class,
        'webCollection' => WebCollection::class,
        'webCategory' => WebCategory::class,
        'webGroup' => WebGroup::class,
        'webSilo' => WebSilo::class,
        'webLinkCategory' => WebLinkCategory::class,
        'webLink' => WebLink::class,
        'webAttribute' =>WebAttribute::class,
        'webAttributeValue' => WebAttribute_WebPart::class,
        'webProductMenuConfiguration' =>WebProductMenuConfiguration::class,
        'webContactBlock' => WebContactBlock::class,
        'assetable' => Assetable::class,
    ];

//    protected static $mimeTypes;

//    protected static $assetCategories;
//
//    protected static $assetableJoinTypes;

    public function __construct($attributes = [])
    {
        parent::__construct($attributes);

//        $this->mimeTypes = [
//            'image/jpeg' => [
//                'type' => 'image',
//                'subtype' => 'jpeg',
//                'displayName' => trans('image'),f
//                'encodeAs' => 'jpg',
//                'isImage' => true,
//            ],
//            'image/png' => [
//                'type' => 'image',
//                'subtype' => 'png',
//                'displayName' => trans('image'),
//                'encodeAs' => 'png',
//                'isImage' => true,
//            ],
//            'image/bmp' => [
//                'type' => 'image',
//                'subtype' => 'bmp',
//                'displayName' => trans('image'),
//                'encodeAs' => 'jpg',
//                'isImage' => true,
//            ],
//            'application/pdf' => [
//                'type' => 'application',
//                'subtype' => 'pdf',
//                'displayName' => trans('pdf'),
//                'encodeAs' => 'pdf',
//                'isImage' => false,
//            ],
//        ];
//
//        $this->assetCategories = [
//            'part' => trans('hilco::app.part_images'),
//            'image' => trans('hilco::app.other_mages'),
//            'banner' => trans('hilco::app.banners'),
//            'document' => trans('hilco::app.documents_forms'),
//        ];
//
//        $this->assetableJoinTypes = [
//            'primary' => trans('hilco::app.primary_image'),
//            'thumbnail' => trans('hilco::app.thumbnail_image'),
//            'additional' => trans('hilco::app.additional_image'),
//            'featured' => trans('hilco::app.featured_image'),
//            'banner' => trans('hilco::app.banner'),
//        ];
    }

    public static function getMorphMap() {
        return self::$morphMap;
    }

    public static function getAssetableClass($morphMapKey) {
        return \Illuminate\Support\Arr::get(self::$morphMap, $morphMapKey);
    }

    public static function getMimeInfo($mimeType) {
        $mimeTypes = [
            'image/jpeg' => [
                'type' => 'image',
                'subtype' => 'jpeg',
                'displayName' => trans('image'),
                'encodeAs' => 'jpg',
                'isImage' => true,
            ],
            'image/png' => [
                'type' => 'image',
                'subtype' => 'png',
                'displayName' => trans('image'),
                'encodeAs' => 'png',
                'isImage' => true,
            ],
            'image/bmp' => [
                'type' => 'image',
                'subtype' => 'bmp',
                'displayName' => trans('image'),
                'encodeAs' => 'jpg',
                'isImage' => true,
            ],
            'application/pdf' => [
                'type' => 'application',
                'subtype' => 'pdf',
                'displayName' => trans('pdf'),
                'encodeAs' => 'pdf',
                'isImage' => false,
            ],
        ];
        return \Illuminate\Support\Arr::get($mimeTypes, $mimeType);
    }

    public static function getAssetableModel($morphMapKey) {
        $className = self::getAssetableClass($morphMapKey);
        return ($className) ? new $className : null;
    }


    public static function getAssetCategory($category = false) {
        $assetCategories = [
            'part' => trans('hilco::app.part_images'),
            'image' => trans('hilco::app.other_mages'),
            'banner' => trans('hilco::app.banners'),
            'document' => trans('hilco::app.documents_forms'),
            'icon' => trans('hilco::app.icon_images'),
            'menubar' => trans('hilco::app.menubar_images'),
        ];
        return $category !== false  ? \Illuminate\Support\Arr::get($assetCategories, $category) : $assetCategories;
    }

    public static function getAssetableJoinType($type = false) {
        $assetableJoinTypes = [
            'primary' => trans('hilco::app.primary_image'),
            'thumbnail' => trans('hilco::app.thumbnail_image'),
            'additional' => trans('hilco::app.additional_image'),
            'featured' => trans('hilco::app.featured_image'),
            'banner' => trans('hilco::app.banner'),
            'icon' => trans('hilco::app.icon_image'),
            'menubartop' => trans('hilco::app.menubar_top_image'),
            'menubarbottom' => trans('hilco::app.menubar_bottom_image'),
            'alternate1' => 'Alternate 1',
            'alternate2' => 'Alternate 2',
            'alternate3' => 'Alternate 3',
            'alternate4' => 'Alternate 4',
            '360-01' => '360-01',
            '360-02' => '360-02',
            '360-03' => '360-03',
            '360-04' => '360-04',
            '360-05' => '360-05',
            '360-06' => '360-06',
            '360-07' => '360-07',
            '360-08' => '360-08',
            '360-09' => '360-09',
            '360-10' => '360-10',
            '360-11' => '360-11',
            '360-12' => '360-12',
            '360-13' => '360-13',
            '360-14' => '360-14',
            '360-15' => '360-15',
            '360-16' => '360-16',
            '360-17' => '360-17',
            '360-18' => '360-18',
            '360-19' => '360-19',
            '360-20' => '360-20',
            '360-21' => '360-21',
            '360-22' => '360-22',
            '360-23' => '360-23',
            '360-24' => '360-24',
            '360-25' => '360-25',
            '360-26' => '360-26',
            '360-27' => '360-27',
            '360-28' => '360-28',
            '360-29' => '360-29',
            '360-30' => '360-30',
            '360-31' => '360-31',
            '360-32' => '360-32',
            '360-33' => '360-33',
            '360-34' => '360-34',
            '360-35' => '360-35',
            '360-36' => '360-36',
            '360-37' => '360-37',
            '360-38' => '360-38',
            '360-39' => '360-39',
            '360-40' => '360-40',
            '360-41' => '360-41',
            '360-42' => '360-42',
            '360-43' => '360-43',
            '360-44' => '360-44',
            '360-45' => '360-45',
            '360-46' => '360-46',
            '360-47' => '360-47',
            '360-48' => '360-48',
        ];

        return $type !== false  ? \Illuminate\Support\Arr::get($assetableJoinTypes, $type) : $assetableJoinTypes;
    }

    public function webParts() {
        return $this->morphedByMany(WebPart::class, 'assetable', 'Assetables', 'webasset_id', 'assetable_id')->withPivot(['sequence', 'assetable_join_type']);
    }

    public function webFamilies() {
        return $this->morphedByMany(WebFamily::class, 'assetable', 'Assetables', 'webasset_id', 'assetable_id')->withPivot(['sequence', 'assetable_join_type']);
    }

    public function getFullKeyAttribute() {
        return $this->asset_category . '/' . $this->asset_key;
    }

    public function getUrlAttribute() {
        return WebAsset::getSizedUrl($this);
    }

    public function getDownloadUrlAttribute() {
        return WebAsset::urlHelper(['id' => $this->id, 'download' => true]);
    }

    public function getUrlsAttribute() {
        $urls['original'] = WebAsset::getSizedUrl($this);
        foreach (config('hilco.assets.sizes') as $size => $dimensions) {
            $urls[$size] = WebAsset::getSizedUrl($this, $dimensions['width'], $dimensions['height']);
        }
        return $urls;
    }

    public function getIconAttribute() {
        if (\Illuminate\Support\Str::startsWith($this->mime_type, 'image')) return 'fa-file-image-o';
        if ($this->mime_type == 'application/pdf') return 'fa-file-pdf-o';
        return 'fa-file-o';
    }

    public function getMimeInfoAttribute() {
        return self::getMimeInfo($this->mime_type);
    }

    public function getIsImageTypeAttribute() {
        return \Illuminate\Support\Arr::get($this->mime_info, 'isImage', false);
    }

    public function getEncodeAsAttribute() {
        return \Illuminate\Support\Arr::get($this->mime_info, 'encodeAs', false);
    }

    public function getMimeNameAttribute() {
        return \Illuminate\Support\Arr::get($this->mime_info, 'displayName', false);
    }

    public function __get($key) {
        if (\Illuminate\Support\Str::startsWith($key, 'url_')) {
            return self::getPredefinedSizeUrl($this, str_replace('url_', '', $key));
        }
        return parent::__get($key);
    }

    public function getFileAttribute() {
        Storage::disk('assets')->get($this->full_key);
    }

    public static function compileUrlForKey($fullKey, $width = false, $height = false) {
        $api = config('hilco.assets.url');
        $url = "$api/$fullKey";
        if ($width) $url .= "/$width";
        if ($height) $url .= "/$height";
        return $url;
    }

    public static function compileUrlForStub($stub) {
        $api = config('hilco.assets.url');
        $spacer = \Illuminate\Support\Str::startsWith($stub, '/') ? '' : '/';
        return $api . $spacer . $stub;
    }

    public static function getPredefinedSizeUrl($webAsset, $size, $keyIfNotFound = false) {
        $size = config("hilco.assets.sizes.$size", [
            'width' => false,
            'height' => false,
        ]);
        return self::getSizedUrl($webAsset, $size['width'], $size['height'], $keyIfNotFound);
    }

    public static function getSizedUrl($webAsset, $width = false, $height = false, $keyIfNotFound = false) {
        if (!($webAsset instanceof WebAsset)) $webAsset = WebAsset::find($webAsset);
        if ($keyIfNotFound === false) $keyIfNotFound = config('hilco.assets.nopic');
        $urlForSeoKey = self::compileUrlForKey(is_null($webAsset) ? $keyIfNotFound : $webAsset->full_key, $width, $height);
        if (isset($webAsset)) {
            $lastMod = Carbon::createFromFormat('Y-m-d H:i:s', $webAsset->date_modified)->timestamp;
            $urlForSeoKey .= "?lastmod=$lastMod";
        }
        return $urlForSeoKey;
    }

    public static function getUrl($webAsset, $keyIfNotFound = false) {
        return self::getSizedUrl($webAsset, false, false, $keyIfNotFound);
    }

    public function scopeAuthorizedOnly($query){
        return $query->where('authorized_only',1);
    }

    public function scopeForAll($query){
        return $query->where('authorized_only',0);
    }

    public static function urlHelper($options) {
        if (!is_array($options)) {
            $options = ['prefix' => 'id', 'key' => $options];
        }
        $url = config('hilco.assets.url');
        $qs = [];

        if(\Illuminate\Support\Arr::get($options, 'productType')) {
            $model = productModel(\Illuminate\Support\Arr::get($options, 'productType'), \Illuminate\Support\Arr::get($options, 'productId'));
            if (!is_null($model)) {
                $webAsset = $model->getPrimaryImage();
                if (!is_null($webAsset)) {
                    $options['id'] = $webAsset->id;
                }
            }
        }

        if (\Illuminate\Support\Arr::has($options, 'id')) {
            $options['prefix'] = 'id';
            $options['key'] = $options['id'];
        }
        if (\Illuminate\Support\Arr::get($options, 'key')) {
            $url .= '/' . \Illuminate\Support\Arr::get($options, 'prefix', 'image');
            $url .= '/' . \Illuminate\Support\Arr::get($options, 'key');
        } else {
            $url .= '/' . config('hilco.assets.nopic');
        }

        if (\Illuminate\Support\Arr::has($options, 'size')) {
            $size = config("hilco.assets.sizes.$options[size]", false);
            if ($size) {
                $options['width'] = $size['width'];
                $options['height'] = $size['height'];
            }
        }
        if (\Illuminate\Support\Arr::get($options, 'width')) $url .= '/' . \Illuminate\Support\Arr::get($options, 'width');
        if (\Illuminate\Support\Arr::get($options, 'height')) $url .= '/' . \Illuminate\Support\Arr::get($options, 'height');

        if (\Illuminate\Support\Arr::get($options, 'download')) $qs['dl'] = '1';
        if (\Illuminate\Support\Arr::get($options, 'token')) {
            if (auth()->user()) {
                $token = createAssetAccessToken();
                $qs['tt'] = $token['token'];
                $qs['ts'] = $token['timestamp'];
            }
            $qs['tr'] = urlencode(config('hilco.b2b.url') . '/login');
        }

        if (count($qs)) {
            $delim = '?';
            foreach ($qs as $key => $value) {
                $url .= $delim . $key . '=' . $value;
                $delim = '&';
            }
        }

        return $url;
    }

    public function scopeCategory($query, $category) {
        return $query->where('asset_category', $category);
    }

    public function scopePartNumber($query, $partNumber) {
        return $query->where('asset_category', 'part')->where('name', $partNumber)->orderBy('date_created', 'DESC')->take(1);
    }

//    public function scopeContentType($query, $type) {
//        return $query->where('content_type', $type);
//    }

    protected static function boot() {
        parent::boot();

        static::deleted(function ($webAsset) {
            Storage::disk('assets')->delete($webAsset->full_key);
        });
    }


}