<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class StaffHistory extends Model
{
    use HasFactory, SoftDeletes;

    const STATUS_CURRENT = 'current';
    const STATUS_FORMER = 'former';

    protected $fillable = [
        'organization_id',
        'user_id',
        'staff_name',
        'position',
        'employment_start_date',
        'employment_end_date',
        'employment_status',
        'termination_reason',
        'passport_path',
    ];

    protected $casts = [
        'employment_start_date' => 'date',
        'employment_end_date' => 'date',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    protected static function booted(): void
    {
        static::saving(function (StaffHistory $staff) {
            if ($staff->employment_end_date) {
                $staff->employment_status = self::STATUS_FORMER;
            } elseif ($staff->employment_status === self::STATUS_CURRENT) {
                $staff->employment_end_date = null;
            }
        });
    }

    public function organization()
    {
        return $this->belongsTo(Organization::class);
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function achievements()
    {
        return $this->hasMany(StaffAchievement::class);
    }

    public function addAchievement(string $description, string $date): StaffAchievement
    {
        return $this->achievements()->create([
            'achievement_description' => $description,
            'achievement_date' => $date,
        ]);
    }

    public function endEmployment(string $endDate, ?string $reason = null): bool
    {
        $this->employment_end_date = $endDate;
        $this->employment_status = self::STATUS_FORMER;
        $this->termination_reason = $reason;
        return $this->save();
    }

    public function getEmploymentDurationInDays(): ?int
    {
        $endDate = $this->employment_end_date ?? now();
        return $this->employment_start_date->diffInDays($endDate);
    }

    public function getEmploymentDurationAttribute(): string
    {
        $endDate = $this->employment_end_date ?? now();
        return $this->employment_start_date->diffForHumans($endDate, true);
    }

    public function isCurrent(): bool
    {
        return $this->employment_status === self::STATUS_CURRENT;
    }

    public function isFormer(): bool
    {
        return $this->employment_status === self::STATUS_FORMER;
    }

    public function getStatusLabelAttribute(): string
    {
        return ucfirst($this->employment_status);
    }

    public function scopeCurrent($query)
    {
        return $query->where('employment_status', self::STATUS_CURRENT);
    }

    public function scopeFormer($query)
    {
        return $query->where('employment_status', self::STATUS_FORMER);
    }

    public function scopeForOrganization($query, int $organizationId)
    {
        return $query->where('organization_id', $organizationId);
    }

    public function scopeByPosition($query, string $position)
    {
        return $query->where('position', 'like', "%{$position}%");
    }

    public function scopeDateRange($query, string $startDate, string $endDate)
    {
        return $query->where(function ($q) use ($startDate, $endDate) {
            $q->whereBetween('employment_start_date', [$startDate, $endDate])
                ->orWhereBetween('employment_end_date', [$startDate, $endDate]);
        });
    }

    public function scopeSearch($query, string $search)
    {
        return $query->where(function ($q) use ($search) {
            $q->where('staff_name', 'like', "%{$search}%")
                ->orWhere('position', 'like', "%{$search}%");
        });
    }

    public function scopeOrderByStartDate($query, string $direction = 'desc')
    {
        return $query->orderBy('employment_start_date', $direction);
    }

    public function getPassportUrl(): ?string
    {
        if (!$this->passport_path) {
            return null;
        }
        return \Illuminate\Support\Facades\Storage::disk('public')->url($this->passport_path);
    }

    public function hasPassport(): bool
    {
        return !is_null($this->passport_path) && \Illuminate\Support\Facades\Storage::disk('public')->exists($this->passport_path);
    }

    public function deletePassport(): bool
    {
        if (!$this->passport_path) {
            return false;
        }
        if (\Illuminate\Support\Facades\Storage::disk('public')->exists($this->passport_path)) {
            \Illuminate\Support\Facades\Storage::disk('public')->delete($this->passport_path);
        }
        $this->passport_path = null;
        return $this->save();
    }

    protected static function booting(): void
    {
        parent::booting();
        static::deleting(function (StaffHistory $staff) {
            if ($staff->passport_path && \Illuminate\Support\Facades\Storage::disk('public')->exists($staff->passport_path)) {
                \Illuminate\Support\Facades\Storage::disk('public')->delete($staff->passport_path);
            }
        });
    }
}
