<?php

/**
 * Created by Reliese Model.
 */

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Notifications\Notifiable;

/**
 * Class User
 * 
 * @property int $id
 * @property int|null $company_id
 * @property int|null $branch_id
 * @property string $name
 * @property string $email
 * @property string|null $phone
 * @property string|null $job_title
 * @property Carbon|null $email_verified_at
 * @property string $password
 * @property string|null $two_factor_secret
 * @property string|null $two_factor_recovery_codes
 * @property Carbon|null $two_factor_confirmed_at
 * @property bool $two_factor_enabled
 * @property string|null $remember_token
 * @property bool $is_active
 * @property Carbon|null $created_at
 * @property Carbon|null $updated_at
 * @property string|null $deleted_at
 * @property string|null $position
 * @property Carbon|null $last_login_at
 * 
 * @property Branch|null $branch
 * @property Company|null $company
 * @property Collection|ActivityLog[] $activity_logs
 * @property Collection|BarcodeTemplate[] $barcode_templates
 * @property Collection|CustomerInteraction[] $customer_interactions
 * @property Collection|CustomerSurvey[] $customer_surveys
 * @property Collection|Customer[] $customers
 * @property Collection|Elevator[] $elevators
 * @property Collection|FinancialReport[] $financial_reports
 * @property Collection|InstallationProject[] $installation_projects
 * @property Collection|InventoryTransaction[] $inventory_transactions
 * @property Collection|InventoryValuation[] $inventory_valuations
 * @property Collection|Invoice[] $invoices
 * @property Collection|LoginHistory[] $login_histories
 * @property Collection|MaintenanceContract[] $maintenance_contracts
 * @property Collection|MaintenanceLog[] $maintenance_logs
 * @property Collection|MaintenanceSchedule[] $maintenance_schedules
 * @property Collection|MarketingCampaign[] $marketing_campaigns
 * @property Collection|Notification[] $notifications
 * @property Collection|Opportunity[] $opportunities
 * @property Collection|Payment[] $payments
 * @property Collection|PayrollItem[] $payroll_items
 * @property Collection|Payroll[] $payrolls
 * @property Collection|ProjectChecklistItem[] $project_checklist_items
 * @property Collection|ProjectChecklist[] $project_checklists
 * @property Collection|ProjectDocument[] $project_documents
 * @property Collection|ProjectExpense[] $project_expenses
 * @property Collection|ProjectInventoryRequest[] $project_inventory_requests
 * @property Collection|ProjectIssue[] $project_issues
 * @property Collection|ProjectPayment[] $project_payments
 * @property Collection|ProjectPhase[] $project_phases
 * @property Collection|ProjectReport[] $project_reports
 * @property Collection|ProjectRisk[] $project_risks
 * @property Collection|ProjectTask[] $project_tasks
 * @property Collection|ProjectTeamMember[] $project_team_members
 * @property Collection|PurchaseOrder[] $purchase_orders
 * @property Collection|Role[] $roles
 * @property Collection|SalaryPolicy[] $salary_policies
 * @property Collection|SupplierEvaluation[] $supplier_evaluations
 * @property Collection|TaxBracket[] $tax_brackets
 * @property Collection|TaxReport[] $tax_reports
 * @property Collection|TwoFactorToken[] $two_factor_tokens
 * @property Collection|Permission[] $permissions
 *
 * @package App\Models
 */
class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract
{
	use SoftDeletes, Authenticatable, Authorizable, CanResetPassword, Notifiable;
	protected $table = 'users';

	/**
	 * The "booted" method of the model.
	 *
	 * @return void
	 */
	protected static function booted()
	{
		static::addGlobalScope('active', function ($builder) {
			// تحويل أي استعلام يستخدم عمود 'active' إلى 'is_active'
			$builder->withoutGlobalScope('active')->when(
				$builder->getQuery()->wheres && is_array($builder->getQuery()->wheres),
				function ($query) {
					foreach ($query->getQuery()->wheres as $key => $where) {
						if (isset($where['column']) && $where['column'] === 'active') {
							$query->getQuery()->wheres[$key]['column'] = 'is_active';
						}
					}
				}
			);
		});
	}

	protected $casts = [
		'company_id' => 'int',
		'branch_id' => 'int',
		'email_verified_at' => 'datetime',
		'two_factor_confirmed_at' => 'datetime',
		'two_factor_enabled' => 'bool',
		'is_active' => 'bool',
		'last_login_at' => 'datetime'
	];

	protected $hidden = [
		'password',
		'two_factor_secret',
		'remember_token'
	];

	protected $fillable = [
		'company_id',
		'branch_id',
		'name',
		'email',
		'phone',
		'job_title',
		'email_verified_at',
		'password',
		'two_factor_secret',
		'two_factor_recovery_codes',
		'two_factor_confirmed_at',
		'two_factor_enabled',
		'remember_token',
		'is_active',
		'position',
		'last_login_at'
	];

	public function branch()
	{
		return $this->belongsTo(Branch::class);
	}

	public function company()
	{
		return $this->belongsTo(Company::class);
	}

	public function activity_logs()
	{
		return $this->hasMany(ActivityLog::class);
	}

	public function barcode_templates()
	{
		return $this->hasMany(BarcodeTemplate::class, 'updated_by');
	}

	public function customer_interactions()
	{
		return $this->hasMany(CustomerInteraction::class);
	}

	public function customer_surveys()
	{
		return $this->hasMany(CustomerSurvey::class);
	}

	public function customers()
	{
		return $this->hasMany(Customer::class);
	}

	public function elevators()
	{
		return $this->hasMany(Elevator::class);
	}

	public function financial_reports()
	{
		return $this->hasMany(FinancialReport::class, 'created_by');
	}

	public function installation_projects()
	{
		return $this->hasMany(InstallationProject::class, 'project_manager_id');
	}

	public function inventory_transactions()
	{
		return $this->hasMany(InventoryTransaction::class, 'created_by');
	}

	public function inventory_valuations()
	{
		return $this->hasMany(InventoryValuation::class, 'created_by');
	}

	public function invoices()
	{
		return $this->hasMany(Invoice::class);
	}

	public function login_histories()
	{
		return $this->hasMany(LoginHistory::class);
	}

	public function maintenance_contracts()
	{
		return $this->hasMany(MaintenanceContract::class);
	}

	public function maintenance_logs()
	{
		return $this->hasMany(MaintenanceLog::class, 'technician_id');
	}

	public function maintenance_schedules()
	{
		return $this->hasMany(MaintenanceSchedule::class);
	}

	public function marketing_campaigns()
	{
		return $this->hasMany(MarketingCampaign::class);
	}

	public function notifications()
	{
		return $this->hasMany(Notification::class);
	}

	public function opportunities()
	{
		return $this->hasMany(Opportunity::class);
	}

	public function payments()
	{
		return $this->hasMany(Payment::class, 'created_by');
	}

	public function payroll_items()
	{
		return $this->hasMany(PayrollItem::class, 'updated_by');
	}

	public function payrolls()
	{
		return $this->hasMany(Payroll::class, 'updated_by');
	}

	public function project_checklist_items()
	{
		return $this->hasMany(ProjectChecklistItem::class, 'completed_by');
	}

	public function project_checklists()
	{
		return $this->hasMany(ProjectChecklist::class, 'created_by');
	}

	public function project_documents()
	{
		return $this->hasMany(ProjectDocument::class, 'uploaded_by');
	}

	public function project_expenses()
	{
		return $this->hasMany(ProjectExpense::class, 'recorded_by');
	}

	public function project_inventory_requests()
	{
		return $this->hasMany(ProjectInventoryRequest::class, 'requested_by');
	}

	public function project_issues()
	{
		return $this->hasMany(ProjectIssue::class, 'reported_by');
	}

	public function project_payments()
	{
		return $this->hasMany(ProjectPayment::class, 'recorded_by');
	}

	public function project_phases()
	{
		return $this->hasMany(ProjectPhase::class, 'responsible_user_id');
	}

	public function project_reports()
	{
		return $this->hasMany(ProjectReport::class, 'created_by');
	}

	public function project_risks()
	{
		return $this->hasMany(ProjectRisk::class, 'responsible_user_id');
	}

	public function project_tasks()
	{
		return $this->hasMany(ProjectTask::class, 'assigned_to');
	}

	public function project_team_members()
	{
		return $this->hasMany(ProjectTeamMember::class);
	}

	public function purchase_orders()
	{
		return $this->hasMany(PurchaseOrder::class, 'created_by');
	}

	public function roles()
	{
		return $this->belongsToMany(Role::class)
			->withPivot('id')
			->withTimestamps();
	}

	public function salary_policies()
	{
		return $this->hasMany(SalaryPolicy::class, 'updated_by');
	}

	public function supplier_evaluations()
	{
		return $this->hasMany(SupplierEvaluation::class, 'created_by');
	}

	public function tax_brackets()
	{
		return $this->hasMany(TaxBracket::class, 'updated_by');
	}

	public function tax_reports()
	{
		return $this->hasMany(TaxReport::class, 'created_by');
	}

	public function two_factor_tokens()
	{
		return $this->hasMany(TwoFactorToken::class);
	}

	public function permissions()
	{
		return $this->belongsToMany(Permission::class, 'user_permission')
			->withPivot('id', 'granted', 'source', 'expires_at', 'deleted_at')
			->withTimestamps();
	}

	/**
	 * Custom implementation to check if user has a specific permission
	 *
	 * @param string $permission
	 * @param mixed $arguments
	 * @return bool
	 */
	public function hasPermission($permission)
	{
		// التحقق من وجود دور "admin" للمستخدم
		foreach ($this->roles as $role) {
			if ($role->slug === 'admin') {
				return true;
			}
		}

		// First check if user has direct permission
		$directPermission = $this->permissions()
			->where('slug', $permission)
			->wherePivot('granted', true)
			->where(function ($query) {
				$query->whereNull('user_permission.expires_at')
					->orWhere('user_permission.expires_at', '>', now());
			})
			->first();

		if ($directPermission) {
			return true;
		}

		// Then check if any of user's roles has the permission
		foreach ($this->roles as $role) {
			$rolePermission = $role->permissions()
				->where('slug', $permission)
				->first();

			if ($rolePermission) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Check if user has a specific role
	 *
	 * @param string $roleName
	 * @return bool
	 */
	public function hasRole($roleName)
	{
		return $this->roles()
			->where(function($query) use ($roleName) {
				$query->where('name', $roleName)
					->orWhere('slug', $roleName);
			})
			->exists();
	}

	/**
	 * Check if user has any of the specified roles
	 *
	 * @param array|string $roleNames
	 * @return bool
	 */
	public function hasAnyRole($roleNames)
	{
		if (!is_array($roleNames)) {
			$roleNames = [$roleNames];
		}

		return $this->roles()
			->where(function($query) use ($roleNames) {
				$query->whereIn('name', $roleNames)
					->orWhereIn('slug', $roleNames);
			})
			->exists();
	}

	/**
	 * Alias for hasPermission to maintain compatibility with Laravel's Gate
	 *
	 * @param string $permission
	 * @param mixed $arguments
	 * @return bool
	 */
	public function can($permission, $arguments = [])
	{
		return $this->hasPermission($permission);
	}

	/**
	 * Alias for hasPermission to maintain compatibility with Spatie Permission
	 *
	 * @param string $permission
	 * @return bool
	 */
	public function hasPermissionTo($permission)
	{
		return $this->hasPermission($permission);
	}

	/**
	 * Check if user is a system admin (admin or super_admin slug)
	 *
	 * @return bool
	 */
	public function isSystemAdmin()
	{
		return $this->roles()->whereIn('slug', ['admin', 'super_admin'])->exists();
	}

	/**
	 * Check if user is a super admin
	 *
	 * @return bool
	 */
	public function isSuperAdmin()
	{
		// التحقق من وجود دور نظامي للمستخدم
		return $this->roles()->where('is_system_role', true)->exists();
	}

	/**
	 * الحصول على الصلاحيات المباشرة للمستخدم
	 *
	 * @return \Illuminate\Database\Eloquent\Relations\HasMany
	 */
	public function directPermissions()
	{
		return $this->hasMany(UserPermission::class);
	}

	/**
	 * الحصول على جميع الصلاحيات للمستخدم (من الأدوار والصلاحيات المباشرة)
	 *
	 * @return \Illuminate\Database\Eloquent\Collection
	 */
	public function getAllPermissions()
	{
		$rolePermissions = collect();

		// جمع الصلاحيات من الأدوار
		foreach ($this->roles as $role) {
			$rolePermissions = $rolePermissions->merge($role->permissions);
		}

		// إضافة الصلاحيات المباشرة
		$directPermissions = $this->permissions;

		// دمج الصلاحيات وإزالة التكرار
		return $rolePermissions->merge($directPermissions)->unique('id');
	}

	/**
	 * العلاقة مع الموظف
	 * 
	 * @return \Illuminate\Database\Eloquent\Relations\HasOne
	 */
	public function employee()
	{
		return $this->hasOne(\App\Models\HRM\Employee::class);
	}
}
