<?php

namespace App\Models\Warehouse;

use App\Models\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;

class MaterialTransferIssue extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'transfer_issue_number',
        'transfer_request_id',
        'issue_date',
        'transfer_type',
        'transfer_instructions',
        'dispatched_by',
        'dispatched_at',
        'dispatch_vehicle',
        'driver_name',
        'driver_contact',
        'received_by',
        'received_at',
        'receipt_notes',
        'status',
        'requires_inspection',
        'inspected_by',
        'inspected_at',
        'inspection_status',
        'inspection_notes',
        'delivery_note_path',
        'attached_documents',
        'total_transferred_value',
        'total_items_transferred'
    ];

    protected $casts = [
        'issue_date' => 'date',
        'dispatched_at' => 'datetime',
        'received_at' => 'datetime',
        'inspected_at' => 'datetime',
        'requires_inspection' => 'boolean',
        'attached_documents' => 'array',
        'total_transferred_value' => 'decimal:2',
        'total_items_transferred' => 'integer'
    ];

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($issue) {
            if (empty($issue->transfer_issue_number)) {
                $issue->transfer_issue_number = static::generateIssueNumber();
            }
        });

        static::saving(function ($issue) {
            // Recalculate totals from items
            if ($issue->exists && $issue->items()->exists()) {
                $issue->total_transferred_value = $issue->items()->sum('total_value');
                $issue->total_items_transferred = $issue->items()->count();
            }
        });
    }

    /**
     * Generate unique transfer issue number
     */
    public static function generateIssueNumber()
    {
        $year = now()->format('Y');
        $sequence = static::whereYear('created_at', $year)->count() + 1;
        return 'MTI-' . $year . '-' . str_pad($sequence, 4, '0', STR_PAD_LEFT);
    }

    /**
     * Relationships
     */
    public function transferRequest(): BelongsTo
    {
        return $this->belongsTo(MaterialTransferRequest::class, 'transfer_request_id');
    }

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

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

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

    public function items(): HasMany
    {
        return $this->hasMany(MaterialTransferIssueItem::class, 'transfer_issue_id');
    }

    /**
     * Through relationships for convenience
     */
    public function transferrerProject()
    {
        return $this->transferRequest->transferrerProject();
    }

    public function receiverProject()
    {
        return $this->transferRequest->receiverProject();
    }

    /**
     * Status Management
     */
    public function dispatch($userId, $vehicleInfo = [], $driverInfo = [])
    {
        $this->dispatched_by = $userId;
        $this->dispatched_at = now();
        $this->dispatch_vehicle = $vehicleInfo['vehicle'] ?? null;
        $this->driver_name = $driverInfo['name'] ?? null;
        $this->driver_contact = $driverInfo['contact'] ?? null;
        $this->status = 'dispatched';
        $this->save();

        // Update inventory for transferrer project
        $this->updateTransferrerInventory();
        $this->createStockMovements();
    }

    public function markInTransit()
    {
        $this->status = 'in_transit';
        $this->save();
    }

    public function receive($userId, $notes = null)
    {
        $this->received_by = $userId;
        $this->received_at = now();
        $this->receipt_notes = $notes;
        $this->status = $this->requires_inspection ? 'delivered' : 'completed';
        $this->save();

        // Update inventory for receiver project if no inspection required
        if (!$this->requires_inspection) {
            $this->updateReceiverInventory();
        }
    }

    public function completeInspection($userId, $inspectionStatus, $notes = null)
    {
        $this->inspected_by = $userId;
        $this->inspected_at = now();
        $this->inspection_status = $inspectionStatus;
        $this->inspection_notes = $notes;

        if ($inspectionStatus === 'passed') {
            $this->status = 'completed';
            $this->updateReceiverInventory();
        }

        $this->save();
    }

    /**
     * Inventory Updates
     */
    protected function updateTransferrerInventory()
    {
        foreach ($this->items as $item) {
            // Find and update project inventory
            $projectInventory = ProjectInventory::where('project_id', $this->transferRequest->transferrer_project_id)
                ->where('item_id', $item->item_id)
                ->first();

            if ($projectInventory) {
                $projectInventory->quantity_available -= $item->quantity_issued;
                $projectInventory->save();
            }
        }
    }

    protected function updateReceiverInventory()
    {
        foreach ($this->items as $item) {
            // Find or create project inventory
            $projectInventory = ProjectInventory::firstOrNew([
                'project_id' => $this->transferRequest->receiver_project_id,
                'item_id' => $item->item_id
            ]);

            $projectInventory->quantity_available += $item->quantity_received;
            $projectInventory->unit_price = $item->unit_price;
            $projectInventory->save();
        }
    }

    protected function createStockMovements()
    {
        foreach ($this->items as $item) {
            // Outbound movement for transferrer project
            StockMovement::create([
                'item_id' => $item->item_id,
                'movement_type' => 'project_transfer_out',
                'reference_type' => 'material_transfer_issue',
                'reference_id' => $this->id,
                'quantity_moved' => $item->quantity_issued,
                'division_id' => $this->transferRequest->transferrerProject->project_division_id,
                'user_id' => $this->dispatched_by,
                'notes' => "Transfer to {$this->transferRequest->receiverProject->project_name} - {$this->transfer_issue_number}"
            ]);

            // Inbound movement for receiver project (created when received)
            if ($this->status === 'completed') {
                StockMovement::create([
                    'item_id' => $item->item_id,
                    'movement_type' => 'project_transfer_in',
                    'reference_type' => 'material_transfer_issue',
                    'reference_id' => $this->id,
                    'quantity_moved' => $item->quantity_received,
                    'division_id' => $this->transferRequest->receiverProject->project_division_id,
                    'user_id' => $this->received_by,
                    'notes' => "Received from {$this->transferRequest->transferrerProject->project_name} - {$this->transfer_issue_number}"
                ]);
            }
        }
    }

    /**
     * Status Checks
     */
    public function isDispatched()
    {
        return in_array($this->status, ['dispatched', 'in_transit', 'delivered', 'completed']);
    }

    public function isCompleted()
    {
        return $this->status === 'completed';
    }

    public function requiresInspection()
    {
        return $this->requires_inspection && $this->inspection_status !== 'passed';
    }

    /**
     * Get status badge color
     */
    public function getStatusColorAttribute()
    {
        return match($this->status) {
            'draft' => 'secondary',
            'dispatched' => 'warning',
            'in_transit' => 'info',
            'delivered' => 'primary',
            'partially_received' => 'warning',
            'completed' => 'success',
            'cancelled' => 'danger',
            default => 'secondary'
        };
    }
}