<?php

namespace App\Http\Controllers;

use App\Models\OltDevice;
use App\Services\OltSshService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;

class BackupConfigController extends Controller
{
    public function index()
    {
        $devices = OltDevice::where('active', true)->get();
        return view('backup-config.index', compact('devices'));
    }

    public function getSlots(OltDevice $device)
    {
        $cacheKey = "olt_cards_{$device->id}";

        $cached = Cache::get($cacheKey);
        if ($cached !== null) {
            return response()->json(['success' => true, 'slots' => $cached]);
        }

        try {
            $ssh = new OltSshService($device);
            if (!$ssh->connect()) {
                return response()->json(['success' => false, 'message' => 'No se pudo conectar a la OLT.']);
            }

            $cards = $ssh->getOltCards();
            $ssh->disconnect();

            if (empty($cards)) {
                $cards = array_map(fn($s) => ['slot' => $s, 'type' => 'GPON'], range(2, 9));
            }

            Cache::put($cacheKey, $cards, now()->addMinutes(30));

            return response()->json(['success' => true, 'slots' => $cards]);
        } catch (\Throwable $e) {
            return response()->json(['success' => false, 'message' => 'Error: ' . $e->getMessage()]);
        }
    }

    public function backupPort(Request $request, OltDevice $device)
    {
        $request->validate([
            'frame' => 'required|integer|min:1',
            'slot'  => 'required|integer|min:1',
            'port'  => 'required|integer|min:1|max:16',
        ]);

        set_time_limit(120);

        try {
            $ssh = new OltSshService($device);
            if (!$ssh->connect()) {
                return response()->json(['success' => false, 'message' => 'No se pudo conectar a la OLT.']);
            }

            $config = $ssh->getRunningConfig($request->frame, $request->slot, $request->port);
            $ssh->disconnect();

            $lines = substr_count($config, "\n") + 1;

            return response()->json([
                'success' => true,
                'config'  => $config,
                'stats'   => [
                    'lines' => $lines,
                    'ports' => 1,
                ],
            ]);
        } catch (\Throwable $e) {
            return response()->json(['success' => false, 'message' => 'Error: ' . $e->getMessage()]);
        }
    }

    public function backupSlot(Request $request, OltDevice $device)
    {
        $request->validate([
            'frame' => 'required|integer|min:1',
            'slot'  => 'required|integer|min:1',
        ]);

        set_time_limit(300);

        try {
            $ssh = new OltSshService($device);
            if (!$ssh->connectLong()) {
                return response()->json(['success' => false, 'message' => 'No se pudo conectar a la OLT.']);
            }

            $results = $ssh->getSlotRunningConfig($request->frame, $request->slot);
            $ssh->disconnect();

            // Combine all configs
            $combined = '';
            $totalLines = 0;
            foreach ($results as $r) {
                $combined .= "! ============================================================\n";
                $combined .= "! Puerto gpon-olt_{$request->frame}/{$request->slot}/{$r['port']}\n";
                $combined .= "! ============================================================\n";
                $combined .= $r['config'] . "\n\n";
                $totalLines += substr_count($r['config'], "\n") + 1;
            }

            return response()->json([
                'success' => true,
                'config'  => $combined,
                'stats'   => [
                    'lines' => $totalLines,
                    'ports' => count($results),
                ],
            ]);
        } catch (\Throwable $e) {
            return response()->json(['success' => false, 'message' => 'Error: ' . $e->getMessage()]);
        }
    }

    public function download(Request $request, OltDevice $device)
    {
        $request->validate([
            'config' => 'required|string',
            'slot'   => 'required|integer',
            'port'   => 'nullable|integer',
        ]);

        $date = now()->format('Ymd_His');
        $portLabel = $request->port ? "port{$request->port}" : 'all';
        $deviceName = preg_replace('/[^a-zA-Z0-9_-]/', '_', $device->name);
        $filename = "backup_{$deviceName}_slot{$request->slot}_{$portLabel}_{$date}.txt";

        return response($request->config)
            ->header('Content-Type', 'text/plain')
            ->header('Content-Disposition', "attachment; filename=\"{$filename}\"");
    }
}
