<?php

namespace App\Http\Controllers\Frontend\Service\Traits;

use App\Models\IngameServiceSetting;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

trait IngameServiceTrait
{
    /**
     * Check if a service is enabled
     */
    protected function checkServiceEnabled(string $serviceName): ?array
    {
        if (!IngameServiceSetting::isEnabled($serviceName)) {
            return [
                'success' => false,
                'error' => ucwords(str_replace('_', ' ', $serviceName)) . ' service is currently disabled.'
            ];
        }
        return null;
    }

    /**
     * Check if user has enough gold for service
     */
    protected function checkGoldBalance($user, int $price): ?array
    {
        if ($price > 0 && $user->gold < $price) {
            return [
                'success' => false,
                'error' => "Insufficient gold. Required: {$price} gold."
            ];
        }
        return null;
    }

    /**
     * Verify role belongs to user and return role data
     */
    protected function verifyRoleOwnership($userId, int $roleId): array
    {
        $rolesData = $this->api->getRoles($userId);
        $roles = $rolesData['roles'] ?? [];
        
        foreach ($roles as $role) {
            if ((int) ($role['id'] ?? 0) === $roleId) {
                return [
                    'found' => true,
                    'role' => $role
                ];
            }
        }

        return [
            'found' => false,
            'error' => [
                'success' => false,
                'error' => 'Character not found or does not belong to you.'
            ]
        ];
    }

    /**
     * Check if role is offline
     */
    protected function checkRoleOffline(int $roleId): ?array
    {
        $onlineList = $this->api->getOnlineList();
        $isOnline = collect($onlineList)->contains('roleid', $roleId);
        
        if ($isOnline) {
            return [
                'success' => false,
                'error' => 'Character must be offline. Please logout from the game first.'
            ];
        }
        return null;
    }

    /**
     * Deduct gold from user
     */
    protected function deductGold($userId, int $price): void
    {
        if ($price > 0) {
            DB::table('users')
                ->where('ID', $userId)
                ->decrement('gold', $price);
        }
    }

    /**
     * Common service execution - validates and runs the service
     */
    protected function executeService(
        string $serviceName,
        int $roleId,
        callable $serviceCallback,
        bool $requireOffline = true,
        ?callable $additionalValidation = null
    ): array {
        // Check if service is enabled
        $error = $this->checkServiceEnabled($serviceName);
        if ($error) return $error;

        $user = Auth::user();
        $price = IngameServiceSetting::getPrice($serviceName);

        // Check gold balance
        $error = $this->checkGoldBalance($user, $price);
        if ($error) return $error;

        // Verify role belongs to user
        $roleCheck = $this->verifyRoleOwnership($user->ID, $roleId);
        if (!$roleCheck['found']) {
            return $roleCheck['error'];
        }

        // Check if role is offline (if required)
        if ($requireOffline) {
            $error = $this->checkRoleOffline($roleId);
            if ($error) return $error;
        }

        // Run additional validation if provided
        if ($additionalValidation) {
            $error = $additionalValidation($roleId, $roleCheck['role']);
            if ($error) return $error;
        }

        // Execute the service
        $result = $serviceCallback($roleId, $roleCheck['role']);

        if (!$result['success']) {
            return [
                'success' => false,
                'error' => ucwords(str_replace('_', ' ', $serviceName)) . ' failed: ' . $result['message']
            ];
        }

        // Deduct gold
        $this->deductGold($user->ID, $price);

        return [
            'success' => true,
            'message' => $result['message']
        ];
    }
}
