<?php

namespace App\Models\Warehouse\FixedAssets;

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

class FixedAssetReturn extends Model
{
    use HasFactory, SoftDeletes;

    protected $table = 'fixed_asset_returns';

    protected $fillable = [
        'return_number',
        'project_id',
        'division_id',
        'return_date',
        'reason',
        'notes',
        'status',
        'returned_by',
        'inspected_by',
        'inspected_at',
        'completed_by',
        'completed_at',
    ];

    protected $casts = [
        'return_date' => 'date',
        'inspected_at' => 'datetime',
        'completed_at' => 'datetime',
    ];

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

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

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

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

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

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

    /**
     * Complete the return process.
     */
    public function complete(int $userId): void
    {
        DB::transaction(function () use ($userId) {
            foreach ($this->items as $item) {
                $asset = $item->fixedAsset;

                $asset->update([
                    'condition' => $item->condition_after ?? $item->condition_on_return,
                    'lifecycle_status' => 'in_warehouse',
                    'current_project_id' => null,
                    'current_division_id' => null,
                ]);

                FixedAssetMovement::create([
                    'fixed_asset_id' => $asset->id,
                    'movement_type' => 'return',
                    'from_location' => 'project',
                    'from_project_id' => $this->project_id,
                    'from_division_id' => $this->division_id,
                    'to_location' => 'warehouse',
                    'movement_date' => now(),
                    'reference_type' => 'return',
                    'reference_id' => $this->id,
                    'performed_by' => $userId,
                    'notes' => 'Asset returned via ' . $this->return_number,
                ]);
            }

            $this->update([
                'status' => 'completed',
                'completed_by' => $userId,
                'completed_at' => now(),
            ]);
        });
    }

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

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

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

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

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

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

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