<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
use App\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\DB;

class AssetHistory extends Model
{
    use HasFactory;

    protected $guarded = [];
    protected $actions = ['moved', 'created', 'status_updated', 'returned', 'linked']; //This is just for documentation for now

    public function getCreatedAtAttribute()
    {
        $date = $this->attributes['created_at'];
        $varDate = Carbon::createFromFormat('Y-m-d H:i:s', $date);

        if ($varDate->isToday()) {
            return " Today at " . $varDate->format('g:i:s A');
        } elseif ($varDate->isYesterday()) {
            return " Yesterday at " . $varDate->format('g:i:s A');
        }

        return $varDate->format('F \ j Y \a\t g:i:s A');
    }

    public function getCreatedDateLabelAttribute()
    {

        $varDate = Carbon::createFromFormat('Y-m-d H:i:s', $this->attributes['created_at']);
        return $varDate->format('m/d/Y H:i:s A');
    }

    public function getCreatedDateAttribute()
    {
        return parse_date_from_db_datetime($this->attributes['created_at']);
    }

    /**
     * Get the formatted updated_at attribute.
     *
     * @return string
     */
    public function getUpdatedAtAttribute()
    {
        return parse_date_from_db_datetime($this->attributes['updated_at']);
    }

    public function user()
    {
        return $this->belongsTo('App\User');
    }
    public function asset()
    {
        return $this->belongsTo('App\Models\Asset');
    }

    public function setOldLoanerReturnDateAttribute($date)
    {
        return $this->attributes['old_loaner_return_date'] =  convert_to_db_date($date);
    }

    public function setNewLoanerReturnDateAttribute($date)
    {
        return $this->attributes['new_loaner_return_date'] =  convert_to_db_date($date);
    }

    public function setOldLoanerRetentionDateAttribute($date)
    {
        return $this->attributes['old_loaner_retention_date'] =  convert_to_db_date($date);
    }

    public function setNewLoanerRetentionDateAttribute($date)
    {
        return $this->attributes['new_loaner_retention_date'] =  convert_to_db_date($date);
    }


    public function getEndOfLifeDateAttribute($date)
    {
        return parse_date_from_db_date($date);
    }

    public function getPersonNameAttribute($new_user_id)
    {

        return $new_user_id;
    }

    public function getNewPersonNameAttribute($new_user_id)
    {
        if ($new_user_id != null) {
            return User::find($new_user_id)->first_name;
        } else {
            return $new_user_id;
        }
    }

    public function scopeLocationHistoryAll($query)
    {
        return $query->whereIn('action', ['created', 'moved', 'returned', 'status_updated', 'assetTag_updated', 'location_updated'])
            ->orderBy('created_at', 'DESC');
    }

    public  function  scopeWritemessage($historydata)
    {
        if ($historydata->action == 'returned' || $historydata->action == 'created') {
            return ucfirst($historydata->action) . " <a href='#'>" . $historydata->asset->asset_tag . "</a>";
        } else if ($historydata->action == 'linked') {
            return ucfirst($historydata->action) . " " . $historydata->old_value . " to " . $historydata->new_value;
        } else if ($historydata->action == 'moved') {
            return ucfirst($historydata->action) . " from <i>" . $historydata->old_value . "</i> to <i>" . $historydata->new_value . "</i>";
        }
        return  "";
    }

    /**
     * Relation for new user
     */
    public function newUser()
    {
        return $this->belongsTo('App\User', 'new_user_id', 'id');
    }

    /**
     * Relation for new location
     */
    public function newLocation()
    {
        return $this->belongsTo('App\Models\Location', 'new_location_id', 'id');
    }

    /**
     * relation with Location table
     */
    public function oldLocation()
    {
        return $this->belongsTo('App\Models\Location', 'old_location_id');
    }

    /**
     * It returns the date of redeployment of assets that returned from a terminated user. (here check the assethistory created date is greater than the asset history created date of  asset returned from terminated user)
     * @param query The query object that is being modified.
     * @return The number of times an asset has been redeployed.
     */
    public function scopeRedeployedDate($query)
    {
        $assignedOrLoanedStatusIds = AssetStatus::whereIn('slug', ['assigned', 'loan_or_test'])->pluck('id')->toArray();

        return $query->addSelect(DB::raw("(SELECT created_at FROM asset_histories AS a2 WHERE asset_histories.asset_id = a2.asset_id AND new_asset_status_id IN (" . implode(',', $assignedOrLoanedStatusIds) . ") AND created_at >= asset_histories.created_at ORDER BY created_at DESC limit 1) AS redeployedDate"));
    }

    /**
     * It returns all assets that have been returned from a terminated user
     *
     * @param query The query builder instance.
     */
    public function scopeReturnedAssetsFromTerminatedUser($query)
    {
        return $query->whereHas('oldUser', function ($query) {
            $query->where('status', '!=', 1)
                ->whereColumn('terminated_date', '<=', 'asset_histories.created_at');
        });
    }

    /**
     * Relation for old user
     */
    public function oldUser()
    {
        return $this->belongsTo('App\User', 'old_user_id', 'id');
    }

    /**
     * Relation for old status
     */
    public function oldStatus()
    {
        return $this->belongsTo('App\Models\AssetStatus', 'old_asset_status_id', 'id');
    }

    /**
     * It returns the count of redeployment of assets that returned from a terminated user. (here check the assethistory created date is greater than the asset history created date of  asset returned from terminated user)
     * @param query The query object that is being modified.
     * @return The number of times an asset has been redeployed.
     */
    public function scopeRedeployedAssetCount($query)
    {
        $assignedOrLoanedStatusIds = AssetStatus::whereIn('slug', ['assigned', 'loan_or_test'])->pluck('id')->toArray();

        return $query->addSelect(DB::raw("(SELECT COUNT(DISTINCT a2.asset_id) FROM asset_histories AS a2 WHERE asset_histories.asset_id = a2.asset_id AND new_asset_status_id IN (" . implode(',', $assignedOrLoanedStatusIds) . ") AND created_at >= asset_histories.created_at GROUP BY a2.asset_id  ORDER BY created_at DESC) AS redeployedAssetCount"));
    }

    /**
     * Relation for new status
     */
    public function newStatus()
    {
        return $this->belongsTo('App\Models\AssetStatus', 'new_asset_status_id', 'id');
    }

    /**
     * Relation for assigned assets based on user id
     */
    public function assignedUserAsset()
    {
        return $this->belongsTo('App\Models\Asset', 'new_user_id', 'user_id')->where('new_value', 'Assigned');
    }

    /**
     * makes query to filter status update history by Retriever API
     */
    public function scopeRetrieverAssetUpdate($query)
    {
        return $query->where([
            'action' => 'status_updated',
            'created_by' => config('retriever.display_name'),
        ])->latest();
    }
}
