<?php

namespace App\Models;

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

class FatteningLot extends Model
{
    use HasFactory;

    public const STATUS_OPEN = 'open';

    public const STATUS_CLOSED = 'closed';

    protected $fillable = [
        'name',
        'description',
        'entry_date',
        'pasture_accrual_start_date',
        'planned_duration_days',
        'status',
        'closed_at',
        'notes',
        'target_net_profit',
        'target_price_per_kg',
        'target_min_gdp_kg_per_day',
        'pasture_cost_per_animal_month',
    ];

    protected $casts = [
        'entry_date' => 'date',
        'pasture_accrual_start_date' => 'date',
        'closed_at' => 'date',
        'planned_duration_days' => 'integer',
        'target_net_profit' => 'decimal:2',
        'target_price_per_kg' => 'decimal:2',
        'target_min_gdp_kg_per_day' => 'decimal:4',
        'pasture_cost_per_animal_month' => 'decimal:2',
    ];

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

    public function activeAnimals(): HasMany
    {
        return $this->animals()->whereNull('removed_at');
    }

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

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

    public function pastureAccrualStartDate(): Carbon
    {
        return ($this->pasture_accrual_start_date ?? $this->entry_date)->copy();
    }

    public function daysInConfinement(): int
    {
        $end = $this->closed_at ?? Carbon::today();

        return max(0, $this->entry_date->diffInDays($end));
    }

    public function plannedDurationDays(): int
    {
        return (int) ($this->planned_duration_days
            ?? config('ranch.fattening.default_duration_days', 90));
    }

    public function plannedExitDate(): Carbon
    {
        return $this->entry_date->copy()->addDays($this->plannedDurationDays());
    }

    public function daysRemaining(): int
    {
        if ($this->status === self::STATUS_CLOSED) {
            return 0;
        }

        return max(0, Carbon::today()->diffInDays($this->plannedExitDate(), false));
    }

    public function pastureCostPerAnimalMonth(): float
    {
        return (float) ($this->pasture_cost_per_animal_month
            ?? config('ranch.fattening.default_pasture_cost_per_animal_month', 100));
    }

    public function scopeOpen($query)
    {
        return $query->where('status', self::STATUS_OPEN);
    }
}
