<?php

namespace App\Models;

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

class EmployeeAccessDetail extends Model
{
    use HasFactory;

    protected $table = 'employee_access_details';

    protected $fillable = [
        'employee_id',
        'access_catalog_id',
        'granted_date',
        'original_expiry_date',
        'current_expiry_date',
        'status',
        'is_extended',
        'extension_count',
        'last_extended_at',
        'last_extended_by',
        'revocation_date',
        'revoked_by',
        'revocation_notes'
    ];

    protected $casts = [
        'granted_date' => 'date',
        'original_expiry_date' => 'date',
        'current_expiry_date' => 'date',
        'revocation_date' => 'date',
        'is_extended' => 'boolean',
        'extension_count' => 'integer',
        'last_extended_at' => 'datetime',
    ];

    // Boot: Auto-create revocation schedule saat create
    protected static function boot()
    {
        parent::boot();

        static::created(function ($accessDetail) {
            // Auto-create schedule
            $accessDetail->revocationSchedules()->create([
                'scheduled_date' => $accessDetail->current_expiry_date,
                'status' => 'scheduled'
            ]);
        });

        static::updated(function ($accessDetail) {
            // Jika tanggal berubah (extended), update schedule
            if ($accessDetail->isDirty('current_expiry_date')) {
                $accessDetail->revocationSchedules()->create([
                    'scheduled_date' => $accessDetail->current_expiry_date,
                    'status' => 'scheduled'
                ]);
            }
        });
    }

    // ==================== RELATIONS ====================

    public function employee()
    {
        return $this->belongsTo(Employee::class);
    }

    public function accessCatalog()
    {
        return $this->belongsTo(AccessCatalog::class);
    }

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

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

    public function extensionRequests()
    {
        return $this->hasMany(ExtensionRequest::class);
    }

    public function revocationSchedules()
    {
        return $this->hasMany(RevocationSchedule::class);
    }

    public function reminderLogs()
    {
        return $this->hasMany(ReminderLog::class);
    }

    public function revocationLogs()
    {
        return $this->hasMany(AccessRevocationLog::class);
    }

    // ==================== SCOPES ====================

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

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

    public function scopeExpiringInDays($query, $days)
    {
        $targetDate = Carbon::now()->addDays($days)->format('Y-m-d');
        return $query->where('current_expiry_date', '<=', $targetDate)
                     ->where('current_expiry_date', '>=', Carbon::now())
                     ->whereIn('status', ['active', 'extended']);
    }

    public function scopeExpiredButNotRevoked($query)
    {
        return $query->where('current_expiry_date', '<', Carbon::today())
                     ->whereNotIn('status', ['revoked']);
    }

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

    // ==================== HELPERS ====================

    public function daysUntilExpiry()
    {
        return Carbon::now()->diffInDays($this->current_expiry_date, false);
    }

    public function needsReminder7Days()
    {
        $days = $this->daysUntilExpiry();
        return $days <= 7 && $days > 1 && !$this->latestSchedule()?->reminder_sent_7;
    }

    public function needsReminder1Day()
    {
        $days = $this->daysUntilExpiry();
        return $days <= 1 && $days >= 0 && !$this->latestSchedule()?->reminder_sent_1;
    }

    public function latestSchedule()
    {
        return $this->revocationSchedules()->latest()->first();
    }

    public function extend($days, $reason, $userId, $document = null)
    {
        $newDate = Carbon::parse($this->current_expiry_date)->addDays($days);
        
        $this->update([
            'current_expiry_date' => $newDate,
            'status' => 'extended',
            'is_extended' => true,
            'extension_count' => $this->extension_count + 1,
            'last_extended_at' => now(),
            'last_extended_by' => $userId
        ]);

        return $this->extensionRequests()->create([
            'requested_by' => $userId,
            'requested_duration_days' => $days,
            'new_expiry_date' => $newDate,
            'reason' => $reason,
            'supporting_document' => $document,
            'approval_status' => 'approved',
            'approved_by' => $userId,
            'approved_at' => now()
        ]);
    }

    public function revoke($userId, $method = 'manual', $notes = null)
    {
        $previousStatus = $this->status;
        
        $this->update([
            'status' => 'revoked',
            'revocation_date' => now(),
            'revoked_by' => $userId
        ]);

        if ($schedule = $this->latestSchedule()) {
            $schedule->update([
                'status' => 'completed',
                'actual_date' => now()
            ]);
        }

        return $this->revocationLogs()->create([
            'revoked_by' => $userId,
            'revoked_at' => now(),
            'method' => $method,
            'previous_status' => $previousStatus,
            'notes' => $notes,
            'ip_address' => request()->ip(),
            'user_agent' => request()->userAgent()
        ]);
    }
}