<?php

namespace Modules\User\Models;

use App\Services\Upload\FileService;
use DB;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Facades\Auth;
use Modules\Canteen\Models\Canteen;
use Modules\Order\Models\Order;
use Modules\Product\Models\Favorite;
use Modules\Product\Models\Product;
use Modules\School\Models\School;
use Modules\User\Models\Module;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Modules\User\Services\AccountService;
use Modules\User\Enums\UserRoleEnum;


/**
 * @property mixed role
 * @property mixed Modules
 */
class User extends Authenticatable
{
    use Notifiable;
    use SoftDeletes;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'email',
        'id_number',
        'last_name',
        'gender',
        'phone',
        'photo',
        'password',
        'role',
        'wallet',
        'cash_per_day',
        'api_token',
        'device_token',
        'language',
        'parent_id',
        'school_id',
        'bracelet_token',
        'active',
        'canteen_id'
    ];

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

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    /**
     * Get the Modules of this user
     * @return BelongsToMany
     */
    public function modules(): BelongsToMany
    {
        return $this->belongsToMany(Module::class, 'user_modules');
    }
    public function canteen_modules(): BelongsToMany
    {
        return $this->belongsToMany(CanteenModule::class, 'user_canteen_modules');
    }

    /**
     * Check if the user can access a module
     * @param string, module name
     * @return bool
     */
    public function hasModule($module): bool
    {
        if ($this->modules->contains('path', $module)) {
            return true;
        }
        return false;
    }

    public function parent()
    {
        return $this->belongsTo(self::class, 'parent_id')->withTrashed();
    }
    public function blockedProducts(): BelongsToMany
    {
        return $this->belongsToMany(Product::class, 'child_block_products', 'user_id', 'product_id');
    }

    public function school()
    {
        return $this->belongsTo(School::class, 'school_id')->withTrashed();
    }
    public function canteen()
    {
        return $this->belongsTo(Canteen::class, 'canteen_id')->withTrashed();
    }

    /**
     * Check if the user can access a module
     * @param string, module name
     * @return bool
     */
    public function canAccess($module)
    {
        if ($this->role == 'super_admin') {
            return true;
        } else {
            return $this->hasModule($module);
        }
        return false;
    }

    public function childs()
    {
        return $this->hasMany(Self::class,'parent_id')->where('role',UserRoleEnum::CHILD->value);
    }

    public function favorited($product_id)
    {
        $account = new AccountService();
        $account = $account->getAccount();
        $favorite = $this->hasOne(Favorite::class)->where('status', $account['status'])->where('user_id', Auth::user()->id)->where('product_id', $product_id)->first();
        return $favorite;
    }
    public function verifications(): HasOne
    {
        return $this->hasOne(Verification::class);
    }

    public function setPasswordAttribute($value)
    {
        if ($value) {
            $this->attributes['password'] = bcrypt($value);
        } else {
            $this->attributes['password'] = $this->password;
        }
    }
    public function setPhotoAttribute($value)
    {
        if ($value) {
            if (is_string($value)) {
                $this->attributes['photo'] = $value;
            } else {
                $photo = FileService::uploadImage($value);
                $this->attributes['photo'] = $photo;
            }
        } else {
            if(request()->method() == 'post')
            {
                if($this->role == UserRoleEnum::PARENT->value)
                {
                    $this->attributes['photo'] = 'users/Parent.png';
                }
                elseif($this->role == UserRoleEnum::CHILD->value)
                {
                    $this->attributes['photo'] = 'users/Student.png';
                }
                elseif($this->role == UserRoleEnum::CANTEEN->value)
                {
                    $this->attributes['photo'] = 'users/Market.png';
                }
                else
                {
                    $this->attributes['photo'] =  'logo.png';
                }
            }
            else
            {
                $this->attributes['photo'] =  $this->photo;
            }
        }
    }
    public function remainingCashToday()
    {

        $spentToday = DB::table('orders')
            ->where('child_id', $this->id)
            ->whereDate('created_at', now()->toDateString())
            ->sum('total');

        $remainingPoints = $this->points_per_day - $spentToday;

        return $remainingPoints > 0 ? $remainingPoints : 0;
    }
    public function orders()
    {
        return $this->hasMany(Order::class, 'canteen_id','canteen_id');
    }

    public function totalOrders($canteen_id)
    {
        return $this->orders()->where('canteen_id', $canteen_id)->count();
    }
}
