<?php

namespace App\Services;

use App\Models\Order;
use App\Models\OrderAuditTrail;
use Illuminate\Support\Facades\Auth;

class OrderStatusTransitionService
{
    private static array $allowedTransitions = [
        'pending' => ['accepted', 'cancelled'],
        'accepted' => ['preparing', 'cancelled'],
        'preparing' => ['ready', 'cancelled'],
        'ready' => ['picked_up', 'cancelled'],
        'picked_up' => ['delivered', 'cancelled'],
        'delivered' => [],
        'cancelled' => []
    ];

    public static function canTransition(string $currentStatus, string $newStatus): bool
    {
        return in_array($newStatus, self::$allowedTransitions[$currentStatus] ?? []);
    }

    public static function validateTransition(Order $order, string $newStatus): array
    {
        $currentStatus = $order->status;

        if (!self::canTransition($currentStatus, $newStatus)) {
            return [
                'valid' => false, 
                'message' => "Invalid transition from '{$currentStatus}' to '{$newStatus}'"
            ];
        }

        return ['valid' => true, 'message' => 'Transition allowed'];
    }

    public static function transitionTo(Order $order, string $newStatus, ?string $reason = null): array
    {
        $validation = self::validateTransition($order, $newStatus);
        
        if (!$validation['valid']) {
            self::logFailedAttempt($order, $newStatus, $validation['message']);
            return $validation;
        }

        $oldStatus = $order->status;
        $order->update(['status' => $newStatus]);

        OrderAuditService::logStatusChange($order, $oldStatus, $newStatus, $reason);

        return ['valid' => true, 'message' => 'Status updated successfully'];
    }

    public static function forceTransition(Order $order, string $newStatus, string $reason): array
    {
        $oldStatus = $order->status;
        $order->update(['status' => $newStatus]);

        OrderAuditService::logManualOverride($order, ['status' => $newStatus], "FORCE TRANSITION: {$reason}");

        return ['valid' => true, 'message' => 'Status forcefully updated'];
    }

    private static function logFailedAttempt(Order $order, string $attemptedStatus, string $reason): void
    {
        $user = request()->user();
        $request = request();

        OrderAuditTrail::create([
            'order_id' => $order->id,
            'user_id' => $user?->id ?? 1,
            'user_role' => $user?->roles->pluck('name')->first() ?? 'system',
            'action_type' => 'status_change',
            'action_description' => "FAILED: Attempted to change status to '{$attemptedStatus}'",
            'old_values' => ['status' => $order->status],
            'new_values' => ['attempted_status' => $attemptedStatus],
            'reason' => $reason,
            'ip_address' => $request?->ip(),
            'user_agent' => $request?->userAgent()
        ]);
    }

    public static function getAllowedTransitions(string $currentStatus): array
    {
        return self::$allowedTransitions[$currentStatus] ?? [];
    }

    public static function getStatusFlow(): array
    {
        return self::$allowedTransitions;
    }
}