<?php

namespace App\Http\Controllers;

use App\Models\Order;
use App\Models\ProductVariant;
use App\Models\Provider;
use App\Models\ProviderProductMapping;
use App\Services\ProviderFulfillmentService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Http;
use RuntimeException;
use Throwable;

class AdminProviderController extends Controller
{
    public function index()
    {
        return view('admin.providers.index', [
            'providers' => Provider::withCount(['mappings', 'logs'])->latest()->get(),
            'products' => ProductVariant::with('game')->whereIn('delivery_method', ['api', 'hybrid', 'manual'])->orderBy('name_ar')->get(),
            'mappings' => ProviderProductMapping::with(['provider', 'productVariant.game'])->latest()->paginate(20),
            'summary' => [
                'providers' => Provider::count(),
                'active' => Provider::where('is_active', true)->count(),
                'mappings' => ProviderProductMapping::where('is_active', true)->count(),
                'failedLogs' => \App\Models\ProviderLog::where('status', 'failed')->where('created_at', '>=', now()->subDay())->count(),
            ],
        ]);
    }

    public function store(Request $request)
    {
        $payload = $request->validate([
            'name' => ['required', 'string', 'max:120'],
            'code' => ['required', 'string', 'max:80', 'unique:providers,code'],
            'type' => ['required', 'in:generic,midasbuy'],
            'mode' => ['required', 'in:mock,live'],
            'base_url' => ['nullable', 'url', 'max:255'],
            'auth_header' => ['required', 'string', 'max:80'],
            'api_key_env' => ['nullable', 'string', 'max:120'],
            'api_key' => ['nullable', 'string', 'max:255'],
            'timeout_seconds' => ['required', 'integer', 'min:3', 'max:60'],
            'retry_attempts' => ['required', 'integer', 'min:0', 'max:5'],
        ]);

        $payload['is_active'] = $request->boolean('is_active', true);
        $payload['settings'] = $this->settingsPayload($request);

        if (filled($payload['api_key'] ?? null)) {
            $payload['encrypted_api_key'] = Crypt::encryptString($payload['api_key']);
        }

        unset($payload['api_key']);

        Provider::create($payload);

        return back()->with('status', 'تم إضافة المزود.');
    }

    public function update(Request $request, Provider $provider)
    {
        $payload = $request->validate([
            'name' => ['required', 'string', 'max:120'],
            'type' => ['required', 'in:generic,midasbuy'],
            'mode' => ['required', 'in:mock,live'],
            'base_url' => ['nullable', 'url', 'max:255'],
            'auth_header' => ['required', 'string', 'max:80'],
            'api_key_env' => ['nullable', 'string', 'max:120'],
            'api_key' => ['nullable', 'string', 'max:255'],
            'timeout_seconds' => ['required', 'integer', 'min:3', 'max:60'],
            'retry_attempts' => ['required', 'integer', 'min:0', 'max:5'],
        ]);

        $payload['is_active'] = $request->boolean('is_active');
        $payload['settings'] = $this->settingsPayload($request);

        if (filled($payload['api_key'] ?? null)) {
            $payload['encrypted_api_key'] = Crypt::encryptString($payload['api_key']);
        }

        unset($payload['api_key']);

        $provider->update($payload);

        return back()->with('status', 'تم تحديث المزود.');
    }

    public function health(Provider $provider)
    {
        if ($provider->mode === 'mock') {
            $provider->update([
                'health_status' => 'healthy',
                'last_health_at' => now(),
            ]);

            return back()->with('status', 'وضع التجربة يعمل بشكل سليم.');
        }

        try {
            $response = Http::timeout($provider->timeout_seconds)
                ->withHeaders(array_filter([
                    'Accept' => 'application/json',
                    $provider->auth_header => $provider->apiKey(),
                ]))
                ->get(rtrim((string) $provider->base_url, '/'));

            $provider->update([
                'health_status' => $response->status() < 500 ? 'healthy' : 'degraded',
                'last_health_at' => now(),
            ]);
        } catch (Throwable $exception) {
            $provider->update([
                'health_status' => 'failed',
                'last_health_at' => now(),
            ]);

            return back()->withErrors(['provider' => 'فشل اختبار المزود: '.$exception->getMessage()]);
        }

        return back()->with('status', 'تم اختبار اتصال المزود.');
    }

    public function storeMapping(Request $request)
    {
        $payload = $this->mappingPayload($request);

        ProviderProductMapping::updateOrCreate(
            [
                'provider_id' => $payload['provider_id'],
                'product_variant_id' => $payload['product_variant_id'],
            ],
            $payload,
        );

        return back()->with('status', 'تم حفظ ربط المنتج بالمزود.');
    }

    public function updateMapping(Request $request, ProviderProductMapping $mapping)
    {
        $mapping->update($this->mappingPayload($request, false));

        return back()->with('status', 'تم تحديث الربط.');
    }

    public function destroyMapping(ProviderProductMapping $mapping)
    {
        $mapping->delete();

        return back()->with('status', 'تم حذف الربط.');
    }

    public function fulfill(Request $request, Order $order, ProviderFulfillmentService $provider)
    {
        try {
            $provider->fulfillOrder($order, $request->user());
        } catch (RuntimeException $exception) {
            return back()->withErrors(['provider' => $exception->getMessage()]);
        }

        return back()->with('status', 'تم تنفيذ بنود API عبر المزود.');
    }

    private function settingsPayload(Request $request): array
    {
        return [
            'player_lookup_enabled' => $request->boolean('player_lookup_enabled', true),
            'code_check_enabled' => $request->boolean('code_check_enabled', true),
            'async_tasks_enabled' => $request->boolean('async_tasks_enabled'),
            'sandbox_note' => $request->input('sandbox_note'),
        ];
    }

    private function mappingPayload(Request $request, bool $requireKeys = true): array
    {
        return $request->validate([
            'provider_id' => [$requireKeys ? 'required' : 'sometimes', 'exists:providers,id'],
            'product_variant_id' => [$requireKeys ? 'required' : 'sometimes', 'exists:product_variants,id'],
            'provider_sku' => ['nullable', 'string', 'max:120'],
            'fulfillment_type' => ['required', 'in:pubg_uc_code,generic_http,manual_provider'],
            'mode' => ['required', 'in:single,bulk,async'],
            'codes_per_order' => ['required', 'integer', 'min:1', 'max:5'],
            'is_active' => ['nullable', 'boolean'],
        ]) + [
            'required_fields' => [
                ['key' => 'player_id', 'label' => 'Player ID', 'required' => true],
            ],
            'settings' => [
                'reserve_stock_code' => true,
                'fail_order_on_provider_error' => false,
            ],
            'is_active' => $request->boolean('is_active'),
        ];
    }
}
