<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
use Illuminate\Support\Facades\Storage;

class Absensi extends Model
{
    use HasFactory;

    /**
     * Nama tabel di database
     */
    protected $table = 'absensis'; // PERBAIKAN: Ganti 'absensi' menjadi 'absensis'

    /**
     * Primary key tabel
     */
    protected $primaryKey = 'id_absensi'; 

    /**
     * Field yang dapat diisi secara mass assignment
     */
    protected $fillable = [
        'id_teknisi',
        'tanggal',
        'jam_masuk',
        'jam_keluar',
        'foto_absen_masuk',
        'foto_absen_keluar',
        'latitude',
        'longitude',
        'status',
        'keterangan'
    ];

    /**
     * Field yang akan di-cast ke tipe data tertentu
     */
    protected $casts = [
        'tanggal' => 'date',
        'jam_masuk' => 'datetime',
        'jam_keluar' => 'datetime',
        'created_at' => 'datetime',
        'updated_at' => 'datetime'
    ];

    /**
     * Status absensi yang valid
     */
    const STATUS_HADIR = 'hadir';
    const STATUS_SAKIT = 'sakit';
    const STATUS_IZIN = 'izin';

    /**
     * Array status yang tersedia
     */
    public static function getStatusOptions()
    {
        return [
            self::STATUS_HADIR => 'Hadir',
            self::STATUS_SAKIT => 'Sakit',
            self::STATUS_IZIN => 'Izin'
        ];
    }

    /**
     * Relasi ke model Teknisi
     * Satu absensi dimiliki oleh satu teknisi
     */
    public function teknisi()
    {
         return $this->belongsTo(Teknisi::class, 'id_teknisi', 'id_teknisi');
    }

    /**
     * Scope untuk filter berdasarkan tanggal
     */
    public function scopeFilterByDate($query, $tanggal)
    {
        if ($tanggal) {
            return $query->whereDate('tanggal', $tanggal);
        }
        return $query;
    }

    /**
     * Scope untuk filter berdasarkan status
     */
    public function scopeFilterByStatus($query, $status)
    {
        if ($status) {
            return $query->where('status', $status);
        }
        return $query;
    }

    /**
     * Scope untuk filter berdasarkan teknisi
     */
    public function scopeFilterByTeknisi($query, $teknisiId)
    {
        if ($teknisiId) {
            return $query->where('id_teknisi', $teknisiId);
        }
        return $query;
    }

    /**
     * Scope untuk filter berdasarkan bulan dan tahun
     */
    public function scopeFilterByMonth($query, $bulan, $tahun = null)
    {
        if (!$tahun) {
            $tahun = date('Y');
        }
        
        return $query->whereMonth('tanggal', $bulan)
                     ->whereYear('tanggal', $tahun);
    }

    /**
     * Scope untuk data absensi hari ini
     */
    public function scopeToday($query)
    {
        return $query->whereDate('tanggal', Carbon::today());
    }

    /**
     * Scope untuk data absensi minggu ini
     */
    public function scopeThisWeek($query)
    {
        return $query->whereBetween('tanggal', [
            Carbon::now()->startOfWeek(),
            Carbon::now()->endOfWeek()
        ]);
    }

    /**
     * Scope untuk data absensi bulan ini
     */
    public function scopeThisMonth($query)
    {
        return $query->whereMonth('tanggal', Carbon::now()->month)
                     ->whereYear('tanggal', Carbon::now()->year);
    }

    /**
     * Accessor untuk format tanggal Indonesia
     */
    public function getTanggalFormattedAttribute()
    {
        return Carbon::parse($this->tanggal)->format('d/m/Y');
    }

    /**
     * Accessor untuk format jam masuk
     */
    public function getJamMasukFormattedAttribute()
    {
        return $this->jam_masuk ? Carbon::parse($this->jam_masuk)->format('H:i') : '-';
    }

    /**
     * Accessor untuk format jam keluar
     */
    public function getJamKeluarFormattedAttribute()
    {
        return $this->jam_keluar ? Carbon::parse($this->jam_keluar)->format('H:i') : '-';
    }

    /**
     * Accessor untuk nama status dengan format title case
     */
    public function getStatusFormattedAttribute()
    {
        return ucfirst($this->status);
    }

    /**
     * Accessor untuk URL foto absen masuk
     */
    public function getFotoAbsenMasukUrlAttribute()
    {
        return $this->foto_absen_masuk ? asset('storage/' . $this->foto_absen_masuk) : null;
    }

    /**
     * Accessor untuk URL foto absen keluar
     */
    public function getFotoAbsenKeluarUrlAttribute()
    {
        return $this->foto_absen_keluar ? asset('storage/' . $this->foto_absen_keluar) : null;
    }

    /**
     * Accessor untuk menghitung durasi kerja (dalam menit)
     */
    public function getDurasiKerjaAttribute()
    {
        if ($this->jam_masuk && $this->jam_keluar) {
            $masuk = Carbon::parse($this->jam_masuk);
            $keluar = Carbon::parse($this->jam_keluar);
            return $keluar->diffInMinutes($masuk);
        }
        return 0;
    }

    /**
     * Accessor untuk durasi kerja dalam format jam:menit
     */
    public function getDurasiKerjaFormattedAttribute()
    {
        $durasi = $this->durasi_kerja;
        if ($durasi > 0) {
            $jam = floor($durasi / 60);
            $menit = $durasi % 60;
            return sprintf('%02d:%02d', $jam, $menit);
        }
        return '00:00';
    }

    /**
     * Accessor untuk menentukan apakah terlambat (asumsi jam masuk normal 08:00)
     */
    /**
     * Accessor untuk kategori kerja (Kerja Biasa vs Lembur)
     */
    public function getKategoriKerjaAttribute()
    {
        if ($this->jam_masuk) {
            $jamMasuk = Carbon::parse($this->jam_masuk);
            $start = Carbon::parse('07:00');
            $end = Carbon::parse('18:00');
            
            if ($jamMasuk->between($start, $end)) {
                return 'Kerja Biasa';
            }
            return 'Kerja Urgent';
        }
        return '-';
    }

    /**
     * Label warna untuk kategori kerja
     */
    public function getKategoriBadgeClassAttribute()
    {
        return $this->kategori_kerja === 'Kerja Biasa' ? 'badge-success' : 'badge-warning';
    }

    /**
     * Logika terlambat ditiadakan sesuai permintaan user
     */
    public function getIsTerlambatAttribute()
    {
        return false;
    }

    /**
     * Accessor untuk CSS class badge berdasarkan status
     */
    public function getStatusBadgeClassAttribute()
    {
        $classes = [
            self::STATUS_HADIR => 'badge-success',
            self::STATUS_SAKIT => 'badge-warning',
            self::STATUS_IZIN => 'badge-info'
        ];

        return $classes[$this->status] ?? 'badge-secondary';
    }

    /**
     * Method untuk mengecek apakah absensi sudah lengkap (ada jam masuk dan keluar)
     */
    public function isComplete()
    {
        return !empty($this->jam_masuk) && !empty($this->jam_keluar);
    }

    /**
     * Method untuk mengecek apakah sudah absen masuk
     */
    public function hasAbsenMasuk()
    {
        return !empty($this->jam_masuk);
    }

    /**
     * Method untuk mengecek apakah sudah absen keluar
     */
    public function hasAbsenKeluar()
    {
        return !empty($this->jam_keluar);
    }

    /**
     * Static method untuk mendapatkan statistik absensi berdasarkan periode
     */
    public static function getStatistik($startDate = null, $endDate = null)
    {
        $query = self::query();
        
        if ($startDate && $endDate) {
            $query->whereBetween('tanggal', [$startDate, $endDate]);
        }

        return [
            'total' => $query->count(),
            'hadir' => $query->where('status', self::STATUS_HADIR)->count(),
            'sakit' => $query->where('status', self::STATUS_SAKIT)->count(),
            'izin' => $query->where('status', self::STATUS_IZIN)->count(),
        ];
    }

    /**
     * Boot method untuk event model
     */
    protected static function boot()
    {
        parent::boot();

        // Event ketika model akan dihapus
        static::deleting(function ($absensi) {
            // Hapus file foto jika ada
            if ($absensi->foto_absen_masuk && Storage::disk('public')->exists($absensi->foto_absen_masuk)) {
                Storage::disk('public')->delete($absensi->foto_absen_masuk);
            }
            
            if ($absensi->foto_absen_keluar && Storage::disk('public')->exists($absensi->foto_absen_keluar)) {
                Storage::disk('public')->delete($absensi->foto_absen_keluar);
            }
        });
    }
}