<?php
// app/Http\Controllers\Web\Api\BaseApiController.php

namespace App\Http\Controllers\Web\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Client\Response as HttpResponse;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Log;

class BaseApiController extends Controller
{
    protected string $apiBaseUrl;
    protected array $headers = [];

    public function __construct()
    {
        $this->apiBaseUrl = rtrim(config('app.api_url', 'http://localhost:8000/api'), '/');
        $this->setupHeaders();
    }

    protected function setupHeaders(): void
    {
        $this->headers = [
            'Accept' => 'application/json',
            'Content-Type' => 'application/json',
        ];

        $token = $this->getApiToken();
        
        if ($token) {
            $this->headers['Authorization'] = 'Bearer ' . $token;
        }
    }
    
    protected function getApiToken(): ?string
    {
        if ($token = Session::get('api_token')) {
            return $token;
        }
        /** @var bool $isAuthenticated */
        if (auth()->check()) {
             /** @var \App\Models\User $user */
            $user = auth()->user();
            
            /** @var \App\Models\User $user */
            if ($user->currentAccessToken()) {
                return $user->currentAccessToken()->plainTextToken;
            }
            
            $token = $user->createToken('web-session')->plainTextToken;
            Session::put('api_token', $token);
            return $token;
        }
        
        return null;
    }

    /**
     * Send API request
     */
    protected function apiRequest(string $method, string $endpoint, array $data = []): array
    {
        try {
            $endpoint = '/' . ltrim($endpoint, '/');
            
            if (str_starts_with($endpoint, '/customer/customer/')) {
                $endpoint = str_replace('/customer/customer/', '/customer/', $endpoint);
            }
            
            $url = $this->apiBaseUrl . $endpoint;
            Log::info('API Request to ' . $url, [
                'method' => $method,
                'data' => $data
            ]);
            
            // Gunakan ->wait() untuk resolve Promise menjadi Response
            $response = $this->makeHttpRequest($method, $url, $data);
            
            $statusCode = $response->status();
            $isSuccessful = $response->successful();
            $responseBody = $response->body();
            $jsonData = $response->json();
            
            Log::info('API Response from ' . $url, [
                'status' => $statusCode,
                'success' => $isSuccessful
            ]);
            
            return [
                'success' => $isSuccessful,
                'status' => $statusCode,
                'data' => $jsonData,
                'raw' => $responseBody,
                'response' => $response,
            ];
            
        } catch (\Exception $e) {
            Log::error('API Request Error', [
                'endpoint' => $endpoint ?? 'unknown',
                'error' => $e->getMessage()
            ]);
            
            return [
                'success' => false,
                'error' => $e->getMessage(),
                'status' => 500,
            ];
        }
    }

    /**
     * Make HTTP request and resolve Promise
     * 
     * @return HttpResponse
     */
    private function makeHttpRequest(string $method, string $url, array $data = []): HttpResponse
    {
        $http = Http::withHeaders($this->headers)
            ->timeout(30)
            ->withOptions(['verify' => config('app.env') === 'production']);
        
        // Gunakan ->wait() untuk resolve Promise
        return match(strtolower($method)) {
            'get' => $http->get($url, $data)->wait(),
            'post' => $http->post($url, $data)->wait(),
            'put' => $http->put($url, $data)->wait(),
            'patch' => $http->patch($url, $data)->wait(),
            'delete' => $http->delete($url, $data)->wait(),
            default => $http->get($url, $data)->wait()
        };
    }

    /**
     * Handle API response for views
     */
    protected function handleResponse(array $apiResponse, string $successView, array $viewData = [])
    {
        if ($apiResponse['success']) {
            $apiData = $apiResponse['data'];
            
            if (isset($apiData['success']) && $apiData['success']) {
                return view($successView, array_merge($viewData, [
                    'apiData' => $apiData['data'] ?? $apiData,
                    'apiMessage' => $apiData['message'] ?? '',
                    'apiMeta' => $apiData['meta'] ?? null,
                ]));
            }
            
            $errorMessage = $apiData['message'] ?? 'API Error';
            return redirect()->back()
                ->with('error', $errorMessage)
                ->withErrors($apiData['errors'] ?? []);
        }

        return redirect()->back()
            ->with('error', 'API Connection Error: ' . ($apiResponse['error'] ?? 'Unknown error'));
    }

    /**
     * Get current user
     */
    protected function getCurrentUser()
    {
        /** @var \App\Models\User|null $user */
        $user = auth()->user();
        return $user ?? Session::get('user');
    }

    /**
     * Get current role
     */
    protected function getCurrentRole(): ?string
    {
        $user = $this->getCurrentUser();
        
        if (is_object($user) && method_exists($user, 'getRole')) {
            return $user->getRole();
        } elseif (is_array($user)) {
            return $user['role'] ?? null;
        } elseif (is_object($user) && property_exists($user, 'role')) {
            return $user->role;
        }
        
        return Session::get('user_role');
    }

    /**
     * Check if user has role
     */
    protected function hasRole(string $role): bool
    {
        return $this->getCurrentRole() === $role;
    }

    /**
     * Check if authenticated
     */
    protected function isAuthenticated(): bool
    {
        /** @var bool $isAuthenticated */
        return auth()->check() || Session::has('api_token');
    }

    /**
     * Test API connection
     */
    protected function testApiConnection(): array
    {
        return $this->apiRequest('get', '/auth/health');
    }
}