<?php

namespace App\Http\Controllers;

use App\Models\EmpresaModuloOverride;
use App\Models\ManyChatIntegracion;
use App\Models\ManyChatLog;
use App\Models\Plan;
use App\Models\PlanModulo;
use App\Models\Suscripcion;
use App\Services\ProductSearchService;
use App\Services\ManyChatResponseService;
use App\Support\TenantContext;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\View\View;

class ManyChatIntegracionController extends Controller
{
    public function __construct(private readonly TenantContext $tenantContext) {}

    public function index(): View
    {
        $empresaId = $this->tenantContext->empresaId();
        abort_if($empresaId === null, 403);

        $integracion = ManyChatIntegracion::query()
            ->where('empresa_id', $empresaId)
            ->first();

        $logs = ManyChatLog::query()
            ->where('empresa_id', $empresaId)
            ->orderByDesc('created_at')
            ->limit(50)
            ->get();

        $planAllows = $this->planAllowsManyChat($empresaId);
        $currentPlan = $this->currentPlan($empresaId);
        $endpointBase = rtrim(url('/api/manychat'), '/');

        return view('modules.configuracion.integraciones.manychat', compact(
            'integracion',
            'logs',
            'planAllows',
            'currentPlan',
            'endpointBase'
        ));
    }

    public function toggle(Request $request): RedirectResponse
    {
        $empresaId = $this->tenantContext->empresaId();
        abort_if($empresaId === null, 403);

        if (! $this->planAllowsManyChat($empresaId)) {
            return back()->with('error', 'Tu plan actual no incluye la integración ManyChat.');
        }

        $integracion = ManyChatIntegracion::firstOrCreate(
            ['empresa_id' => $empresaId],
            ['api_token' => ManyChatIntegracion::generateToken(), 'activo' => false]
        );

        $nuevoEstado = ! $integracion->activo;
        $integracion->update(['activo' => $nuevoEstado]);

        $this->clearTokenCache($integracion->api_token);

        $msg = $nuevoEstado ? 'Integración ManyChat activada.' : 'Integración ManyChat desactivada.';

        return back()->with('status', $msg);
    }

    public function regenerarToken(): RedirectResponse
    {
        $empresaId = $this->tenantContext->empresaId();
        abort_if($empresaId === null, 403);

        $integracion = ManyChatIntegracion::firstOrCreate(
            ['empresa_id' => $empresaId],
            ['api_token' => ManyChatIntegracion::generateToken(), 'activo' => false]
        );

        $oldToken = $integracion->api_token;
        $nuevoToken = ManyChatIntegracion::generateToken();

        $integracion->update(['api_token' => $nuevoToken, 'activo' => false]);

        $this->clearTokenCache($oldToken);

        return back()->with('status', 'Token regenerado. La integración fue desactivada por seguridad. Actualiza el token en ManyChat y reactívala.');
    }

    public function updateNombre(Request $request): RedirectResponse
    {
        $empresaId = $this->tenantContext->empresaId();
        abort_if($empresaId === null, 403);

        $request->validate(['nombre_integracion' => 'required|string|max:120']);

        $integracion = ManyChatIntegracion::firstOrCreate(
            ['empresa_id' => $empresaId],
            ['api_token' => ManyChatIntegracion::generateToken(), 'activo' => false]
        );

        $integracion->update(['nombre_integracion' => trim((string) $request->input('nombre_integracion'))]);

        return back()->with('status', 'Nombre actualizado.');
    }

    public function updateTemplates(Request $request): RedirectResponse
    {
        $empresaId = $this->tenantContext->empresaId();
        abort_if($empresaId === null, 403);

        $validated = $request->validate([
            'template_producto' => 'nullable|string|max:3000',
            'template_productos_multiples' => 'nullable|string|max:3000',
            'template_no_encontrado' => 'nullable|string|max:3000',
        ]);

        $integracion = ManyChatIntegracion::firstOrCreate(
            ['empresa_id' => $empresaId],
            ['api_token' => ManyChatIntegracion::generateToken(), 'activo' => false]
        );

        $integracion->update([
            'template_producto' => $this->normalizeTemplate($validated['template_producto'] ?? null),
            'template_productos_multiples' => $this->normalizeTemplate($validated['template_productos_multiples'] ?? null),
            'template_no_encontrado' => $this->normalizeTemplate($validated['template_no_encontrado'] ?? null),
        ]);

        return back()->with('status', 'Plantillas ManyChat actualizadas.');
    }

    /** AJAX: test a product query without touching ManyChat */
    public function testProducto(Request $request): JsonResponse
    {
        $empresaId = $this->tenantContext->empresaId();
        if ($empresaId === null) {
            return response()->json(['success' => false, 'message' => 'Sin empresa activa.'], 403);
        }

        $query = trim((string) $request->query('query', ''));
        if ($query === '') {
            return response()->json(['success' => false, 'message' => 'Escribe un nombre o código de producto.']);
        }

        $searchService = app(ProductSearchService::class);
        $responseService = app(ManyChatResponseService::class);

        $products = $searchService->search($empresaId, $query);

        if ($products->isEmpty()) {
            return response()->json($responseService->productNotFound($query, $empresaId));
        }

        $result = $products->count() === 1
            ? $responseService->productFound($products->first(), $empresaId)
            : $responseService->multipleProducts($products, $empresaId);

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

    private function planAllowsManyChat(int $empresaId): bool
    {
        $override = EmpresaModuloOverride::query()
            ->where('empresa_id', $empresaId)
            ->where('modulo', 'manychat')
            ->first();

        if ($override !== null) {
            return (bool) $override->habilitado;
        }

        $plan = $this->currentPlan($empresaId);
        if (! $plan) {
            return false;
        }

        if (! $plan->relationLoaded('modulos')) {
            $plan->load('modulos');
        }

        return $plan->tieneModulo('manychat')
            || PlanModulo::query()
                ->where('plan_id', $plan->id)
                ->where('modulo', 'manychat')
                ->exists();
    }

    private function currentPlan(int $empresaId): ?Plan
    {
        $suscripcion = Suscripcion::query()
            ->where('empresa_id', $empresaId)
            ->whereIn('estado', ['activa', 'morosa'])
            ->with('plan')
            ->orderByDesc('id')
            ->first();

        if ($suscripcion && $suscripcion->plan) {
            return $suscripcion->plan;
        }

        return Plan::query()->where('activo', 1)->orderBy('precio_mensual')->first();
    }

    private function clearTokenCache(string $token): void
    {
        Cache::forget('mc_token_'.hash('sha256', $token));
    }

    private function normalizeTemplate(?string $template): ?string
    {
        $value = trim((string) $template);

        return $value !== '' ? $value : null;
    }
}
