<?php

namespace App\Models;

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

class ShipmentSupplier extends Model
{
    use HasFactory;

    protected $table = 'm_shipment_suppliers';
    
    protected $fillable = [
        'code',
        'name',
        'contact_person',
        'phone',
        'email',
        'address',
        'contact_days',
        'contact_time_start',
        'contact_time_end',
        'lead_time_days',
        'notes',
        'is_active',
        'delete_flag',
        'created_by',
        'updated_by'
    ];

    protected $casts = [
        'contact_days' => 'array',
        'contact_time_start' => 'datetime:H:i',
        'contact_time_end' => 'datetime:H:i',
        'is_active' => 'boolean',
        'delete_flag' => 'boolean',
        'lead_time_days' => 'integer'
    ];

    // 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);
    }

    // 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';
        }
    }

    // Get contact days as readable string
    public function getContactDaysStringAttribute()
    {
        if (!$this->contact_days || empty($this->contact_days)) {
            return 'Not Set';
        }

        $dayNames = [
            'monday' => 'Monday',
            'tuesday' => 'Tuesday', 
            'wednesday' => 'Wednesday',
            'thursday' => 'Thursday',
            'friday' => 'Friday',
            'saturday' => 'Saturday',
            'sunday' => 'Sunday'
        ];

        $contactDays = array_map(function($day) use ($dayNames) {
            return $dayNames[$day] ?? $day;
        }, $this->contact_days);

        return implode(', ', $contactDays);
    }

    // Check if today is a contact day
    public function canContactToday()
    {
        if (!$this->contact_days || empty($this->contact_days)) {
            return false;
        }

        $today = strtolower(Carbon::now()->format('l')); // monday, tuesday, etc.
        return in_array($today, $this->contact_days);
    }

    // Get next available contact date
    public function getNextContactDate()
    {
        if (!$this->contact_days || empty($this->contact_days)) {
            return null;
        }

        $dayMapping = [
            'monday' => 1,
            'tuesday' => 2,
            'wednesday' => 3,
            'thursday' => 4,
            'friday' => 5,
            'saturday' => 6,
            'sunday' => 0
        ];

        $contactDayNumbers = array_map(function($day) use ($dayMapping) {
            return $dayMapping[$day] ?? null;
        }, $this->contact_days);

        $contactDayNumbers = array_filter($contactDayNumbers, function($day) {
            return $day !== null;
        });

        if (empty($contactDayNumbers)) {
            return null;
        }

        sort($contactDayNumbers);

        $today = Carbon::now();
        $currentDayNumber = $today->dayOfWeek;

        // Find next contact day
        foreach ($contactDayNumbers as $contactDay) {
            if ($contactDay > $currentDayNumber) {
                return $today->copy()->next($this->getDayName($contactDay));
            }
        }

        // If no day found this week, get first day of next week
        $firstContactDay = $contactDayNumbers[0];
        return $today->copy()->next($this->getDayName($firstContactDay));
    }

    // Get estimated delivery date based on lead time
    public function getEstimatedDeliveryDate($contactDate = null)
    {
        if (!$contactDate) {
            $contactDate = $this->getNextContactDate();
        }

        if (!$contactDate || !$this->lead_time_days) {
            return null;
        }

        return $contactDate->copy()->addDays($this->lead_time_days);
    }

    // Helper to get day name from number
    private function getDayName($dayNumber)
    {
        $days = [
            0 => 'Sunday',
            1 => 'Monday',
            2 => 'Tuesday',
            3 => 'Wednesday',
            4 => 'Thursday',
            5 => 'Friday',
            6 => 'Saturday'
        ];

        return $days[$dayNumber] ?? 'Monday';
    }

    // Check if supplier can be contacted at specific time
    public function canContactAtTime($time = null)
    {
        if (!$time) {
            $time = Carbon::now()->format('H:i');
        }

        if (!$this->contact_time_start || !$this->contact_time_end) {
            return true; // No time restriction
        }

        $startTime = Carbon::createFromFormat('H:i', $this->contact_time_start->format('H:i'));
        $endTime = Carbon::createFromFormat('H:i', $this->contact_time_end->format('H:i'));
        $checkTime = Carbon::createFromFormat('H:i', $time);

        return $checkTime->between($startTime, $endTime);
    }

    // Get contact window string
    public function getContactWindowAttribute()
    {
        if (!$this->contact_time_start || !$this->contact_time_end) {
            return 'Anytime';
        }

        return $this->contact_time_start->format('H:i') . ' - ' . $this->contact_time_end->format('H:i');
    }
}