<?php

namespace App\Models;

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

class Holiday extends Model
{
    use HasFactory;

    protected $table = 'm_holidays';
    
    protected $fillable = [
        'name',
        'date',
        'type',
        'description',
        'is_recurring',
        'recurring_type',
        'is_active',
        'delete_flag',
        'created_by',
        'updated_by'
    ];

    protected $casts = [
        'date' => 'date',
        'is_recurring' => 'boolean',
        'is_active' => 'boolean',
        'delete_flag' => 'boolean'
    ];

    // Holiday types
    const TYPE_NATIONAL = 'National';
    const TYPE_RELIGIOUS = 'Religious';
    const TYPE_COMPANY = 'Company';
    const TYPE_REGIONAL = 'Regional';

    // Recurring types
    const RECURRING_YEARLY = 'Yearly';
    const RECURRING_MONTHLY = 'Monthly';
    const RECURRING_NONE = 'None';

    // Scope untuk data aktif
    public function scopeActive($query)
    {
        return $query->where('delete_flag', false);
    }

    // Scope untuk data yang aktif dan enabled
    public function scopeEnabled($query)
    {
        return $query->where('delete_flag', false)->where('is_active', true);
    }

    // Scope untuk tahun tertentu
    public function scopeForYear($query, $year)
    {
        return $query->whereYear('date', $year);
    }

    // Scope untuk bulan tertentu
    public function scopeForMonth($query, $year, $month)
    {
        return $query->whereYear('date', $year)->whereMonth('date', $month);
    }

    // Scope untuk range tanggal
    public function scopeForDateRange($query, $startDate, $endDate)
    {
        return $query->whereBetween('date', [$startDate, $endDate]);
    }

    // Relationship dengan user yang membuat
    public function creator()
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    // Relationship dengan user yang mengupdate
    public function modificator()
    {
        return $this->belongsTo(User::class, 'updated_by');
    }

    // Helper methods
    public function isEnabled()
    {
        return $this->is_active && !$this->delete_flag;
    }

    public function getStatusAttribute()
    {
        if ($this->delete_flag) {
            return 'Deleted';
        }
        return $this->is_active ? 'Active' : 'Inactive';
    }

    public function getStatusBadgeAttribute()
    {
        switch ($this->status) {
            case 'Active':
                return 'badge-success';
            case 'Inactive':
                return 'badge-secondary';
            case 'Deleted':
                return 'badge-danger';
            default:
                return 'badge-secondary';
        }
    }

    public function getTypeBadgeAttribute()
    {
        switch ($this->type) {
            case self::TYPE_NATIONAL:
                return 'badge-danger';
            case self::TYPE_RELIGIOUS:
                return 'badge-info';
            case self::TYPE_COMPANY:
                return 'badge-secondary';
            case self::TYPE_REGIONAL:
                return 'badge-secondary';
            default:
                return 'badge-light';
        }
    }

    // Check if holiday is today
    public function isToday()
    {
        return $this->date->isToday();
    }

    // Check if holiday is in the past
    public function isPast()
    {
        return $this->date->isPast();
    }

    // Check if holiday is in the future
    public function isFuture()
    {
        return $this->date->isFuture();
    }

    // Check if holiday is this year
    public function isThisYear()
    {
        return $this->date->isCurrentYear();
    }

    // Get days until holiday
    public function getDaysUntilAttribute()
    {
        if ($this->isPast()) {
            return null;
        }
        
        return Carbon::now()->diffInDays($this->date);
    }

    // Get formatted date
    public function getFormattedDateAttribute()
    {
        return $this->date->format('D, M j Y');
    }

    // Get short formatted date
    public function getShortDateAttribute()
    {
        return $this->date->format('M j');
    }

    // Static method to check if a date is holiday
    public static function isHoliday($date)
    {
        $checkDate = Carbon::parse($date);
        
        return static::enabled()
            ->where('date', $checkDate->format('Y-m-d'))
            ->exists();
    }

    // Static method to get holidays for a date range
    public static function getHolidaysInRange($startDate, $endDate)
    {
        return static::enabled()
            ->forDateRange($startDate, $endDate)
            ->orderBy('date')
            ->get();
    }

    // Static method to get next holiday
    public static function getNextHoliday()
    {
        return static::enabled()
            ->where('date', '>', Carbon::now())
            ->orderBy('date')
            ->first();
    }

    // Static method to get holidays this month
    public static function getHolidaysThisMonth()
    {
        $now = Carbon::now();
        return static::enabled()
            ->forMonth($now->year, $now->month)
            ->orderBy('date')
            ->get();
    }

    // Static method to get holidays this year
    public static function getHolidaysThisYear()
    {
        return static::enabled()
            ->forYear(Carbon::now()->year)
            ->orderBy('date')
            ->get();
    }

    // Generate recurring holidays for next year
    public function generateRecurringHoliday($targetYear)
    {
        if (!$this->is_recurring || $this->recurring_type === self::RECURRING_NONE) {
            return null;
        }

        $newDate = null;
        
        switch ($this->recurring_type) {
            case self::RECURRING_YEARLY:
                $newDate = $this->date->copy()->year($targetYear);
                break;
                
            case self::RECURRING_MONTHLY:
                // For monthly recurring, we need to be more careful
                // This is a simplified implementation
                $newDate = $this->date->copy()->year($targetYear);
                break;
        }

        if ($newDate) {
            return [
                'name' => $this->name,
                'date' => $newDate->format('Y-m-d'),
                'type' => $this->type,
                'description' => $this->description,
                'is_recurring' => true,
                'recurring_type' => $this->recurring_type,
                'is_active' => $this->is_active,
                'delete_flag' => false
            ];
        }

        return null;
    }

    // Check if date conflicts with business days
    public function conflictsWithBusinessDay($businessDays = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
    {
        $dayOfWeek = strtolower($this->date->format('l'));
        return in_array($dayOfWeek, $businessDays);
    }

    // Get available holiday types
    public static function getTypes()
    {
        return [
            self::TYPE_NATIONAL => 'National Holiday',
            self::TYPE_RELIGIOUS => 'Religious Holiday', 
            self::TYPE_COMPANY => 'Company Holiday',
            self::TYPE_REGIONAL => 'Regional Holiday'
        ];
    }

    // Get available recurring types
    public static function getRecurringTypes()
    {
        return [
            self::RECURRING_NONE => 'No Recurring',
            self::RECURRING_YEARLY => 'Yearly',
            self::RECURRING_MONTHLY => 'Monthly'
        ];
    }
}