<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\FraudModuleSetting;
use App\Services\Fraud\FraudModuleManager;
use App\Traits\LogsAdminActivity;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

/**
 * Fraud Module Settings Controller
 *
 * Manages external fraud detection modules (MaxMind, FraudLabs, etc.)
 */
class FraudModuleSettingsController extends Controller
{
    use LogsAdminActivity;

    protected FraudModuleManager $moduleManager;

    public function __construct(FraudModuleManager $moduleManager)
    {
        $this->moduleManager = $moduleManager;
    }

    /**
     * Display fraud modules management page
     */
    public function index()
    {
        // Sync modules first
        $this->moduleManager->syncModules();

        $availableModules = $this->moduleManager->getAvailableModules();
        $settings = FraudModuleSetting::all()->keyBy('module_slug');

        $modules = collect($availableModules)->map(function ($moduleData, $slug) use ($settings) {
            $setting = $settings->get($slug);

            return [
                'slug' => $slug,
                'metadata' => $moduleData['metadata'],
                'config_fields' => $moduleData['config_fields'],
                'enabled' => $setting->enabled ?? false,
                'priority' => $setting->priority ?? 0,
                'last_tested_at' => $setting->last_tested_at ?? null,
                'is_configured' => $setting ? $setting->isConfigured() : false,
            ];
        })->sortBy('priority')->values();

        return view('admin.fraud.modules.index', compact('modules'));
    }

    /**
     * Show module configuration page
     */
    public function edit(string $slug)
    {
        $module = $this->moduleManager->getModule($slug);

        if (!$module) {
            return redirect()->route('admin.fraud.modules.index')
                ->with('error', __('admin/fraud.messages_module_not_found'));
        }

        $setting = $this->moduleManager->getModuleSetting($slug);
        $metadata = $module->getMetadata();
        $configFields = $module->getConfigFields();

        return view('admin.fraud.modules.edit', compact('slug', 'metadata', 'configFields', 'setting'));
    }

    /**
     * Update module configuration
     */
    public function update(Request $request, string $slug)
    {
        $module = $this->moduleManager->getModule($slug);

        if (!$module) {
            return back()->with('error', __('admin/fraud.messages_module_not_found'));
        }

        // Build validation rules from config fields
        $configFields = $module->getConfigFields();
        $rules = [];

        foreach ($configFields as $key => $field) {
            if ($key === 'enabled') {
                $rules['enabled'] = 'boolean';
                continue;
            }

            $fieldRules = [];

            if (!empty($field['required'])) {
                $fieldRules[] = 'required';
            } else {
                $fieldRules[] = 'nullable';
            }

            switch ($field['type']) {
                case 'text':
                case 'password':
                    $fieldRules[] = 'string';
                    break;
                case 'number':
                    $fieldRules[] = 'numeric';
                    if (isset($field['min'])) {
                        $fieldRules[] = 'min:' . $field['min'];
                    }
                    if (isset($field['max'])) {
                        $fieldRules[] = 'max:' . $field['max'];
                    }
                    break;
                case 'boolean':
                    $fieldRules[] = 'boolean';
                    break;
                case 'select':
                    if (!empty($field['options'])) {
                        $fieldRules[] = 'in:' . implode(',', array_keys($field['options']));
                    }
                    break;
            }

            $rules["config.{$key}"] = $fieldRules;
        }

        $rules['priority'] = 'nullable|integer|min:0';

        $validated = $request->validate($rules);

        try {
            DB::beginTransaction();

            $setting = $this->moduleManager->getModuleSetting($slug);
            $setting->config = $validated['config'] ?? [];
            $setting->enabled = $validated['enabled'] ?? false;
            $setting->priority = $validated['priority'] ?? 0;
            $setting->save();

            $this->logUpdated(
                model: $setting,
                description: "Updated fraud module settings for {$slug}. Enabled: " . ($setting->enabled ? 'Yes' : 'No')
            );

            DB::commit();

            return redirect()->route('admin.fraud.modules.index')
                ->with('success', __('admin/fraud.messages_module_updated'));

        } catch (\Exception $e) {
            DB::rollBack();

            return back()
                ->withInput()
                ->with('error', __('admin/fraud.messages_module_update_failed'));
        }
    }

    /**
     * Test module connection
     */
    public function test(string $slug)
    {
        $result = $this->moduleManager->testModule($slug);

        if ($result['success']) {
            $this->logActivity(
                model: FraudModuleSetting::class,
                action: 'test_module',
                description: "Successfully tested fraud module: {$slug}"
            );
        }

        return response()->json($result);
    }

    /**
     * Toggle module enabled status
     */
    public function toggle(Request $request, string $slug)
    {
        try {
            $setting = $this->moduleManager->getModuleSetting($slug);
            $setting->enabled = !$setting->enabled;
            $setting->save();

            $this->logUpdated(
                model: $setting,
                description: ($setting->enabled ? 'Enabled' : 'Disabled') . " fraud module: {$slug}"
            );

            return response()->json([
                'success' => true,
                'enabled' => $setting->enabled,
                'message' => __('admin/fraud.messages_module_toggled'),
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => __('admin/fraud.messages_module_toggle_failed'),
            ], 500);
        }
    }

    /**
     * Update module priorities
     */
    public function updatePriorities(Request $request)
    {
        $request->validate([
            'priorities' => 'required|array',
            'priorities.*' => 'required|integer|min:0',
        ]);

        try {
            DB::beginTransaction();

            foreach ($request->priorities as $slug => $priority) {
                $setting = $this->moduleManager->getModuleSetting($slug);
                $setting->priority = $priority;
                $setting->save();
            }

            $this->logActivity(
                model: FraudModuleSetting::class,
                action: 'update_priorities',
                description: 'Updated fraud module execution priorities'
            );

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => __('admin/fraud.messages_priorities_updated'),
            ]);

        } catch (\Exception $e) {
            DB::rollBack();

            return response()->json([
                'success' => false,
                'message' => __('admin/fraud.messages_priorities_update_failed'),
            ], 500);
        }
    }
}
