<?php

namespace Modules\MultiPOS\Services;

use Modules\MultiPOS\Entities\PosMachine;
use Modules\MultiPOS\Events\PosMachineRegistrationRequested;
use App\Models\Branch;
use App\Models\Restaurant;
use Illuminate\Support\Facades\DB;

class PosMachineService
{
    /**
     * Check if a new machine can be registered for a branch
     */
    public static function canRegisterNewMachine(int $branchId): bool
    {
        $branch = Branch::find($branchId);
        if (!$branch) {
            return false;
        }

        $restaurant = $branch->restaurant;
        if (!$restaurant || !$restaurant->package) {
            return false;
        }

        $package = $restaurant->package;
        
        // Check if package has MultiPOS module
        if (!$package->hasModule('MultiPOS')) {
            return false;
        }

        $limit = $package->multipos_limit ?? -1;
        
        // -1 means unlimited
        if ($limit === -1) {
            return true;
        }

        // Count active and pending machines for this branch
        $currentCount = PosMachine::where('branch_id', $branchId)
            ->whereIn('status', ['active', 'pending'])
            ->count();

        return $currentCount < $limit;
    }

    /**
     * Get machine count for a branch
     */
    public static function getMachineCount(?int $branchId, ?string $status = null): int
    {
        if (!$branchId) {
            return 0;
        }
        
        $query = PosMachine::where('branch_id', $branchId);
        
        if ($status) {
            $query->where('status', $status);
        }
        
        return $query->count();
    }

    /**
     * Get remaining machine slots for a branch
     */
    public static function getRemainingSlots(?int $branchId): ?int
    {
        if (!$branchId) {
            return null;
        }
        
        $branch = Branch::find($branchId);
        if (!$branch) {
            return null;
        }

        $restaurant = $branch->restaurant;
        if (!$restaurant || !$restaurant->package) {
            return null;
        }

        $package = $restaurant->package;
        $limit = $package->multipos_limit ?? -1;

        if ($limit === -1) {
            return null; // Unlimited
        }

        $currentCount = self::getMachineCount($branchId, null);
        
        return max(0, $limit - $currentCount);
    }

    /**
     * Register a new POS machine
     */
    public static function registerMachine(array $data): PosMachine
    {
        return DB::transaction(function () use ($data) {
            // Check if device_id already exists
            if (isset($data['device_id'])) {
                $existing = PosMachine::where('device_id', $data['device_id'])
                    ->where('branch_id', $data['branch_id'])
                    ->first();
                
                if ($existing) {
                    return $existing;
                }
            }

            // Ensure required fields
            $data['registered_at'] = $data['registered_at'] ?? now();
            $data['status'] = $data['status'] ?? 'pending';

            $machine = PosMachine::create($data);
            
            // Dispatch event
            event(new PosMachineRegistrationRequested($machine));
            
            return $machine;
        });
    }

    /**
     * Approve a POS machine
     */
    public static function approveMachine(PosMachine $machine, int $approvedBy, ?string $note = null): bool
    {
        return $machine->update([
            'status' => 'active',
            'approved_by' => $approvedBy,
            'approved_at' => now(),
            'declined_by' => null,
            'declined_at' => null,
            'declined_reason' => null,
        ]);
    }

    /**
     * Decline a POS machine
     */
    public static function declineMachine(PosMachine $machine, int $declinedBy, ?string $reason = null): bool
    {
        return $machine->update([
            'status' => 'declined',
            'declined_by' => $declinedBy,
            'declined_at' => now(),
            'declined_reason' => $reason,
            'approved_by' => null,
            'approved_at' => null,
        ]);
    }
}

