namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use App\Models\ApiProvider; use App\Models\ApiLog; use App\Services\Api\ApiServiceManager; use App\Jobs\SyncProviderServices; use App\Jobs\CheckProviderBalances; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class ApiProviderController extends Controller { protected ApiServiceManager $apiManager; public function __construct(ApiServiceManager $apiManager) { $this->apiManager = $apiManager; } public function index(Request $request) { $query = ApiProvider::withCount('services'); if ($request->has('search')) { $search = $request->search; $query->where('name', 'like', "%{$search}%") ->orWhere('code', 'like', "%{$search}%"); } if ($request->has('status') && $request->status != 'all') { $query->where('status', $request->status); } $providers = $query->orderBy('name')->paginate(20); $stats = [ 'total' => ApiProvider::count(), 'active' => ApiProvider::where('status', 'active')->count(), 'total_balance' => ApiProvider::sum('balance'), ]; return view('admin.api.providers.index', compact('providers', 'stats')); } public function create() { return view('admin.api.providers.create'); } public function store(Request $request) { $request->validate([ 'name' => 'required|string|max:100', 'code' => 'required|string|max:50|unique:api_providers', 'api_url' => 'required|url', 'api_key' => 'required|string', 'api_secret' => 'nullable|string', 'api_version' => 'nullable|string', 'api_type' => 'required|in:standard,advanced,custom', 'profit_type' => 'required|in:fixed,percentage', 'profit_value' => 'required|numeric|min:0', 'rate_multiplier' => 'required|numeric|min:0.1|max:10', 'timeout' => 'required|integer|min:5|max:300', 'retry_attempts' => 'required|integer|min:0|max:10', 'auto_sync' => 'boolean', 'sync_interval' => 'required_if:auto_sync,true|integer|min:5|max:1440', ]); DB::beginTransaction(); try { $data = $request->all(); $data['api_key'] = encrypt($request->api_key); if ($request->api_secret) { $data['api_secret'] = encrypt($request->api_secret); } $provider = ApiProvider::create($data); DB::commit(); // Log activity auth()->guard('admin')->user()->logActivity( 'Created API provider: ' . $provider->name ); return redirect()->route('admin.api.providers.show', $provider) ->with('success', 'API provider created successfully.'); } catch (\Exception $e) { DB::rollBack(); return back()->with('error', 'Failed to create provider: ' . $e->getMessage()) ->withInput(); } } public function show(ApiProvider $provider) { $provider->loadCount('services'); $recentLogs = ApiLog::where('api_provider_id', $provider->id) ->latest() ->limit(20) ->get(); $balanceHistory = $provider->apiBalances() ->latest() ->limit(30) ->get(); $stats = [ 'total_orders' => $provider->orders()->count(), 'successful_orders' => $provider->orders()->where('status', 'completed')->count(), 'failed_orders' => $provider->orders()->where('status', 'error')->count(), 'total_revenue' => $provider->orders()->where('status', 'completed')->sum('price'), 'total_profit' => $provider->orders()->where('status', 'completed')->sum('profit'), ]; return view('admin.api.providers.show', compact( 'provider', 'recentLogs', 'balanceHistory', 'stats' )); } public function edit(ApiProvider $provider) { // Decrypt sensitive data $provider->api_key = decrypt($provider->api_key); if ($provider->api_secret) { $provider->api_secret = decrypt($provider->api_secret); } return view('admin.api.providers.edit', compact('provider')); } public function update(Request $request, ApiProvider $provider) { $request->validate([ 'name' => 'required|string|max:100', 'code' => 'required|string|max:50|unique:api_providers,code,' . $provider->id, 'api_url' => 'required|url', 'api_key' => 'required|string', 'api_secret' => 'nullable|string', 'api_version' => 'nullable|string', 'api_type' => 'required|in:standard,advanced,custom', 'profit_type' => 'required|in:fixed,percentage', 'profit_value' => 'required|numeric|min:0', 'rate_multiplier' => 'required|numeric|min:0.1|max:10', 'timeout' => 'required|integer|min:5|max:300', 'retry_attempts' => 'required|integer|min:0|max:10', 'auto_sync' => 'boolean', 'sync_interval' => 'required_if:auto_sync,true|integer|min:5|max:1440', ]); DB::beginTransaction(); try { $data = $request->all(); $data['api_key'] = encrypt($request->api_key); if ($request->api_secret) { $data['api_secret'] = encrypt($request->api_secret); } $provider->update($data); DB::commit(); // Log activity auth()->guard('admin')->user()->logActivity( 'Updated API provider: ' . $provider->name ); return redirect()->route('admin.api.providers.show', $provider) ->with('success', 'API provider updated successfully.'); } catch (\Exception $e) { DB::rollBack(); return back()->with('error', 'Failed to update provider: ' . $e->getMessage()) ->withInput(); } } public function destroy(ApiProvider $provider) { if ($provider->services()->exists()) { return back()->with('error', 'Cannot delete provider with linked services.'); } $name = $provider->name; $provider->delete(); // Log activity auth()->guard('admin')->user()->logActivity('Deleted API provider: ' . $name); return redirect()->route('admin.api.providers.index') ->with('success', 'API provider deleted successfully.'); } public function checkBalance(ApiProvider $provider) { try { $result = $this->apiManager->checkProviderBalance($provider); if ($result['success']) { return response()->json([ 'success' => true, 'balance' => $result['balance'], 'currency' => $result['currency'], ]); } return response()->json([ 'success' => false, 'error' => $result['error'] ?? 'Failed to check balance', ], 422); } catch (\Exception $e) { return response()->json([ 'success' => false, 'error' => $e->getMessage(), ], 500); } } public function syncServices(ApiProvider $provider) { try { SyncProviderServices::dispatch($provider->id); return response()->json([ 'success' => true, 'message' => 'Service sync started. This may take a few minutes.', ]); } catch (\Exception $e) { return response()->json([ 'success' => false, 'error' => $e->getMessage(), ], 500); } } public function logs(ApiProvider $provider, Request $request) { $query = ApiLog::where('api_provider_id', $provider->id); if ($request->has('status_code')) { $query->where('status_code', $request->status_code); } if ($request->has('date_from')) { $query->whereDate('created_at', '>=', $request->date_from); } if ($request->has('date_to')) { $query->whereDate('created_at', '<=', $request->date_to); } $logs = $query->latest()->paginate(50); return view('admin.api.providers.logs', compact('provider', 'logs')); } public function services(ApiProvider $provider, Request $request) { $query = $provider->providerServices()->with('service'); if ($request->has('search')) { $search = $request->search; $query->where('provider_service_name', 'like', "%{$search}%") ->orWhere('provider_service_id', 'like', "%{$search}%"); } if ($request->has('status') && $request->status != 'all') { $query->where('status', $request->status); } $services = $query->paginate(50); return view('admin.api.providers.services', compact('provider', 'services')); } public function updateService(Request $request, ProviderService $providerService) { $request->validate([ 'service_id' => 'required|exists:services,id', 'our_price' => 'required|numeric|min:0', ]); $providerService->update([ 'service_id' => $request->service_id, 'our_price' => $request->our_price, ]); // Update linked service price if ($request->service_id) { Service::where('id', $request->service_id)->update([ 'price' => $request->our_price, ]); } return response()->json(['success' => true]); } public function toggleStatus(ApiProvider $provider) { $provider->update([ 'status' => $provider->status === 'active' ? 'inactive' : 'active' ]); return response()->json([ 'success' => true, 'status' => $provider->status ]); } }