<?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;
use App\Events\IGPProcessed;

class Grn extends Model
{
	use LogsActivity, HasStatusManagement;

	protected $table = 'good_received_notes';

	protected $fillable = [
		'grn_number',
		'purchase_order_id',
		'inward_gate_pass_id',
		'qc_id',
		'warehouse_id',
		'received_by_id',
		'received_date',
		'vehicle_no',
		'gate_pass_id',
		'status',
		'notes',
		'cancelled_by',
		'cancelled_reason',
		'cancelled_at'
	];

	protected $casts = [
		'received_date' => 'date',
		'cancelled_at' => 'datetime',
	];

	// Status constants
	const STATUS_PENDING_QC = 'pending_qc';
	const STATUS_ACCEPTED = 'accepted';
	const STATUS_REJECTED = 'rejected';
	const STATUS_PARTIAL = 'partial';
	const STATUS_CANCELLED = 'cancelled';

    public function vendor(): BelongsTo { return $this->belongsTo(Contact::class, 'contact_id'); }
	public function items(): HasMany { return $this->hasMany(GrnItem::class); }
	public function purchaseOrder(): BelongsTo { return $this->belongsTo(PurchaseOrder::class); }
	public function warehouse(): BelongsTo { return $this->belongsTo(Warehouse::class); }
	public function receivedBy(): BelongsTo { return $this->belongsTo(User::class, 'received_by_id'); }
	public function gatePass(): BelongsTo { return $this->belongsTo(GatePass::class); }
	public function inwardGatePass(): BelongsTo { return $this->belongsTo(GatePass::class, 'inward_gate_pass_id'); }
	public function qcs(): HasMany { return $this->hasMany(Qc::class); }
	public function qc(): BelongsTo { return $this->belongsTo(Qc::class); }
	public function cancelledBy(): BelongsTo { return $this->belongsTo(Contact::class, 'cancelled_by'); }

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

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

	protected function getCancellableStatuses(): array
	{
		return [self::STATUS_ACCEPTED, self::STATUS_REJECTED, self::STATUS_PARTIAL];
	}

	protected function getConfirmedStatuses(): array
	{
		return [self::STATUS_PENDING_QC, self::STATUS_ACCEPTED, self::STATUS_PARTIAL];
	}

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

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

	/**
	 * Check if GRN can be cancelled (not already posted)
	 */
	public function canCancel(): bool
	{
		return parent::canCancel() && $this->status !== self::STATUS_POSTED;
	}

	/**
	 * Check if GRN is awaiting QC
	 */
	public function isPendingQc(): bool
	{
		return $this->status === self::STATUS_PENDING_QC;
	}

	/**
	 * Check if GRN has been QC'd
	 */
	public function hasQc(): bool
	{
		return $this->qcs()->exists();
	}

	// Scopes
	public function scopePendingQc($query)
	{
		return $query->where('status', self::STATUS_PENDING_QC);
	}

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

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

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

	// Helper methods
	public function getStatusBadgeAttribute()
	{
		$statusMap = [
			self::STATUS_PENDING_QC => 'warning',
			self::STATUS_ACCEPTED => 'success',
			self::STATUS_REJECTED => 'danger',
			self::STATUS_PARTIAL => 'info',
			self::STATUS_CANCELLED => 'dark',
		];

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

	public function getTotalReceivedQtyAttribute()
	{
		return $this->items()->sum('received_quantity');
	}

	public function getTotalAcceptedQtyAttribute()
	{
		return $this->items()->sum('accepted_quantity');
	}

	public function getTotalRejectedQtyAttribute()
	{
		return $this->items()->sum('rejected_quantity');
	}

	public function getReceiptProgressAttribute()
	{
		$ordered = $this->purchaseOrder ? $this->purchaseOrder->total_ordered_qty : 0;
		$received = $this->total_received_qty;

		if ($ordered == 0) return 0;
		return min(100, round(($received / $ordered) * 100, 2));
	}

	public function getCanBePostedAttribute()
	{
		return in_array($this->status, [self::STATUS_ACCEPTED, self::STATUS_PARTIAL]) &&
			   $this->qcs()->where('status', 'completed')->exists();
	}

	public function getCanBeQcAttribute()
	{
		return $this->status === self::STATUS_AWAITING_QC && !$this->qcs()->exists();
	}

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