<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Estimate extends Model
{
    use HasFactory;

    protected $fillable = [
        'job_card_id',
        'diagnosis_id',
        'customer_id',
        'vehicle_id',
        'estimate_number',
        'prepared_by_id',
        'labor_cost',
        'parts_cost',
        'miscellaneous_cost',
        'subtotal',
        'tax_rate',
        'tax_amount',
        'discount_amount',
        'total_amount',
        'validity_period_days',
        'terms_and_conditions',
        'status',
        'customer_approval_status',
        'customer_approved_at',
        'customer_approval_method',
        'sent_to_customer_at',
        'sms_sent_at',
        'email_sent_at',
        'notes',
        'internal_notes',
        'revision_number',
        'original_estimate_id',
    ];

    protected $casts = [
        'labor_cost' => 'decimal:2',
        'parts_cost' => 'decimal:2',
        'miscellaneous_cost' => 'decimal:2',
        'subtotal' => 'decimal:2',
        'tax_rate' => 'decimal:2',
        'tax_amount' => 'decimal:2',
        'discount_amount' => 'decimal:2',
        'total_amount' => 'decimal:2',
        'customer_approved_at' => 'datetime',
        'sent_to_customer_at' => 'datetime',
        'sms_sent_at' => 'datetime',
        'email_sent_at' => 'datetime',
    ];

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

        static::creating(function ($estimate) {
            if (empty($estimate->estimate_number)) {
                $estimate->estimate_number = 'EST'.str_pad(rand(1, 9999), 4, '0', STR_PAD_LEFT);
            }
        });
    }

    public function jobCard(): BelongsTo
    {
        return $this->belongsTo(JobCard::class, 'job_card_id');
    }

    public function diagnosis(): BelongsTo
    {
        return $this->belongsTo(Diagnosis::class);
    }

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

    public function customer(): BelongsTo
    {
        return $this->belongsTo(Customer::class);
    }

    public function vehicle(): BelongsTo
    {
        return $this->belongsTo(Vehicle::class);
    }

    public function lineItems(): HasMany
    {
        return $this->hasMany(EstimateLineItem::class);
    }

    public function originalEstimate(): BelongsTo
    {
        return $this->belongsTo(Estimate::class, 'original_estimate_id');
    }

    public function revisions(): HasMany
    {
        return $this->hasMany(Estimate::class, 'original_estimate_id');
    }

    public function workOrders(): HasMany
    {
        return $this->hasMany(WorkOrder::class);
    }

    public function getValidUntilAttribute()
    {
        return $this->created_at->addDays($this->validity_period_days ?? 30);
    }

    public function getIsExpiredAttribute()
    {
        return now()->isAfter($this->valid_until);
    }

    public function getFormattedValidUntilAttribute()
    {
        return $this->valid_until->format('M d, Y');
    }

    public function scopeExpired($query)
    {
        return $query->whereDate('created_at', '<', now()->subDays(30));
    }

    public function scopeValid($query)
    {
        return $query->whereDate('created_at', '>=', now()->subDays(30));
    }

    public function scopeByStatus($query, $status)
    {
        return $query->where('status', $status);
    }

    public function scopeByBranch($query, $branchId)
    {
        return $query->whereHas('jobCard', function ($q) use ($branchId) {
            $q->where('branch_id', $branchId);
        });
    }

    /**
     * Get the customer for this estimate (either direct or through job card)
     */
    public function getEstimateCustomerAttribute()
    {
        return $this->customer_id ? $this->customer : $this->jobCard?->customer;
    }

    /**
     * Get the vehicle for this estimate (either direct or through job card)
     */
    public function getEstimateVehicleAttribute()
    {
        return $this->vehicle_id ? $this->vehicle : $this->jobCard?->vehicle;
    }
}
