<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class PosSession extends Model
{
    protected $fillable = [
        'user_id',
        'branch_id',
        'opened_at',
        'closed_at',
        'opening_cash',
        'expected_cash',
        'actual_cash',
        'difference',
        'status',
        'reviewed_by',
        'reviewed_at',
        'notes',
        'review_notes',
    ];

    protected $casts = [
        'opened_at' => 'datetime',
        'closed_at' => 'datetime',
        'reviewed_at' => 'datetime',
        'opening_cash' => 'decimal:2',
        'expected_cash' => 'decimal:2',
        'actual_cash' => 'decimal:2',
        'difference' => 'decimal:2',
    ];

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

    public function branch(): BelongsTo
    {
        return $this->belongsTo(Branch::class);
    }

    public function reviewer(): BelongsTo
    {
        return $this->belongsTo(User::class, 'reviewed_by');
    }

    public function cashTransactions(): HasMany
    {
        return $this->hasMany(CashTransaction::class);
    }

    public function sales(): HasMany
    {
        return $this->hasMany(Sale::class);
    }

    public function scopeOpen($query)
    {
        return $query->where('status', 'open');
    }

    public function scopeClosed($query)
    {
        return $query->where('status', 'closed');
    }

    public function scopeReviewed($query)
    {
        return $query->where('status', 'reviewed');
    }

    public function scopePendingReview($query)
    {
        return $query->where('status', 'closed');
    }

    /**
     * Check if session is open
     */
    public function isOpen(): bool
    {
        return $this->status === 'open';
    }

    /**
     * Get total cash sales
     */
    public function getTotalCashSalesAttribute(): float
    {
        return $this->sales()
            ->whereHas('paymentMethod', fn($q) => $q->where('code', 'cash'))
            ->where('is_credit', false)
            ->sum('total');
    }

    /**
     * Get total card sales
     */
    public function getTotalCardSalesAttribute(): float
    {
        return $this->sales()
            ->whereHas('paymentMethod', fn($q) => $q->where('code', 'card'))
            ->where('is_credit', false)
            ->sum('total');
    }

    /**
     * Get total credit sales
     */
    public function getTotalCreditSalesAttribute(): float
    {
        return $this->sales()
            ->where('is_credit', true)
            ->sum('total');
    }

    /**
     * Get total cash in
     */
    public function getTotalCashInAttribute(): float
    {
        return $this->cashTransactions()
            ->where('type', 'cash_in')
            ->sum('amount');
    }

    /**
     * Get total cash out
     */
    public function getTotalCashOutAttribute(): float
    {
        return $this->cashTransactions()
            ->where('type', 'cash_out')
            ->sum('amount');
    }

    /**
     * Calculate expected cash
     */
    public function calculateExpectedCash(): float
    {
        return $this->opening_cash 
            + $this->total_cash_sales 
            + $this->total_cash_in 
            - $this->total_cash_out;
    }

    /**
     * Close session
     */
    public function close(float $actualCash, ?string $notes = null): self
    {
        $this->expected_cash = $this->calculateExpectedCash();
        $this->actual_cash = $actualCash;
        $this->difference = $actualCash - $this->expected_cash;
        $this->closed_at = now();
        $this->status = 'closed';
        $this->notes = $notes;
        $this->save();

        return $this;
    }

    /**
     * Review session
     */
    public function review(int $reviewerId, ?string $reviewNotes = null): self
    {
        $this->reviewed_by = $reviewerId;
        $this->reviewed_at = now();
        $this->status = 'reviewed';
        $this->review_notes = $reviewNotes;
        $this->save();

        return $this;
    }

    /**
     * Get status badge color
     */
    public function getStatusColorAttribute(): string
    {
        return match ($this->status) {
            'open' => 'success',
            'closed' => 'warning',
            'reviewed' => 'primary',
            default => 'secondary',
        };
    }
}
