<?php

namespace App\Models\Warehouse\FixedAssets;

use App\Models\User;
use App\Models\Warehouse\Project;
use App\Models\Warehouse\ProjectDivision;
use App\Models\Warehouse\Supplier;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\DB;

class FixedAssetIncoming extends Model
{
    use HasFactory, SoftDeletes;

    protected $table = 'fixed_asset_incoming';

    protected $fillable = [
        'receipt_number',
        'supplier_id',
        'project_id',
        'division_id',
        'receipt_date',
        'invoice_number',
        'invoice_date',
        'delivery_note_number',
        'total_amount',
        'vat_rate',
        'vat_amount',
        'grand_total',
        'currency',
        'payment_terms',
        'status',
        'notes',
        'received_by',
        'approved_by',
        'approved_at',
        'attached_documents',
    ];

    protected $casts = [
        'total_amount' => 'decimal:2',
        'vat_amount' => 'decimal:2',
        'grand_total' => 'decimal:2',
        'receipt_date' => 'date',
        'invoice_date' => 'date',
        'approved_at' => 'datetime',
        'attached_documents' => 'array',
    ];

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

        static::creating(function ($model) {
            if (empty($model->receipt_number)) {
                $model->receipt_number = static::generateReceiptNumber();
            }

            if ($model->total_amount && $model->vat_rate) {
                $model->vat_amount = $model->total_amount * ($model->vat_rate / 100);
            }
        });

        static::updating(function ($model) {
            if ($model->isDirty(['total_amount', 'vat_rate'])) {
                if ($model->total_amount && $model->vat_rate) {
                    $model->vat_amount = $model->total_amount * ($model->vat_rate / 100);
                }
            }
        });
    }

    /**
     * Generate a unique receipt number.
     */
    public static function generateReceiptNumber(): string
    {
        return DB::transaction(function () {
            $prefix = 'FAR-' . now()->format('Ymd') . '-';

            $lastRecord = static::withTrashed()
                ->where('receipt_number', 'like', $prefix . '%')
                ->orderBy('receipt_number', 'desc')
                ->lockForUpdate()
                ->first();

            if ($lastRecord) {
                $lastNumber = (int) substr($lastRecord->receipt_number, -4);
                $newNumber = $lastNumber + 1;
            } else {
                $newNumber = 1;
            }

            return $prefix . str_pad($newNumber, 4, '0', STR_PAD_LEFT);
        });
    }

    /**
     * Complete the incoming receipt and create fixed asset records.
     */
    public function complete(): void
    {
        DB::transaction(function () {
            foreach ($this->items as $item) {
                for ($i = 0; $i < $item->quantity; $i++) {
                    $lifecycleStatus = $this->project_id ? 'in_use' : 'in_warehouse';

                    $asset = FixedAsset::create([
                        'category_id' => $item->category_id,
                        'name' => $item->name,
                        'description' => $item->description,
                        'brand' => $item->brand,
                        'model' => $item->model,
                        'serial_number' => $item->serial_number,
                        'unit_price' => $item->unit_price,
                        'purchase_date' => $this->receipt_date,
                        'supplier_id' => $this->supplier_id,
                        'warranty_start_date' => $item->warranty_start_date,
                        'warranty_end_date' => $item->warranty_end_date,
                        'current_project_id' => $this->project_id,
                        'current_division_id' => $this->division_id,
                        'lifecycle_status' => $lifecycleStatus,
                        'condition' => 'new',
                        'status' => 'active',
                        'incoming_id' => $this->id,
                        'incoming_item_id' => $item->id,
                    ]);

                    $item->update(['fixed_asset_id' => $asset->id]);

                    FixedAssetMovement::create([
                        'fixed_asset_id' => $asset->id,
                        'movement_type' => 'incoming',
                        'from_location' => 'supplier',
                        'to_location' => $this->project_id ? 'project' : 'warehouse',
                        'to_project_id' => $this->project_id,
                        'to_division_id' => $this->division_id,
                        'movement_date' => now(),
                        'reference_type' => 'incoming',
                        'reference_id' => $this->id,
                        'performed_by' => $this->received_by,
                        'notes' => 'Asset received via incoming receipt ' . $this->receipt_number,
                    ]);
                }
            }

            $this->update(['status' => 'completed']);
        });
    }

    // ── Relationships ──────────────────────────────────────────────────

    public function items()
    {
        return $this->hasMany(FixedAssetIncomingItem::class, 'fixed_asset_incoming_id');
    }

    public function supplier()
    {
        return $this->belongsTo(Supplier::class);
    }

    public function project()
    {
        return $this->belongsTo(Project::class);
    }

    public function division()
    {
        return $this->belongsTo(ProjectDivision::class, 'division_id');
    }

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

    public function approver()
    {
        return $this->belongsTo(User::class, 'approved_by');
    }
}
