<?php

namespace Mtc\Plugins\Wisebee\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Mtc\Core\AdminUser;
use Mtc\Plugins\Wisebee\Classes\Models\WisebeeUser;
use Wisebee\Provisioning;
use Wisebee\Resources\User as RemoteUser;
use Wisebee\Wisebee;

class WisebeeSetupController extends Controller
{
    /**
     * Renders the setup wizard page
     *
     * @return mixed
     */
    public function index()
    {
        $adminUsers = AdminUser::all();
        $isConfigured = !empty(config('wisebee.api_key'));
        $hasProvisioningKey = !empty(config('wisebee.provisioning_key'));

        $environments = config('wisebee.environments', []);

        $appUrl = preg_replace('/^http:\/\//', 'https://', rtrim(config('app.url'), '/'));
        $bookingUrl = $appUrl . '/book-a-consultation';
        $consultationUrl = $appUrl . '/video-consultation';
        $paymentRedirectUrl = $appUrl . '/shop/checkout/basket_overview.php';

        return template('wisebee/admin/setup/wizard.twig', [
            'title' => 'Wisebee Setup',
            'adminUsers' => $adminUsers,
            'isConfigured' => $isConfigured,
            'hasProvisioningKey' => $hasProvisioningKey,
            'environments' => $environments,
            'currentHost' => config('wisebee.host'),
            'currentApiKey' => config('wisebee.api_key'),
            'currentBookingWidgetKey' => config('wisebee.booking_widget_api_key'),
            'currentConsultationWidgetKey' => config('wisebee.consultation_widget_api_key'),
            'websiteUrl' => config('app.url'),
            'webhookUrl' => route('wisebee-webhook'),
            'bookingUrl' => $bookingUrl,
            'consultationUrl' => $consultationUrl,
            'paymentRedirectUrl' => $paymentRedirectUrl,
        ]);
    }

    /**
     * Fetches industries from the selected Wisebee environment
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function industries(Request $request): JsonResponse
    {
        $request->validate([
            'environment' => 'required|string',
        ]);

        $environments = config('wisebee.environments', []);
        $environment = $request->input('environment');
        if (!array_key_exists($environment, $environments)) {
            return response()->json(['success' => false, 'error' => 'Invalid environment selected'], 422);
        }

        $provisioningKey = $request->input('provisioning_key', config('wisebee.provisioning_key'));
        if (empty($provisioningKey)) {
            return response()->json(['success' => false, 'error' => 'Provisioning key is required'], 422);
        }

        $provisioning = new Provisioning(
            'https://' . $environment . '/api/',
            $provisioningKey
        );

        $result = $provisioning->industries();
        if ($result === false) {
            $error = $provisioning->getError();
            return response()->json(['success' => false, 'error' => is_string($error) ? $error : 'Failed to fetch industries'], 422);
        }

        return response()->json(['success' => true, 'data' => $result]);
    }

    /**
     * Provisions a new Wisebee client
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function provision(Request $request): JsonResponse
    {
        $request->validate([
            'admin_user_id' => 'required|integer|exists:admin_users,id',
            'environment' => 'required|string',
            'name' => 'required|string|max:255',
            'code' => ['required', 'string', 'max:50', 'regex:/^[a-zA-Z0-9_-]+$/'],
            'email' => 'required|email',
            'password' => 'required|string|min:8',
            'firstname' => 'required|string|max:255',
            'lastname' => 'required|string|max:255',
            'phone' => 'required|string|max:20',
            'industry_id' => 'required|integer',
        ]);

        $environments = config('wisebee.environments', []);
        $environment = $request->input('environment');
        if (!array_key_exists($environment, $environments)) {
            return response()->json(['success' => false, 'error' => 'Invalid environment selected'], 422);
        }

        $provisioningKey = $request->input('provisioning_key', config('wisebee.provisioning_key'));
        if (empty($provisioningKey)) {
            return response()->json(['success' => false, 'error' => 'Provisioning key is required'], 422);
        }

        $provisioning = new Provisioning(
            'https://' . $environment . '/api/',
            $provisioningKey
        );

        $result = $provisioning->provision([
            'name' => $request->input('name'),
            'code' => $request->input('code'),
            'email' => $request->input('email'),
            'password' => $request->input('password'),
            'firstname' => $request->input('firstname'),
            'lastname' => $request->input('lastname'),
            'phone' => $request->input('phone'),
            'industry_id' => $request->input('industry_id'),
        ]);

        if ($result === false) {
            $error = $provisioning->getError();
            $message = is_string($error) ? $error : 'Provisioning failed';
            return response()->json(['success' => false, 'error' => $message], 422);
        }

        // Write credentials to .env
        $host = 'https://' . $request->input('code') . '.' . $environment . '/';
        $this->updateEnvFile([
            'WISEBEE_PROVISIONING_KEY' => $provisioningKey,
            'WISEBEE_ENABLED' => 'true',
            'WISEBEE_API_KEY' => $result->api_token,
            'WISEBEE_HOST' => $host,
            'WISEBEE_API_ENDPOINT' => 'api/',
            'WISEBEE_BOOKING_WIDGET_API_KEY' => $result->booking_widget_api_key,
            'WISEBEE_CONSULTATION_WIDGET_API_KEY' => $result->consultation_widget_api_key,
        ]);

        Artisan::call('config:clear');

        return response()->json([
            'success' => true,
            'data' => [
                'client_id' => $result->client_id,
                'client_code' => $result->client_code,
                'domain' => $request->input('code') . '.' . $environment,
                'host' => $host,
                'api_token' => $result->api_token,
                'booking_widget_api_key' => $result->booking_widget_api_key,
                'consultation_widget_api_key' => $result->consultation_widget_api_key,
                'admin_user_id' => $request->input('admin_user_id'),
                'owner_email' => $request->input('email'),
            ],
        ]);
    }

    /**
     * Configures remote Wisebee settings
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function configureSettings(Request $request): JsonResponse
    {
        $request->validate([
            'settings' => 'required|array',
        ]);

        // Force reload config from .env (bypass any caching)
        $host = env('WISEBEE_HOST', config('wisebee.host'));
        $apiEndpoint = env('WISEBEE_API_ENDPOINT', config('wisebee.api_endpoint'));
        $apiKey = env('WISEBEE_API_KEY', config('wisebee.api_key'));

        if (empty($host) || empty($apiKey)) {
            return response()->json([
                'success' => false,
                'error' => 'Wisebee is not configured. Host or API key is missing.',
            ], 422);
        }

        // Use cURL directly to capture full response
        $url = $host . $apiEndpoint . 'settings';
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $apiKey,
            'Accept: application/json',
            'Content-Type: application/json',
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
            'settings' => $request->input('settings'),
        ]));

        // Bypass SSL verification for dev environments with self-signed/mismatched certs
        if (config('app.env') !== 'production') {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curlError = curl_error($ch);
        curl_close($ch);

        if ($curlError) {
            return response()->json([
                'success' => false,
                'error' => 'Connection error: ' . $curlError,
            ], 422);
        }

        $result = json_decode($response, true);

        if ($httpCode >= 200 && $httpCode < 300) {
            // Link admin user to Wisebee user if provided
            $adminUserId = $request->input('admin_user_id');
            $ownerEmail = $request->input('owner_email');

            if ($adminUserId && $ownerEmail) {
                // Check if link already exists
                $existingLink = WisebeeUser::query()
                    ->where('admin_user_id', $adminUserId)
                    ->first();

                if (!$existingLink) {
                    $wisebee = new Wisebee($host . $apiEndpoint, $apiKey);
                    $remoteUsers = $wisebee->list(RemoteUser::class, [
                        'email' => $ownerEmail,
                    ]);

                    if (!empty($remoteUsers)) {
                        $remoteUser = $remoteUsers[0];
                        WisebeeUser::query()->create([
                            'wisebee_id' => $remoteUser->id,
                            'admin_user_id' => $adminUserId,
                        ]);
                    }
                }
            }

            return response()->json([
                'success' => true,
                'data' => $result,
            ]);
        }

        return response()->json([
            'success' => false,
            'error' => $result['error']['message'] ?? $result['message'] ?? 'Failed to update settings',
            'debug' => [
                'httpCode' => $httpCode,
                'response' => $response,
            ],
        ], 422);
    }

    /**
     * Uploads a company logo to Wisebee via the API
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function uploadLogo(Request $request): JsonResponse
    {
        $request->validate([
            'file' => 'required|file|mimes:jpg,jpeg,png,gif|max:2048',
        ]);

        $apiUrl = config('wisebee.host') . config('wisebee.api_endpoint') . 'settings/upload-file';
        $apiKey = config('wisebee.api_key');

        $file = $request->file('file');
        $filePath = $file->getRealPath();
        $fileName = $file->getClientOriginalName();
        $fileMime = $file->getMimeType();

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $apiKey,
            'Accept: application/json',
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, [
            'type' => 'company_logo',
            'file' => new \CURLFile($filePath, $fileMime, $fileName),
        ]);

        // Bypass SSL verification for dev environments with self-signed/mismatched certs
        if (config('app.env') !== 'production') {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curlError = curl_error($ch);
        curl_close($ch);

        if ($response === false) {
            return response()->json([
                'success' => false,
                'error' => 'Connection error: ' . $curlError,
            ], 422);
        }

        $result = json_decode($response, true);

        if ($httpCode >= 200 && $httpCode < 300 && !empty($result['success'])) {
            return response()->json([
                'success' => true,
                'url' => $result['url'] ?? '',
            ]);
        }

        return response()->json([
            'success' => false,
            'error' => $result['error'] ?? 'Failed to upload logo',
        ], 422);
    }

    /**
     * Updates the .env file with the given key-value pairs
     *
     * @param array $values
     * @return void
     */
    private function updateEnvFile(array $values): void
    {
        $envPath = base_path('.env');
        $envContent = file_get_contents($envPath);

        foreach ($values as $key => $value) {
            $quotedValue = '"' . addcslashes($value, '"\\') . '"';
            $pattern = "/^{$key}=.*/m";
            $replacement = "{$key}={$quotedValue}";
            if (preg_match($pattern, $envContent)) {
                $envContent = preg_replace($pattern, str_replace('$', '\$', $replacement), $envContent);
            } else {
                $envContent .= "\n{$replacement}";
            }
        }

        file_put_contents($envPath, $envContent);
    }
}
