<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Wildside\Userstamps\Userstamps;
use Illuminate\Database\Eloquent\SoftDeletes;

class BookingDetail extends Model
{
    use HasFactory, Userstamps, SoftDeletes;

    protected $fillable = [
        'booking_id',
        'room_id',
        'booking_type',
        'room_price',
        'base_price',
        'nights',
        'duration_hours',
        'guest_count',
        'price_per_night',
        'total_price',
        'ppn_rate',
        'ppn_amount',
        'grand_total'
    ];

    protected $casts = [
        'room_price' => 'decimal:2',
        'base_price' => 'decimal:2',
        'total_price' => 'decimal:2',
        'ppn_rate' => 'decimal:4',
        'ppn_amount' => 'decimal:2',
        'grand_total' => 'decimal:2',
        'nights' => 'integer',
        'duration_hours' => 'integer',
        'guest_count' => 'integer',
    ];

    // Booking type constants
    const TYPE_DAILY = 'daily';
    const TYPE_HOURLY = 'hourly';
    const TYPE_PER_PERSON = 'per_person';

    // Relationships
    public function booking()
    {
        return $this->belongsTo(Booking::class);
    }

    public function room()
    {
        return $this->belongsTo(MsRooms::class, 'room_id');
    }

    // NEW: Booking type methods
    public function isDailyBooking()
    {
        return $this->booking_type === self::TYPE_DAILY;
    }

    public function isHourlyBooking()
    {
        return $this->booking_type === self::TYPE_HOURLY;
    }

    public function isPerPersonBooking()
    {
        return $this->booking_type === self::TYPE_PER_PERSON;
    }

    // NEW: Get booking type display name
    public function getBookingTypeDisplayAttribute()
    {
        $types = [
            'daily' => 'Harian',
            'hourly' => 'Per Jam',
            'per_person' => 'Per Orang'
        ];

        return $types[$this->booking_type] ?? 'Unknown';
    }

    // NEW: Get duration display based on booking type
    public function getDurationDisplayAttribute()
    {
        switch ($this->booking_type) {
            case 'daily':
                return $this->nights . ' malam';
            case 'hourly':
                return $this->duration_hours . ' jam';
            case 'per_person':
                return $this->guest_count . ' orang';
            default:
                return 'Unknown';
        }
    }

    // NEW: Get calculation display
    public function getCalculationDisplayAttribute()
    {
        switch ($this->booking_type) {
            case 'daily':
                return "Rp " . number_format($this->base_price, 0, ',', '.') . " x {$this->nights} malam";
            case 'hourly':
                return "Rp " . number_format($this->base_price, 0, ',', '.') . " x {$this->duration_hours} jam";
            case 'per_person':
                return "Rp " . number_format($this->base_price, 0, ',', '.') . " x {$this->guest_count} orang x {$this->nights} malam";
            default:
                return 'Unknown';
        }
    }

    // Accessors
    public function getRoomPriceFormattedAttribute()
    {
        return 'Rp ' . number_format($this->room_price, 0, ',', '.');
    }

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

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

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

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

    public function getPpnRatePercentAttribute()
    {
        return ($this->ppn_rate * 100) . '%';
    }

    // NEW: Static method untuk kalkulasi harga berdasarkan tipe booking
    public static function calculatePrice($roomType, $bookingType, $nights = 1, $durationHours = 1, $guestCount = 1)
    {
        $basePrice = 0;
        $totalPrice = 0;

        switch ($bookingType) {
            case 'daily':
                $basePrice = $roomType->harga_per_malam;
                $totalPrice = $basePrice * $nights;
                break;
            
            case 'hourly':
                $basePrice = $roomType->harga_per_jam ?? 0;
                $totalPrice = $basePrice * $durationHours;
                break;
            
            case 'per_person':
                $basePrice = $roomType->harga_per_orang;
                $totalPrice = $basePrice * $guestCount * $nights;
                break;
        }

        $ppnRate = $roomType->ppn / 100;
        $ppnAmount = $totalPrice * $ppnRate;
        $grandTotal = $totalPrice + $ppnAmount;

        return [
            'base_price' => $basePrice,
            'total_price' => $totalPrice,
            'ppn_rate' => $ppnRate,
            'ppn_amount' => $ppnAmount,
            'grand_total' => $grandTotal,
            'nights' => $nights,
            'duration_hours' => $durationHours,
            'guest_count' => $guestCount
        ];
    }

    // NEW: Method untuk update harga berdasarkan tipe booking
    public function updatePriceCalculation()
    {
        if (!$this->room || !$this->room->typeRoom) {
            return false;
        }

        $calculation = self::calculatePrice(
            $this->room->typeRoom,
            $this->booking_type,
            $this->nights ?? 1,
            $this->duration_hours ?? 1,
            $this->guest_count ?? 1
        );

        $this->update([
            'base_price' => $calculation['base_price'],
            'room_price' => $calculation['total_price'], // Untuk backward compatibility
            'total_price' => $calculation['total_price'],
            'ppn_rate' => $calculation['ppn_rate'],
            'ppn_amount' => $calculation['ppn_amount'],
            'grand_total' => $calculation['grand_total']
        ]);

        return true;
    }

    // Scopes
    public function scopeDaily($query)
    {
        return $query->where('booking_type', 'daily');
    }

    public function scopeHourly($query)
    {
        return $query->where('booking_type', 'hourly');
    }

    public function scopePerPerson($query)
    {
        return $query->where('booking_type', 'per_person');
    }
}