<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\License;
use App\Models\LicenseLog;
use Illuminate\Http\Request;
use Carbon\Carbon;

class LicenseController extends Controller
{
    // Validación de seguridad simple antes de cualquier cosa
    public function __construct()
    {
        $secret = request()->header('X-IGPOS-SECRET');
        if ($secret !== env('IGPOS_API_SECRET')) {
            abort(403, 'Acceso Denegado: API Secret inválido.');
        }
    }

    /**
     * 1. VERIFICAR (Paso previo a instalar)
     * El instalador pregunta: "¿Esta clave existe y puedo usarla?"
     */
    public function verify(Request $request)
    {
        $request->validate([
            'license_key' => 'required|string'
        ]);

        $license = License::where('license_key', $request->license_key)->first();

        // 1. No existe
        if (!$license) {
            $this->log($license, 'VERIFY', 'FAIL_NOT_FOUND');
            return response()->json(['success' => false, 'message' => 'Licencia no encontrada.'], 404);
        }

        // 2. Está suspendida o baneada
        if ($license->status !== 'ACTIVE') {
            $this->log($license, 'VERIFY', 'FAIL_STATUS_' . $license->status);
            return response()->json(['success' => false, 'message' => 'Licencia suspendida o inactiva.'], 403);
        }

        // 3. Está vencida
        if ($license->isExpired()) {
            $this->log($license, 'VERIFY', 'FAIL_EXPIRED');
            return response()->json(['success' => false, 'message' => 'La licencia ha caducado.'], 403);
        }

        // 4. Ya está usada por otro servidor (Tiene HWID y es diferente al que consulta, si es que envía uno)
        // Nota: En verify solo avisamos, no bloqueamos aun, pero informamos al cliente.
        $isUsed = !is_null($license->hardware_id);

        $this->log($license, 'VERIFY', 'SUCCESS');

        return response()->json([
            'success' => true,
            'message' => 'Licencia válida.',
            'data' => [
                'type' => $license->type,
                'is_used' => $isUsed, // Si es true, el instalador debería advertir al usuario
                'expiration' => $license->expiration_date ? $license->expiration_date->format('d/m/Y') : 'Vitalicia',
                'max_connections' => $license->max_connections
            ]
        ]);
    }

    /**
     * 2. ACTIVAR (El amarre)
     * El instalador dice: "Voy a instalarme en ESTE equipo (HWID)".
     */
    public function activate(Request $request)
    {
        $request->validate([
            'license_key' => 'required|string',
            'hardware_id' => 'required|string', // CPU ID + Disk Serial
        ]);

        $license = License::where('license_key', $request->license_key)->first();

        if (!$license || $license->status !== 'ACTIVE' || $license->isExpired()) {
            return response()->json(['success' => false, 'message' => 'Licencia no válida para activación.'], 403);
        }

        // CASO A: Primera vez (Licencia virgen) -> AMARRAMOS
        if (is_null($license->hardware_id)) {
            $license->update([
                'hardware_id' => $request->hardware_id,
                'last_check_at' => now(),
                'last_ip' => $request->ip()
            ]);

            $this->log($license, 'ACTIVATE', 'SUCCESS_NEW_BINDING');

            return response()->json([
                'success' => true,
                'message' => 'Activación exitosa. Equipo vinculado.',
                'token' => $this->generateOfflineToken($license) // Token para guardar en archivo local
            ]);
        }

        // CASO B: Reinstalación (El mismo PC) -> PERMITIMOS
        if ($license->hardware_id === $request->hardware_id) {
            $license->update(['last_check_at' => now(), 'last_ip' => $request->ip()]);
            $this->log($license, 'ACTIVATE', 'SUCCESS_REINSTALL');

            return response()->json([
                'success' => true,
                'message' => 'Re-activación exitosa.',
                'token' => $this->generateOfflineToken($license)
            ]);
        }

        // CASO C: Piratería (Otro PC intenta usar la clave) -> BLOQUEAMOS
        $this->log($license, 'ACTIVATE', 'FAIL_HWID_MISMATCH');
        return response()->json([
            'success' => false,
            'message' => 'Error: Esta licencia ya está en uso en otro servidor. Contacte soporte para resetear.'
        ], 409);
    }

    /**
     * 3. HEARTBEAT (Latido)
     * El servidor IGPos PRO llama a esto cada 24h para decir "Sigo vivo".
     */
    public function check(Request $request)
    {
        $request->validate([
            'license_key' => 'required',
            'hardware_id' => 'required',
        ]);

        $license = License::where('license_key', $request->license_key)
                          ->where('hardware_id', $request->hardware_id)
                          ->first();

        if (!$license) {
            return response()->json(['success' => false, 'command' => 'KILL'], 404); // Mata la app
        }

        if ($license->status !== 'ACTIVE' || $license->isExpired()) {
            return response()->json(['success' => false, 'command' => 'BLOCK'], 403); // Bloquea acceso
        }

        // Todo bien, actualizamos la última vez que lo vimos
        $license->update([
            'last_check_at' => now(),
            'last_ip' => $request->ip()
        ]);

        return response()->json([
            'success' => true,
            'command' => 'CONTINUE',
            'new_token' => $this->generateOfflineToken($license) // Renovamos el token offline
        ]);
    }

    // --- Helpers Privados ---

    private function log($license, $type, $response)
    {
        LicenseLog::create([
            'license_id' => $license ? $license->id : null,
            'ip_address' => request()->ip(),
            'request_type' => $type,
            'user_agent' => request()->header('User-Agent'),
            'response_code' => $response
        ]);
    }

    private function generateOfflineToken($license)
    {
        // Generamos un string encriptado que C# pueda guardar en un archivo .lic
        // Contiene: FECHA_LIMITE | HWID | FIRMA
        // Esto es básico, luego en C# lo desencriptas.
        $data = $license->expiration_date . '|' . $license->hardware_id . '|' . 'IGPOS_VALID';
        return base64_encode($data);
    }
}
