<?php

namespace App\Models;

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

class Receivable extends Model
{
    use HasFactory;

    protected $fillable = [
        'order_id',
        'user_id',
        'receivable_number',
        'total_amount',
        'paid_amount',
        'remaining_amount',
        'payment_status',
        'due_date',
        'notes',
        'status'
    ];

    protected $casts = [
        'total_amount' => 'decimal:2',
        'paid_amount' => 'decimal:2',
        'remaining_amount' => 'decimal:2',
        'due_date' => 'date',
    ];

    /**
     * Relasi ke Order
     */
    public function order(): BelongsTo
    {
        return $this->belongsTo(Order::class);
    }

    /**
     * Relasi ke User
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * Scope untuk piutang aktif
     */
    public function scopeActive($query)
    {
        return $query->where('status', 'active');
    }

    /**
     * Scope untuk piutang yang belum lunas
     */
    public function scopeUnpaid($query)
    {
        return $query->whereIn('payment_status', ['pending', 'partial', 'overdue']);
    }

    /**
     * Scope untuk piutang yang sudah jatuh tempo
     */
    public function scopeOverdue($query)
    {
        return $query->where('due_date', '<', now())
                    ->whereIn('payment_status', ['pending', 'partial']);
    }

    /**
     * Cek apakah piutang sudah jatuh tempo
     */
    public function isOverdue(): bool
    {
        return $this->due_date && 
               $this->due_date->isPast() && 
               in_array($this->payment_status, ['pending', 'partial']);
    }

    /**
     * Update status pembayaran berdasarkan jumlah yang dibayar
     */
    public function updatePaymentStatus(): void
    {
        // Round untuk prevent floating point issues
        $paid = round($this->paid_amount, 2);
        $total = round($this->total_amount, 2);
        
        if ($paid >= $total && $paid > 0) {
            $this->update([
                'payment_status' => 'paid',
                'status' => 'completed',
                'remaining_amount' => 0
            ]);
        } elseif ($this->paid_amount > 0) {
            $this->update([
                'payment_status' => 'partial',
                'remaining_amount' => $this->total_amount - $this->paid_amount
            ]);
        } else {
            $this->update([
                'payment_status' => 'pending',
                'remaining_amount' => $this->total_amount
            ]);
        }

        // Cek apakah jatuh tempo (hanya untuk pending/partial)
        if ($this->isOverdue() && $this->payment_status !== 'paid') {
            $this->update(['payment_status' => 'overdue']);
        }
    }

    /**
     * Tambah pembayaran
     */
    public function addPayment(float $amount, string $notes = null): void
    {
        $this->update([
            'paid_amount' => $this->paid_amount + $amount,
            'notes' => $notes ? $this->notes . "\n" . $notes : $this->notes
        ]);

        $this->updatePaymentStatus();
        
        // Sinkronisasi dengan Order status
        $this->syncOrderStatus();
    }
    
    /**
     * Sinkronisasi status Order berdasarkan status Receivable
     */
    public function syncOrderStatus(): void
    {
        if ($this->payment_status === 'paid') {
            // Jika piutang lunas, update order status menjadi selesai
            $this->order->update([
                'status' => 'selesai'
            ]);
            // Tidak memaksa status produksi; ikuti workflow teknisi/supervisor
        } elseif ($this->payment_status === 'partial') {
            // Jika piutang sudah bayar sebagian, update order status menjadi diproses
            // (kecuali jika sudah selesai, jangan turunkan)
            if ($this->order->status !== 'selesai') {
                $this->order->update([
                    'status' => 'diproses'
                ]);
            }
        }
        // Jika payment_status = 'pending', biarkan status order seperti semula
        // (bisa 'menunggu' atau 'menunggu_verifikasi' tergantung apakah sudah upload bukti)
    }

    /**
     * Generate nomor piutang
     */
    public static function generateReceivableNumber(): string
    {
        $prefix = 'PIU';
        $date = now()->format('Ymd');
        $lastNumber = self::whereDate('created_at', now())->count() + 1;
        
        return $prefix . $date . str_pad($lastNumber, 3, '0', STR_PAD_LEFT);
    }

    /**
     * Accessor untuk status pembayaran dalam bahasa Indonesia
     */
    public function getPaymentStatusLabelAttribute(): string
    {
        return match($this->payment_status) {
            'pending' => 'Belum Bayar',
            'partial' => 'Bayar Sebagian',
            'paid' => 'Lunas',
            'overdue' => 'Jatuh Tempo',
            default => 'Tidak Diketahui'
        };
    }

    /**
     * Accessor untuk status dalam bahasa Indonesia
     */
    public function getStatusLabelAttribute(): string
    {
        return match($this->status) {
            'active' => 'Aktif',
            'completed' => 'Selesai',
            'cancelled' => 'Dibatalkan',
            default => 'Tidak Diketahui'
        };
    }
}
