<?php

namespace App\Models;

use App\Models\Traits\HasAuditFields;
use App\Models\Traits\HasScopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Grn extends Model
{
    use HasScopes, SoftDeletes, HasAuditFields;

    protected $table = 'grns';

    /**
     * Status constants
     */
    public const STATUS_DRAFT = 'draft';
    public const STATUS_RECEIVED = 'received';
    public const STATUS_INSPECTED = 'inspected';
    public const STATUS_ACCEPTED = 'accepted';
    public const STATUS_REJECTED = 'rejected';

    /**
     * Custom column mapping for HasScopes trait
     */
    protected string $dateColumn = 'grn_date';

    protected $fillable = [
        'grn_no',
        'grn_date',
        'order_no',
        'order_date',
        'order_ref_no',
        'purchase_invoice_id',
        'company_name',
        'company_address',
        'company_gst',
        'company_phone',
        'company_email',
        'quotation_no',
        'quotation_date',
        'rfq_no',
        'rfq_date',
        'part_no',
        'project_material_no',
        'drawing_no',
        'drawing_rev',
        'description',
        'product_type',
        'challan_file',
        'status',
        'created_by',
        'updated_by',
    ];

    protected $casts = [
        'grn_date' => 'date',
        'order_date' => 'date',
        'quotation_date' => 'date',
        'rfq_date' => 'date',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    // ──────────────────────────────────────────────────────────────────────────
    // RELATIONSHIPS
    // ──────────────────────────────────────────────────────────────────────────

    /**
     * GRN products/items
     */
    public function products()
    {
        return $this->hasMany(GrnProductDetail::class, 'grn_id');
    }

    /**
     * Purchase invoice associated with this GRN
     */
    public function purchaseInvoice()
    {
        return $this->belongsTo(Purchase::class, 'purchase_invoice_id');
    }

    /**
     * Related purchase order
     */
    public function purchaseOrder()
    {
        return $this->belongsTo(PurchaseOrder::class, 'order_no', 'purchase_order_no');
    }

    /**
     * GRN items (alternate relationship name)
     */
    public function items()
    {
        return $this->hasMany(GrnItem::class, 'grn_id');
    }

    // ──────────────────────────────────────────────────────────────────────────
    // SCOPES
    // ──────────────────────────────────────────────────────────────────────────

    /**
     * Filter by received status
     */
    public function scopeReceived(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_RECEIVED);
    }

    /**
     * Filter by inspected status
     */
    public function scopeInspected(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_INSPECTED);
    }

    /**
     * Filter by accepted status
     */
    public function scopeAccepted(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_ACCEPTED);
    }

    /**
     * Filter by rejected status
     */
    public function scopeRejectedItems(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_REJECTED);
    }

    /**
     * Filter pending inspection
     */
    public function scopePendingInspection(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_RECEIVED);
    }

    /**
     * Search by GRN number or order
     */
    public function scopeSearchGrn(Builder $query, string $term): Builder
    {
        return $query->where(function ($q) use ($term) {
            $q->where('grn_no', 'LIKE', "%{$term}%")
              ->orWhere('order_no', 'LIKE', "%{$term}%")
              ->orWhere('order_ref_no', 'LIKE', "%{$term}%")
              ->orWhere('company_name', 'LIKE', "%{$term}%");
        });
    }

    /**
     * Filter GRNs with challan
     */
    public function scopeWithChallan(Builder $query): Builder
    {
        return $query->whereNotNull('challan_file');
    }

    // ──────────────────────────────────────────────────────────────────────────
    // ACCESSORS & HELPERS
    // ──────────────────────────────────────────────────────────────────────────

    /**
     * Get all valid statuses
     */
    public static function getStatuses(): array
    {
        return [
            self::STATUS_DRAFT,
            self::STATUS_RECEIVED,
            self::STATUS_INSPECTED,
            self::STATUS_ACCEPTED,
            self::STATUS_REJECTED,
        ];
    }

    /**
     * Check if GRN is accepted
     */
    public function isAccepted(): bool
    {
        return $this->status === self::STATUS_ACCEPTED;
    }

    /**
     * Check if needs inspection
     */
    public function needsInspection(): bool
    {
        return $this->status === self::STATUS_RECEIVED;
    }

    /**
     * Get total received quantity
     */
    public function getTotalReceivedQuantity(): float
    {
        return $this->products()->sum('received_qty') ?? 0;
    }

    /**
     * Get total accepted quantity
     */
    public function getTotalAcceptedQuantity(): float
    {
        return $this->products()->sum('accepted_qty') ?? 0;
    }

    /**
     * Get total rejected quantity
     */
    public function getTotalRejectedQuantity(): float
    {
        return $this->products()->sum('rejected_qty') ?? 0;
    }

    /**
     * Check if has challan file
     */
    public function hasChallan(): bool
    {
        return !empty($this->challan_file);
    }
}
