<?php

namespace App\Http\Controllers;

use App\Models\OpenVpnServer;
use App\Models\Router;
use App\Models\VpnClient;
use App\Services\OpenVpnProvisioner;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class VpnController extends Controller
{
    public function create(Router $router)
    {
        $servers = OpenVpnServer::orderBy('name')->get();
        $suggestCN = 'BB-RT-' . $router->id;
        $suggestIP = '10.8.0.' . (10 + $router->id); // simple suggestion
        return view('vpn.create', compact('router','servers','suggestCN','suggestIP'));
    }

    public function store(Request $r, Router $router, OpenVpnProvisioner $prov)
    {
        $data = $r->validate([
            'openvpn_server_id' => 'required|exists:openvpn_servers,id',
            'common_name'       => 'required|alpha_dash|unique:vpn_clients,common_name',
            'static_ip'         => 'required|ip',
        ]);

        $vc = VpnClient::create([
            'router_id' => $router->id,
            'openvpn_server_id' => $data['openvpn_server_id'],
            'common_name' => $data['common_name'],
            'static_ip'   => $data['static_ip'],
            'status'      => 'new',
        ]);

        try {
            $prov->createClient($vc);
            return redirect()->route('vpn.show', $vc)->with('status','OpenVPN profile created.');
        } catch (\Throwable $e) {
            $vc->update(['status'=>'error','last_error'=>$e->getMessage()]);
            return back()->withErrors('Provision failed: '.$e->getMessage());
        }
    }

    public function show(VpnClient $vpn)
    {
        $router = $vpn->router;
        $ovpnUrl = $vpn->ovpn_path ? route('vpn.download',$vpn) : null;

        // Ready-to-paste MikroTik CLI (username not required if cert only)
        $server = $vpn->server;
        $vpsHost = $server->host;

        $mikrotik = <<<RSC
# Upload the 3 blocks (CA/CRT/KEY) from the .ovpn file into Files (or keep as separate files)
# If you keep separate files, adjust names below:
# /file print  (to confirm names)

# Create OVPN client:
 /interface ovpn-client add name=ovpn-bluebando connect-to={$vpsHost} port=1194 \
   user={$vpn->common_name} password="" \
   profile=default-encryption certificate={$vpn->common_name}.crt_0 \
   auth=sha1 cipher=aes256 add-default-route=no disabled=no

# (Optional) Assign the VPN IP if you want a fixed address inside the tunnel:
 /ip address add address={$vpn->static_ip}/24 interface=ovpn-bluebando comment="BlueBando VPN"

# Test:
 /ping {$server->host}
RSC;

        return view('vpn.show', compact('vpn','router','ovpnUrl','mikrotik'));
    }

    public function download(VpnClient $vpn)
    {
        abort_unless($vpn->ovpn_path && file_exists($vpn->ovpn_path), 404);
        return response()->download($vpn->ovpn_path, basename($vpn->ovpn_path));
    }

    public function revoke(VpnClient $vpn, OpenVpnProvisioner $prov)
    {
        $prov->revoke($vpn);
        return back()->with('status','OpenVPN client revoked.');
    }
}
