<?php

namespace App\Models;

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

class Penggajian extends Model
{
    // use HasFactory, SoftDeletes;

    /**
     * Get nama bulan dari angka 1-12
     */
    public static function getNamaBulan($angka)
    {
        $bulan = [
            1 => 'Januari', 2 => 'Februari', 3 => 'Maret', 4 => 'April',
            5 => 'Mei', 6 => 'Juni', 7 => 'Juli', 8 => 'Agustus',
            9 => 'September', 10 => 'Oktober', 11 => 'November', 12 => 'Desember'
        ];
        return $bulan[(int)$angka] ?? 'N/A';
    }

    /**
     * The table associated with the model.
     */
    protected $table = 'penggajians';

    /**
     * The primary key for the model.
     */
    protected $primaryKey = 'id_penggajian';

    /**
     * The attributes that are mass assignable.
     */
    protected $fillable = [
        'id_teknisi',
        'periode_bulan',
        'periode_tahun',
        'tanggal_penggajian',
        'total_ongkos_pekerjaan',
        'jumlah_penugasan_selesai',
        'jumlah_hari_kerja',
        'total_kasbon',
        'biaya_makan',
        'total_potongan',
        'gaji_bersih',
        'status_pembayaran',
        'metode_pembayaran',
        'tanggal_dibayar',
        'bukti_pembayaran',
        'catatan',
    ];

    /**
     * The attributes that should be cast.
     */
    protected $casts = [
        'tanggal_penggajian' => 'date',
        'jumlah_hari_kerja' => 'integer',
        'total_ongkos_pekerjaan' => 'decimal:2',
        'total_kasbon' => 'decimal:2',
        'biaya_makan' => 'decimal:2',
        'total_potongan' => 'decimal:2',
        'gaji_bersih' => 'decimal:2',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
        'deleted_at' => 'datetime',
    ];

    /**
     * The attributes that should be hidden for arrays.
     */
    protected $hidden = [
        'deleted_at',
    ];

    /**
     * Status pembayaran constants
     */
    const STATUS_BELUM_BAYAR = 'belum_bayar';
    const STATUS_SUDAH_BAYAR = 'sudah_bayar';

    /**
     * Get all available status pembayaran
     */
    public static function getStatusPembayaran()
    {
        return [
            self::STATUS_BELUM_BAYAR => 'Belum Bayar',
            self::STATUS_SUDAH_BAYAR => 'Sudah Bayar',
        ];
    }

    /**
     * Relationship with Teknisi
     */
    public function teknisi()
    {
        return $this->belongsTo(Teknisi::class, 'id_teknisi', 'id_teknisi');
    }

    /**
     * Relationship with DetailPenggajian
     */
    public function detailPenggajian()
    {
        return $this->hasMany(DetailPenggajian::class, 'id_penggajian', 'id_penggajian');
    }

    /**
     * Scope for filtering by periode
     */
    public function scopeByPeriode($query, $bulan = null, $tahun = null)
    {
        if ($bulan) {
            $query->where('periode_bulan', $bulan);
        }
        if ($tahun) {
            $query->where('periode_tahun', $tahun);
        }
        return $query;
    }

    /**
     * Scope for filtering by status pembayaran
     */
    public function scopeByStatus($query, $status)
    {
        return $query->where('status_pembayaran', $status);
    }

    /**
     * Scope for belum bayar
     */
    public function scopeBelumBayar($query)
    {
        return $query->where('status_pembayaran', self::STATUS_BELUM_BAYAR);
    }

    /**
     * Scope for sudah bayar
     */
    public function scopeSudahBayar($query)
    {
        return $query->where('status_pembayaran', self::STATUS_SUDAH_BAYAR);
    }

    /**
     * Scope for current month
     */
    public function scopeCurrentMonth($query)
    {
        return $query->where('periode_bulan', date('n'))
                    ->where('periode_tahun', date('Y'));
    }

    /**
     * Scope for latest periode
     */
    public function scopeLatestPeriode($query)
    {
        return $query->orderBy('periode_tahun', 'desc')
                    ->orderBy('periode_bulan', 'desc');
    }

    /**
     * Get formatted periode
     */
    public function getFormattedPeriodeAttribute()
    {
        $bulan = Carbon::create()->month($this->periode_bulan)->format('F');
        return $bulan . ' ' . $this->periode_tahun;
    }

    /**
     * Get periode short format
     */
    public function getPeriodeShortAttribute()
    {
        $bulan = Carbon::create()->month($this->periode_bulan)->format('M');
        return $bulan . ' ' . $this->periode_tahun;
    }

    /**
     * Get status pembayaran label
     */
    public function getStatusLabelAttribute()
    {
        $statuses = self::getStatusPembayaran();
        return $statuses[$this->status_pembayaran] ?? $this->status_pembayaran;
    }

    /**
     * Get status badge class
     */
    public function getStatusBadgeClassAttribute()
    {
        switch ($this->status_pembayaran) {
            case self::STATUS_SUDAH_BAYAR:
                return 'bg-success';
            case self::STATUS_BELUM_BAYAR:
            default:
                return 'bg-warning';
        }
    }

    /**
     * Check if already paid
     */
    public function isPaid()
    {
        return $this->status_pembayaran === self::STATUS_SUDAH_BAYAR;
    }

    /**
     * Check if not paid yet
     */
    public function isUnpaid()
    {
        return $this->status_pembayaran === self::STATUS_BELUM_BAYAR;
    }

    /**
     * Mark as paid
     */
    public function markAsPaid()
    {
        $this->update([
            'status_pembayaran' => self::STATUS_SUDAH_BAYAR
        ]);
    }

    /**
     * Mark as unpaid
     */
    public function markAsUnpaid()
    {
        $this->update([
            'status_pembayaran' => self::STATUS_BELUM_BAYAR
        ]);
    }

    /**
     * Calculate total from detail penggajian
     */
    public function calculateTotals()
    {
        $details = $this->detailPenggajian;
        
        $totals = [
            'subtotal' => $details->sum('subtotal'),
            'total_unit' => $details->sum('jumlah_unit'),
        ];

        return $totals;
    }

    /**
     * Get formatted currency attributes
     */
    public function getFormattedGajiKotorAttribute()
    {
        return 'Rp ' . number_format($this->total_ongkos_pekerjaan, 0, ',', '.');
    }

    public function getFormattedBiayaMakanAttribute()
    {
        return 'Rp ' . number_format($this->biaya_makan, 0, ',', '.');
    }

    public function getFormattedTotalKasbonAttribute()
    {
        return 'Rp ' . number_format($this->total_kasbon, 0, ',', '.');
    }

    public function getFormattedGajiBersihAttribute()
    {
        return 'Rp ' . number_format($this->gaji_bersih, 0, ',', '.');
    }

    /**
     * Get potongan (total kasbon)
     */
    public function getPotonganAttribute()
    {
        return $this->total_kasbon;
    }

    /**
     * Get formatted potongan
     */
    public function getFormattedPotonganAttribute()
    {
        return 'Rp ' . number_format($this->potongan, 0, ',', '.');
    }

    /**
     * Static method to get summary by periode
     */
    public static function getSummaryByPeriode($bulan = null, $tahun = null, $status = null)
    {
        $query = self::with('teknisi');

        if ($bulan) {
            $query->where('periode_bulan', $bulan);
        }
        if ($tahun) {
            $query->where('periode_tahun', $tahun);
        }
        if ($status) {
            $query->where('status_pembayaran', $status);
        }

        $data = $query->get();

        return [
            'total_teknisi' => $data->count(),
            'total_gaji' => $data->sum('total_ongkos_pekerjaan'),
            'total_kasbon' => $data->sum('total_kasbon'),
            'total_biaya_makan' => $data->sum('biaya_makan'),
            'gaji_bersih' => $data->sum('gaji_bersih'),
            'belum_bayar' => $data->where('status_pembayaran', self::STATUS_BELUM_BAYAR)->count(),
            'sudah_bayar' => $data->where('status_pembayaran', self::STATUS_SUDAH_BAYAR)->count(),
        ];
    }

    /**
     * Static method to check if periode already exists for teknisi
     */
    public static function isPeriodeExists($idTeknisi, $bulan, $tahun)
    {
        return self::where('id_teknisi', $idTeknisi)
                  ->where('periode_bulan', $bulan)
                  ->where('periode_tahun', $tahun)
                  ->exists();
    }

    /**
     * Static method to get latest periode
     */
    public static function getLatestPeriode()
    {
        $latest = self::orderBy('periode_tahun', 'desc')
                     ->orderBy('periode_bulan', 'desc')
                     ->first();

        if (!$latest) {
            return [
                'bulan' => date('n'),
                'tahun' => date('Y')
            ];
        }

        return [
            'bulan' => $latest->periode_bulan,
            'tahun' => $latest->periode_tahun
        ];
    }

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

        // Auto calculate gaji_bersih before saving
        static::saving(function ($penggajian) {
            $ongkos = $penggajian->total_ongkos_pekerjaan ?? 0;
            $makan  = $penggajian->biaya_makan ?? 0;
            $potongan = $penggajian->total_potongan ?? 0;
            
            // Gaji Bersih = Ongkos - Uang Makan - Potongan Kasbon
            // (Uang makan sekarang dihitung sebagai potongan)
            $penggajian->gaji_bersih = $ongkos - $makan - $potongan;
        });
    }
}