<?php
namespace App;

use Exception;
use Illuminate\Support\Facades\DB;

trait HasOrderStatus
{
    public static array $validStatuses = [
        'unpaid',
        'paid',
        'verify',
        'dikirim',
        'cancelled'
    ];

    public function updateStatus(string $status): void
    {
        if (!in_array($status, self::$validStatuses)) {
            throw new Exception("Invalid order status: {$status}");
        }

        $this->validateStatusTransition($status);

        DB::transaction(function () use ($status) {
            $oldStatus = $this->status;
            $this->status = $status;
            $this->save();

            if ($status === 'verify') {
                $this->decreaseProductStock();
            }

            if ($status === 'cancelled' && $oldStatus !== 'cancelled') {
                $this->restoreProductStock();
            }
        });
    }

    private function validateStatusTransition(string $newStatus): void
    {
        if ($this->status === 'cancelled') {
            throw new Exception("Cannot change status of cancelled order");
        }

        $statusFlow = [
            'unpaid' => ['paid', 'cancelled'],
            'paid' => ['verify', 'cancelled'],
            'verify' => ['dikirim', 'cancelled'],
            'dikirim' => ['cancelled'],
        ];

        $allowed = $statusFlow[$this->status] ?? [];

        if (!in_array($newStatus, $allowed)) {
            throw new Exception("Invalid status transition from {$this->status} to {$newStatus}");
        }
    }

    private function decreaseProductStock(): void
    {
        foreach ($this->items as $item) {
            $item->product->decreaseStock($item->quantity);
        }
    }

    private function restoreProductStock(): void
    {
        foreach ($this->items as $item) {
            $item->product->increaseStock($item->quantity);
        }
    }

    public function isUnpaid(): bool
    {
        return $this->status === 'unpaid';
    }

    public function isPaid(): bool
    {
        return $this->status === 'paid';
    }

    public function isVerify(): bool
    {
        return $this->status === 'verify';
    }

    public function isDikirim(): bool
    {
        return $this->status === 'dikirim';
    }

    public function isCancelled(): bool
    {
        return $this->status === 'cancelled';
    }

    public function getStatusColorAttribute(): string
    {
        return match ($this->status) {
            'unpaid' => 'warning',
            'paid' => 'info',
            'verify' => 'success',
            'dikirim' => 'primary',
            'cancelled' => 'danger',
            default => 'light',
        };
    }
}
