<?php

namespace App\Models\Warehouse\FixedAssets;

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

class FixedAssetDisposal extends Model
{
    use HasFactory, SoftDeletes;

    protected $table = 'fixed_asset_disposals';

    protected $fillable = [
        'disposal_number',
        'fixed_asset_id',
        'disposal_type',
        'disposal_date',
        'disposal_reason',
        'book_value_at_disposal',
        'disposal_amount',
        'gain_loss',
        'buyer_name',
        'buyer_contact',
        'invoice_number',
        'notes',
        'status',
        'requested_by',
        'approved_by',
        'approved_at',
        'attached_documents',
    ];

    protected $casts = [
        'disposal_date' => 'date',
        'book_value_at_disposal' => 'decimal:2',
        'disposal_amount' => 'decimal:2',
        'gain_loss' => 'decimal:2',
        'approved_at' => 'datetime',
        'attached_documents' => 'array',
    ];

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

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

            if ($model->disposal_amount !== null && $model->book_value_at_disposal !== null) {
                $model->gain_loss = $model->disposal_amount - $model->book_value_at_disposal;
            }
        });

        static::updating(function ($model) {
            if ($model->isDirty(['disposal_amount', 'book_value_at_disposal'])) {
                if ($model->disposal_amount !== null && $model->book_value_at_disposal !== null) {
                    $model->gain_loss = $model->disposal_amount - $model->book_value_at_disposal;
                }
            }
        });
    }

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

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

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

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

    /**
     * Complete the disposal process.
     */
    public function complete(): void
    {
        DB::transaction(function () {
            $asset = $this->fixedAsset;

            $lifecycleStatus = $this->disposal_type === 'retired' ? 'retired' : 'disposed';

            $asset->update([
                'lifecycle_status' => $lifecycleStatus,
                'status' => 'inactive',
                'current_project_id' => null,
                'current_division_id' => null,
            ]);

            FixedAssetMovement::create([
                'fixed_asset_id' => $asset->id,
                'movement_type' => 'disposal',
                'from_location' => $asset->current_project_id ? 'project' : 'warehouse',
                'from_project_id' => $asset->current_project_id,
                'from_division_id' => $asset->current_division_id,
                'to_location' => 'disposed',
                'movement_date' => $this->disposal_date ?? now(),
                'reference_type' => 'disposal',
                'reference_id' => $this->id,
                'performed_by' => $this->approved_by ?? $this->requested_by,
                'notes' => 'Asset disposed via ' . $this->disposal_number . ' (' . $this->disposal_type . ')',
            ]);

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

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

    public function fixedAsset()
    {
        return $this->belongsTo(FixedAsset::class, 'fixed_asset_id');
    }

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

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