<?php
namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class EmployeeDetails extends Model
{
    use SoftDeletes; // Optional: If you want soft deletes (recommended for production).

    protected $table = 'employees';

    protected $fillable = [
        'employee_id', 'name', 'gender', 'department', 'designation',
        'dob', 'doj', 'mobile', 'aadhar_number', 'category', 'status', 'profile_picture',
    ];

    protected $appends = ['availability', 'available_by'];

    // Relationships
    public function leaves()
    {
        return $this->hasMany(EmployeeLeave::class, 'employee_id', 'id');
    }

    public function routeCardProcesses()
    {
        return $this->hasMany(RouteCardProcess::class, 'operator', 'id');
    }

    // --- Helper methods ---

    /**
     * Get number of CL taken in a given year
     */
    public function clTakenThisYear($year = null)
    {
        $year = $year ?: now()->year;
        return $this->leaves()
            ->where('leave_type', 'CL')
            ->whereYear('leave_from', $year)
            ->whereIn('status', ['Approved', 'Pending'])
            ->sum('number_of_days');
    }

    /**
     * Get CL accrued up to a given date (default: today)
     * Returns integer, e.g., Jan=1, Feb=2, ..., Dec=12
     */
    public function clAccrued(Carbon $asOf = null)
    {
        $asOf = $asOf ?: now();
        return $asOf->month;
    }

    /**
     * Get available CL for this employee for a specific month/year
     */
    public function clAvailable($asOf = null)
    {
        $asOf    = $asOf ?: now();
        $year    = $asOf->year;
        $accrued = $this->clAccrued($asOf);
        $taken   = $this->leaves()
            ->where('leave_type', 'CL')
            ->whereYear('leave_from', $year)
            ->whereIn('status', ['Approved', 'Pending'])
            ->sum('number_of_days');
        return max(0, $accrued - $taken);
    }

    // (Optional) Any other relationships you want
    public function processes()
    {
        return $this->belongsToMany(Process::class, 'process_operator', 'employee_id', 'process_id');
    }

    public function getAvailabilityAttribute()
    {
        $routeCard = isset(request()->route_card) ? request()->route_card : null;
        $now       = empty($routeCard) ? Carbon::now() : Carbon::parse($routeCard->project_start_date);
        $startTime = $now->copy()->startOfDay();
        $endTime   = $now->copy()->endOfDay();
        $inUse     = $this->routeCardProcesses()
            ->where(function($query) use ($startTime, $endTime) {
                $query->where(function($q) use ($startTime, $endTime) {
                    $q->where('start_date', '<=', $startTime)
                    ->where('end_date', '>=', $endTime);
                })->orWhere(function($q) use ($startTime, $endTime) {
                    $q->where('start_date', '>=', $startTime);
                })->orWhere(function($q) use ($startTime, $endTime) {
                    $q->where('end_date', '<=', $startTime);
                });
            })
            ->exists();
        return $inUse ? 0 : 1;
    }

    public function getAvailableByAttribute()
    {
        $routeCard        = isset(request()->route_card) ? request()->route_card : null;
        $now              = empty($routeCard) ? Carbon::now() : Carbon::parse($routeCard->project_start_date);
        $startTime        = $now->copy()->startOfDay();
        $endTime          = $now->copy()->endOfDay();
        $nextAvailability = $this->routeCardProcesses()
        ->where(function($query) use ($startTime, $endTime) {
            $query->where(function($q) use ($startTime, $endTime) {
                $q->where('start_date', '<=', $startTime)
                ->where('end_date', '>=', $endTime);
            })->orWhere(function($q) use ($startTime, $endTime) {
                $q->where('start_date', '>=', $startTime);
            })->orWhere(function($q) use ($startTime, $endTime) {
                $q->where('end_date', '<=', $startTime);
            });
        })
        ->orderBy('end_date','desc')
        ->value('end_date');

        return $nextAvailability
        ? Carbon::parse($nextAvailability)->format('Y-m-d H:i')
        : Carbon::parse($now)->format('Y-m-d H:i');
    }
}
