<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
use App\Traits\HasStatusManagement;

class PurchaseRequest extends Model
{
	use LogsActivity, HasStatusManagement;

	protected $table = 'purchase_requests';

	protected $fillable = [
		'pr_number',
		'title',
		'description',
		'user_id',
		'status',
		'required_date',
		'expected_date',
		'priority',
		'approved_by',
		'approved_at',
		'approval_notes',
		'rejected_by',
		'rejected_at',
		'rejection_reason',
		'estimated_total',
		'currency',
		'department',
		'project_code',
		'unit_code',
		'remarks',
	];

	protected $casts = [
		'required_date' => 'date',
		'approved_at' => 'datetime',
		'rejected_at' => 'datetime',
		'estimated_total' => 'decimal:4',
	];

	// Status constants - matches database enum
	const STATUS_DRAFT = 'draft';
	const STATUS_SUBMITTED = 'submitted';
	const STATUS_APPROVED = 'approved';
	const STATUS_REJECTED = 'rejected';

	public function items(): HasMany {
        return $this->hasMany(PurchaseRequestItem::class);
    }
	public function user(): BelongsTo { return $this->belongsTo(User::class); }

	// Approval workflow relationships
	public function approvedBy(): BelongsTo
	{
		return $this->belongsTo(User::class, 'approved_by');
	}

	public function rejectedBy(): BelongsTo
	{
		return $this->belongsTo(User::class, 'rejected_by');
	}

	public function purchaseOrders(): HasMany
	{
		return $this->hasMany(PurchaseOrder::class);
	}

	/**
	 * Override status management methods for PurchaseRequest
	 */
	protected function getEditableStatuses(): array
	{
		return [self::STATUS_DRAFT];
	}

	protected function getDeletableStatuses(): array
	{
		return [self::STATUS_DRAFT];
	}

	protected function getCancellableStatuses(): array
	{
		return [self::STATUS_DRAFT, self::STATUS_SUBMITTED, self::STATUS_APPROVED];
	}

	protected function getConfirmedStatuses(): array
	{
		return [self::STATUS_SUBMITTED, self::STATUS_APPROVED];
	}

	protected function getCompletedStatuses(): array
	{
		return [self::STATUS_CONVERTED_TO_PO, self::STATUS_REJECTED, self::STATUS_CANCELLED];
	}

	/**
	 * Check if PR can be deleted (no PO dependencies)
	 */
	public function canDelete(): bool
	{
		return parent::canDelete() && $this->purchaseOrders()->count() === 0;
	}

	/**
	 * Check if PR can be cancelled (not already converted to PO)
	 */
	public function canCancel(): bool
	{
		return parent::canCancel() && $this->status !== self::STATUS_CONVERTED_TO_PO;
	}

	// Status-based scopes
	public function scopeDraft($query)
	{
		return $query->where('status', self::STATUS_DRAFT);
	}

	public function scopeSubmitted($query)
	{
		return $query->where('status', self::STATUS_SUBMITTED);
	}

	public function scopeApproved($query)
	{
		return $query->where('status', self::STATUS_APPROVED);
	}

	public function scopeRejected($query)
	{
		return $query->where('status', self::STATUS_REJECTED);
	}

	public function scopePendingApproval($query)
	{
		return $query->where('status', self::STATUS_SUBMITTED);
	}

	public function scopeByPriority($query, $priority)
	{
		return $query->where('priority', $priority);
	}

	public function scopeByDepartment($query, $department)
	{
		return $query->where('department', $department);
	}

	public function scopeByProject($query, $projectCode)
	{
		return $query->where('project_code', $projectCode);
	}

	public function scopeByDateRange($query, $fromDate, $toDate)
	{
		return $query->whereBetween('required_date', [$fromDate, $toDate]);
	}

	public function scopeOverdue($query)
	{
		return $query->where('required_date', '<', now()->toDateString())
					->whereNotIn('status', [self::STATUS_COMPLETED, self::STATUS_REJECTED]);
	}

	// Helper methods
	public function getStatusBadgeAttribute()
	{
		$statusMap = [
			self::STATUS_DRAFT => 'secondary',
			self::STATUS_SUBMITTED => 'info',
			self::STATUS_APPROVED => 'success',
			self::STATUS_REJECTED => 'danger',
			self::STATUS_CONVERTED_TO_PO => 'primary',
		];

		$class = $statusMap[$this->status] ?? 'secondary';
		return '<span class="badge bg-' . $class . '">' . ucwords(str_replace('_', ' ', $this->status)) . '</span>';
	}

	public function getPriorityBadgeAttribute()
	{
		$priorityMap = [
			'low' => 'secondary',
			'medium' => 'info',
			'high' => 'warning',
			'urgent' => 'danger',
		];

		$class = $priorityMap[$this->priority] ?? 'secondary';
		return '<span class="badge bg-' . $class . '">' . ucfirst($this->priority) . '</span>';
	}

	public function getIsOverdueAttribute()
	{
		return $this->required_date < now()->toDateString() &&
			   !in_array($this->status, [self::STATUS_COMPLETED, self::STATUS_REJECTED]);
	}

	public function getCanBeConvertedToPoAttribute()
	{
		return $this->status === self::STATUS_APPROVED && $this->purchaseOrders()->count() === 0;
	}

	public function getActivitylogOptions(): LogOptions
	{
		return LogOptions::defaults()
			->useLogName('purchase_request')
			->logFillable()
			->logOnlyDirty()
			->dontSubmitEmptyLogs();
	}
}
